Algorithm for Divison - verilog

I have been using '/' operator to perform divison in verilog. I am able to get the simulation results right but the thing is that my code was unable to get synthesized due to '/' operator. It was displaying the error "second operand of / should be a power of 2". How should I perform divison in Verilog HDL ?

The operator for division is not synthesizable as pointed by the error message, it's supposed to be used for simulation only.
What you need to do depends on the conditions of the division.
You can use the repeated subtraction algorithm, which is the simplest solution.
The downside is that you get the result of your division in N clock cycles, where N in the integer part of the division, but you can set a flag bit for when the division is complete.
Here is the description of the algorithm, from Wikipedia:
while N ≥ D do
N := N − D
end
return N
Edit: For the sake of completeness to anyone reaching this question. Here is a synthetizable implementation of the algorithm. (This is not the best implementation, nor it has been fully tested )
module mod_div(
input clk,
input rst,
input start,
input [7:0] num,
input [7:0] den,
output [7:0] res,
output [7:0] rem,
output reg done
);
/* Registers to store the input arguments */
reg [7:0] num_r;
reg [7:0] den_r;
/* counts the number of times denominator fits in numerator */
reg [7:0] result_integer;
/* True if the algorithm is running */
reg working;
always #(posedge clk) begin
if(rst == 1'b1)begin
/* setting the working registers to 0 */
num_r <= 8'b0;
den_r <= 8'b0;
working <= 1'b0;
result_integer <= 'b0;
done <= 'b0;
end else if(start == 1'b1) begin
/* Captures the parameters and starts the operation */
num_r <= num;
den_r <= den;
working <= 1'b1;
done <= 1'b0;
end
/* The actual algorithm */
if (working == 1'b1 && start == 1'b0)begin
if(num_r >= den_r) begin
/* The division will give a proper fraction */
num_r <= num_r - den_r;
result_integer <= result_integer + 8'b1;
end else begin
working <= 'b0;
done <= 1'b1;
end
end
end
/* The reminder of the division */
assign rem = num_r;
/*The integer part is the number of times the divisor was substracted from the
* numerator*/
assign res = result_integer;
endmodule
And also here is the test bench for this module:
module division_tb();
reg clk;
reg rst;
reg [7:0] numerator;
reg [7:0] denominator;
reg start;
wire [7:0] integer_result;
wire [7:0] reminder_result;
wire done_flag;
mod_div DUT (
.clk(clk),
.rst(rst),
.start(start),
.num(numerator),
.den(denominator),
.res(integer_result),
.rem(reminder_result),
.done(done_flag)
);
always begin
#10 clk = ~clk;
end
initial begin
clk = 1'b0;
rst = 1'b1;
#15 rst = 1'b0;
numerator = 17;
denominator = 5;
#1 start = 1;
#20 start = 0;
#200 $finish;
end
/* FOR GTK WAVE */
initial
begin
$dumpfile("shift.vcd");
$dumpvars(0, division_tb);
end
endmodule
This is the result of the simulation using GTK-Wave:
In the image the division of 17/5 is being performed, to start the operation
the start wire needs to be in 1 for at least 1 clock cycle, when the division is complete the flag done is set to 1 at that moment the result is in the output registers. For this example integer_part: 3 and the reminder is 2

Related

8 bit sequential multiplier using add and shift

I'm designing an 8-bit signed sequential multiplier using Verilog. The inputs are clk (clock), rst (reset), a (8 bit multiplier), b (8 bit multiplicand), and the outputs are p (product) and rdy (ready signal, indicating multiplication is over). For negative inputs, I do a sign extension and save it in the 15 bit register variables multiplier and multiplicand. Here's my code:
module seq_mult (p, rdy, clk, reset, a, b);
input clk, reset;
input [7:0] a, b;
output [15:0] p;
output rdy;
reg [15:0] p;
reg [15:0] multiplier;
reg [15:0] multiplicand;
reg rdy;
reg [4:0] ctr;
always #(posedge clk or posedge reset) begin
if (reset)
begin
rdy <= 0;
p <= 0;
ctr <= 0;
multiplier <= {{8{a[7]}}, a};
multiplicand <= {{8{b[7]}}, b};
end
else
begin
if(ctr < 16)
begin
if(multiplier[ctr]==1)
begin
multiplicand = multiplicand<<ctr;
p <= p + multiplicand;
end
ctr <= ctr+1;
end
else
begin
rdy <= 1;
end
end
end //End of always block
endmodule
And here's my testbench:
`timescale 1ns/1ns
`define width 8
`define TESTFILE "test_in.dat"
module seq_mult_tb () ;
reg signed [`width-1:0] a, b;
reg clk, reset;
wire signed [2*`width-1:0] p;
wire rdy;
integer total, err;
integer i, s, fp, numtests;
// Golden reference - can be automatically generated in this case
// otherwise store and read from a file
wire signed [2*`width-1:0] ans = a*b;
// Device under test - always use named mapping of signals to ports
seq_mult dut( .clk(clk),
.reset(reset),
.a(a),
.b(b),
.p(p),
.rdy(rdy));
// Set up 10ns clock
always #5 clk = !clk;
// A task to automatically run till the rdy signal comes back from DUT
task apply_and_check;
input [`width-1:0] ain;
input [`width-1:0] bin;
begin
// Set the inputs
a = ain;
b = bin;
// Reset the DUT for one clock cycle
reset = 1;
#(posedge clk);
// Remove reset
#1 reset = 0;
// Loop until the DUT indicates 'rdy'
while (rdy == 0) begin
#(posedge clk); // Wait for one clock cycle
end
if (p == ans) begin
$display($time, " Passed %d * %d = %d", a, b, p);
end else begin
$display($time, " Fail %d * %d: %d instead of %d", a, b, p, ans);
err = err + 1;
end
total = total + 1;
end
endtask // apply_and_check
initial begin
// Initialize the clock
clk = 1;
// Counters to track progress
total = 0;
err = 0;
// Get all inputs from file: 1st line has number of inputs
fp = $fopen(`TESTFILE, "r");
s = $fscanf(fp, "%d\n", numtests);
// Sequences of values pumped through DUT
for (i=0; i<numtests; i=i+1) begin
s = $fscanf(fp, "%d %d\n", a, b);
apply_and_check(a, b);
end
if (err > 0) begin
$display("FAIL %d out of %d", err, total);
end else begin
$display("PASS %d tests", total);
end
$finish;
end
endmodule // seq_mult_tb
I also created a file called test_in.dat in which the test cases are stored (first line indicates number of test cases):
10
5 5
2 3
10 1
10 2
20 20
-128 2
10 -128
-1 -1
10 0
0 2
Now the problem is: the code works for only the first two inputs and for the last two inputs. For the remaining inputs, I get a different number than is expected. Can someone point out any logical error in my code that is causing this? Or if there's a much simpler strategy for doing the same, please let me know of that as well.
multiplicand is shifted to the left by ctr in each iteration if multiplier[ctr] is 1.
But ctr already includes the previous shift amounts, so you are shifting too far.
You should just shift multiplicand by 1 in every iteration unconditionally:
multiplicand <= multiplicand << 1;
if (multiplier[ctr] == 1)
begin
p <= p + multiplicand;
end
ctr <= ctr + 1;
You should also use nonblocking assignment for multiplicand. You might need to move the shifting to after adding it to p.

4 bit countetr using verilog not incrementing

Sir,
I have done a 4 bit up counter using verilog. but it was not incrementing during simulation. A frequency divider circuit is used to provide necessory clock to the counter.please help me to solve this. The code is given below
module my_upcount(
input clk,
input clr,
output [3:0] y
);
reg [26:0] temp1;
wire clk_1;
always #(posedge clk or posedge clr)
begin
temp1 <= ( (clr) ? 4'b0 : temp1 + 1'b1 );
end
assign clk_1 = temp1[26];
reg [3:0] temp;
always #(posedge clk_1 or posedge clr)
begin
temp <= ( (clr) ? 4'b0 : temp + 1'b1 );
end
assign y = temp;
endmodule
Did you run your simulation for at least (2^27) / 2 + 1 iterations? If not then your clk_1 signal will never rise to 1, and your counter will never increment. Try using 4 bits for the divisor counter so you won't have to run the simulation for so long. Also, the clk_1 signal should activate when divisor counter reaches its max value, not when the MSB bit is one.
Apart from that, there are couple of other issues with your code:
Drive all registers with a single clock - Using different clocks within a single hardware module is a very bad idea as it violates the principles of synchronous design. All registers should be driven by the same clock signal otherwise you're looking for trouble.
Separate current and next register value - It is a good practice to separate current register value from the next register value. The next register value will then be assigned in a combinational portion of the circuit (not driven by the clock) and stored in the register on the beginning of the next clock cycle (check code below for example). This makes the code much more clear and understandable and minimises the probability of race conditions and unwanted inferred memory.
Define all signals at the beginning of the module - All signals should be defined at the beginning of the module. This helps to keep the module logic as clean as possible.
Here's you example rewritten according to my suggestions:
module my_counter
(
input wire clk, clr,
output [3:0] y
);
reg [3:0] dvsr_reg, counter_reg;
wire [3:0] dvsr_next, counter_next;
wire dvsr_tick;
always #(posedge clk, posedge clr)
if (clr)
begin
counter_reg <= 4'b0000;
dvsr_reg <= 4'b0000;
end
else
begin
counter_reg <= counter_next;
dvsr_reg <= dvsr_next;
end
/// Combinational next-state logic
assign dvsr_next = dvsr_reg + 4'b0001;
assign counter_next = (dvsr_reg == 4'b1111) ? counter_reg + 4'b0001 : counter_reg;
/// Set the output signals
assign y = counter_reg;
endmodule
And here's the simple testbench to verify its operation:
module my_counter_tb;
localparam
T = 20;
reg clk, clr;
wire [3:0] y;
my_counter uut(.clk(clk), .clr(clr), .y(y));
always
begin
clk = 1'b1;
#(T/2);
clk = 1'b0;
#(T/2);
end
initial
begin
clr = 1'b1;
#(negedge clk);
clr = 1'b0;
repeat(50) #(negedge clk);
$stop;
end
endmodule

Verilog code 2 errors i can't find: Would be grateful for an extra pair of eyes to spot a mistake i might've overlooked

I'm writing a verilog code where i'm reading two files and saving those numbers into registers. I'm then multiplying them and adding them. Pretty much a Multiplication Accumulator. However i'm having a hard frustrating time with the code that i have. It read the numbers from the files correctly and it multiples but here is the problem? When i first run it using ModelSim, I reset everything so i can clear out the accumulator. I then begin the program, but there is always this huge delay in my "macc_out" and i cannot seem to figure out why. This delay should not be there and instead it should be getting the result out A*B+MAC. Even after the delay, it's not getting the correct output. My second problem is that if i go from reset high, to low (start the program) and then back to reset high ( to reset all my values), they do not reset! This is frustrating since i've been working on this for a week and don't know/can't see a bug. Im asking for an extra set of eyes to see if you can spot my mistake. Attached is my code with the instantiations and also my ModelSim functional Wave Form. Any help is appreciated!
module FSM(clk,start,reset,done,clock_count);
input clk, start, reset;
output reg done;
output reg[10:0] clock_count;
reg [0:0] macc_clear;
reg[5:0] Aread, Bread, Cin;
wire signed [7:0] a, b;
wire signed [18:0] macc_out;
reg [3:0] i,j,m;
reg add;
reg [0:0] go;
reg[17:0] c;
parameter n = 8;
reg[1:0] state;
reg [1:0] S0 = 2'b00;
reg [1:0] S1 = 2'b01;
reg [1:0] S2 = 2'b10;
reg [1:0] S3 = 2'b11;
ram_A Aout(.clk(clk), .addr(Aread), .q(a));
ram_B Bout(.clk(clk), .addr(Bread), .q(b));
mac macout(.clk(clk), .macc_clear(macc_clear), .A(a), .B(b), .macc_out(macc_out), .add(add));
ram_C C_in(.clk(clk), .addr(Cin), .q(c));
always #(posedge clk) begin
if (reset == 1) begin
i <= 0;
add<=0;
j <= 0;
m <= 0;
clock_count <= 0;
go <= 0;
macc_clear<=1;
end
else
state<=S0;
case(state)
S0: begin
// if (reset) begin
// i <= 0;
// add<=0;
// j <= 0;
// m <= 0;
// clock_count <= 0;
// go <= 0;
// macc_clear<=1;
// state <= S0;
// end
macc_clear<=1;
done<=0;
state <= S1;
end
S1: begin
add<=1;
macc_clear<=0;
clock_count<=clock_count+1;
m<=m+1;
Aread <= 8*m + i;
Bread <= 8*j + m;
if (m==7) begin
state <= S2;
macc_clear<=1;
add<=0;
end
else
state <=S1;
end
S2: begin
add<=1;
macc_clear<=0;
m<=0;
i<=i+1;
if (i<7)
state<=S1;
else if (i==8) begin
state<=S3;
add<=0;
end
end
S3: begin
add<=1;
i<=0;
j<=j+1;
if(j<7)
state<=S1;
else begin
state<=S0;
done<=1;
add<=0;
end
end
endcase
end
always # (posedge macc_clear) begin
Cin <= 8*j + i;
c <= macc_out;
end
endmodule
module mac(clk, macc_clear, A, B, macc_out, add);
input clk, macc_clear;
input signed [7:0] A, B;
input add;
output reg signed [18:0] macc_out;
reg signed [18:0] MAC;
always #( posedge clk) begin
if (macc_clear) begin
macc_out <= MAC;
MAC<=0;
end
else if (add) begin
MAC<=(A*B)+ MAC;
macc_out<=MAC;
end
end
endmodule
module ram_A( clk, addr,q);
output reg[7:0] q;
input [5:0] addr;
input clk;
reg [7:0] mem [0:63];
initial begin
$readmemb("ram_a_init.txt", mem);
end
always #(posedge clk) begin
q <= mem[addr];
end
endmodule
module ram_C(clk,addr, q);
input [18:0] q;
input [5:0] addr;
input clk;
reg [18:0] mem [0:63];
always #(posedge clk) begin
mem[addr] <= q;
end
endmodule
ModelSim Functional Simulation Wave Form
1) Take a look at the schematic view for your MACC module - I think some of your "problems" will be obvious from that;
2) Consider using an always#(*) (Combinational) block for your FSM control signals (stuff like add or macc_clear) rather than a always#(posedge clk) (sequential) - it makes the logic to assert them easier. Right now they're registered, so you have a cycle delay. ;
3) In your MAC, you clear the MAC register on a reset, but you don't clear the macc_out register.
In short, I think you need to step back, and consider which signals are combinational logic, and which ones are sequential and need to be in registers.

How to execute task concurrently with other statements in an always block?

I am writing code for 8*4 RAM in Verilog. For each binary cell of memory, I am using an SR flip-flop. Initially, each cell is assigned 1'bx. The logic seems to be correct, but the output isn't. It is probably because statements are not getting executed concurrently. Can anyone suggest how can I get the task SRFlipFlop to get executed concurrently with other statements?
module memory(addr, read_data, rw, write_data, clk);
// read_data is the data read
// rw specifies read or write operation. 1 for read and 0 for write
// write data is the data to be written
// addr is the address to be written or read
task SRFlipFlop;
input d,r,s,clk; // d is the value initially stored
output q;
begin
case({s,r})
{1'b0,1'b0}: q<=d;
{1'b0,1'b1}: q<=1'b0;
{1'b1,1'b0}: q<=1'b1;
{1'b1,1'b1}: q<=1'bx;
endcase
end
endtask
task decoder; // a 3 to 8 line decoder
input [2:0] A;
input E;
output [7:0] D;
if (!E)
D <= 16'b0000000000000000;
else
begin
case (A)
3'b000 : D <= 8'b00000001;
3'b001 : D <= 8'b00000010;
3'b010 : D <= 8'b00000100;
3'b011 : D <= 8'b00001000;
3'b100 : D <= 8'b00010000;
3'b101 : D <= 8'b00100000;
3'b110 : D <= 8'b01000000;
3'b111 : D <= 8'b10000000;
endcase
end
endtask
output reg [3:0] read_data;
input [3:0] write_data;
input [2:0] addr;
input rw, clk;
reg [3:0] memory [7:0];
reg [3:0] r [7:0];
reg [3:0] s [7:0];
reg [3:0] intermediate;
reg [3:0] select [7:0];
reg [7:0] out;
reg [7:0] out1;
integer i,j,k,l;
initial
begin
for (i = 0; i <= 7; i=i+1)
begin
for (j = 0; j <= 3; j=j+1)
begin
memory[i][j] = 1'bx;
r[i][j] = 1'b0;
s[i][j] = 1'b0;
select[i][j] = 1'b0;
end
end
end
always #(posedge clk)
begin
decoder(addr, 1'b1, out);
for (i = 0; i <= 7; i=i+1)
begin
if (out[i] == 1'b1)
begin
for (j = 0; j <= 3; j=j+1)
begin
select[i][j] <= 1'b1;
s[i][j] <= write_data[j] & !rw & select[i][j];
r[i][j] <= !write_data[j] & !rw & select[i][j];
SRFlipFlop(memory[i][j],r[i][j],s[i][j],clk,intermediate);
memory[i][j] <= intermediate;
read_data[j] <= memory[i][j];
end
end
end
end
endmodule
Your code style is very software-oriented. Personally I like to know how my code will look as a circuit, so instead of using nested for loops and tasks I will use modules and generate-loops to create my circuits.
I have not been able to make your code work, but I suspect that the error is in the fact that s and r are not reset to zero on every iteration.
I have created a functioning design here:
http://www.edaplayground.com/x/Guc
Instead of using the initial block to initialize values I have added an asynchronous reset.
The SRFF-task has been converted to a module. A RAMblock module instantiates four SRFF-modules. 8 RAMblocks are instantiated in the memory module.
I have converted your packed(reg [] a []) arrays into unpacked arrays(reg [][] a) to be able to perform bitwise operations on several bits without for-loops.
If you have questions about the code, feel free to message me.
Edit: Perhaps the most important thing to note in this design is that I separate the sequential circuitry from the combinatorial. This way it is much easier to control what should be updated on the posedge of clk and what should just be a combinatorial reaction to the changes performed at the posedge.

calculate how many times input is repeated verilog

I'm trying to calculate times in which input x with 8 bits is repeated on every posedge clk.
I'm thinking about creating 256b counter to each value of these 8 bit to compare x with it, but I get error when I'm trying to compare each value of these counter with each input x on rising edge.
module counter_initial(x);
input[7:0] x;
//output [7:0] y;
//reg [7:0] y;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] freq_num;
endmodule
module counter_256(clk,x,out);
input [7:0] x;
input clk;
// input [7:0] in;
output [7:0] out;
reg [7:0] out;
//reg [7:0] freq_tst,gap_tst;
reg [7:0] k=0;
// reg [] t=0;
genvar i;
generate
for (i=0;i<256;i=i+1)
begin
counter_initial m(i);
//t=m(i);
end
endgenerate
always #(posedge clk)
begin
if(k<256) begin
if (x==m[i])
//counter_initial[k]==x
begin
freq_num=freq_num+1;
end
//else
//begin gap_tst=gap_tst+1; end
k=k+1;
end
end
endmodule
You don't need an additional module to count. You can use a memory array. Example:
input [WIDTH-1:0] x;
reg [7:0] mem [WIDTH-1:0];
integer i;
always #(posedge clk) begin
if (reset) begin
for (i = 0; i < 2**WIDTH; i = i+1) begin
mem[i] <= 8'b0;
end
end
else if (mem[x] < 8'd255) begin // cap counting and prevent overflow
mem[x] <= mem[x] + 1'b1;
end
end
If you want to use separate modules then pass the clock to it. Example:
module counter (output reg [7:0] count, input increment, clk, reset);
always #(posedge clk) begin
if (reset) begin
count <= 8'b0;
end
else if (count < 8'd255) begin // cap counting and prevent overflow
count <= count + increment;
end
end
endmodule
module my_device ( /* ..., */ input [7:0] x, input clk, reset );
/* ... */
genvar i;
generate
for (i=0; i<256; i=i+1) begin
counter icount( .count(/* ... */), .increment(x==i), .* );
end
endgenerate
/* ... */
endmdoule
Reminder 8'd255 + 1 is 8'd0 because the MSB of 8'd256 is out of range. I capped the counters so the will not overflow and roll back to zero.

Resources