how to define N bus with width 32bit - verilog

I wanted to define large number of bus with bus width 32bit.
for example
input [31:0] a0, a1, a2, .... aN;
input [31:0] b0, b1, b2, .... bN;
output [31:0] c0, c1, c2, .... cN;
c0 = a0 + b0;
c1 = a1 + b1;
.
.
cN = aN + bN;
how can I realize this code with iteration?

Verilog Generates are designed for solving this issue. It would be easier if you can use unpacked arrays for ports.
Statements need to be contained in an initial or always, to imply the output is a flip-flop use always #(posedge clk) for a combinatorial circuit use always #*.
module example (
parameter N = 10
)(
input clk,
input [31:0] a [0:N],
input [31:0] b [0:N],
output reg [31:0] c [0:N]
);
genvar i;
generate
for(i=0; i<=N; i++) begin
always #(posedge clk) begin
c[i] <= a[i] + b[i];
end
end
endgenerate
endmodule
Generates are good when you need to parameterise module instance, the above can be rewritten with a plain for loop.
integer i;
always #(posedge clk) begin
for(i=0; i<=N; i++) begin
c[i] <= a[i] + b[i];
end
end
For synthesizable code the for loop must be able to be statically unrolled.

Related

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.

verilog average, add n-bit numbers together and then divide by nbit numbers

I am having trouble putting this code together my main code is a state machine it adds 2 numbers together = sum then loads A to add A to sum(sum=a+sum) after clock is reached it then divides by n bit. I'm lost putting it together. In having Lots of trouble assigning outputs. what is legal and what is not am I able to set the regs equal to each other sometimes I feel like I can do that and some other times I cannot.if I use the module can the input be an output and vice versa I posted my whole code cause I wanted to get it to work. I think my device is correct but I need to create a test bench to tested.
module Adder (A1, B1, Cin,Q);
parameter n = 5;
output[n:0]Q;
reg [n:0]Q;
input [n:0] A1;
wire[n:0] A1;
input [n:0] B1;
wire [n:0] B1;
input Cin;
always #(A1 or B1 or Cin)
begin
Q = A1 +B1 + Cin;
end
endmodule
module ave(Clk,X,LA,DataA,Sum,Q);
parameter n=5;
input A,B,EB,Temp,DataA,DataB,Sum,Q;
input X;
reg A,B,Temp,Sum;
reg y,Y
wire
reg S1=3'b000;S2=3'b001;S3=3'b010;S4=3'b011;S5=3'b100;
always (Clk)
begin
case(y)
S1:
y=S2;
S2:
y=S3;
S3:
if (counter>0) y=S2;
else y=S4;
S4:
y=S4;
S5:
Done;
endcase
end
always (Clk)
begin
case
S1:
Counter=n; Temp=n; Sum=0;
S2:
A=X;
S3:
if (counter>0) B<=A+B;
else B<=B;
S4:
DataA=Temp;
DataB=Sum;
S5:
Done=1;
end
Adder add(A,Sum,Cin,Sum);
divider divid(Clk,1,1,1,1,DataA,DataB,1,1,Q,0);
endmodule
this is my divider plus the other modules:
module shiftlne(R,C,L,w,Clk,Q);
parameter n=8;
input [n-1:0]R;
input L,w,Clk,C;
output [n-1:0]Q;
reg [n-1:0]Q;
integer k;
always #(posedge Clk)
begin
if(L)begin
if(C)begin
Q<=R;end
else
begin
for (k=0;k<(n-1);k=(k+1))
Q[k+1]=Q[k];
Q[0]<=w;
end
end
end
endmodule
module downcounter (R,E,L,Clk,Q);
parameter n=8;
input[n-1:0]R;
input Clk,L,E;
output [n-1:0]Q;
reg[n-1:0]Q;
always #(posedge Clk)
begin if(L)
Q<=R;
else if(E)
Q<=(Q-1);
end
endmodule
module muxdff( D0, D1, Sel, Clk,Q);
input Clk,D0,D1,Sel;
wire D;
output Q;
reg Q;
assign D=Sel?D1:D0;
always # (posedge Clk)
begin
Q=D;
end
endmodule
module regne (R,Clk,Resetn,E,Q);
parameter n=8;
input [n-1:0]R;
input Clk,Resetn,E;
output [n-1:0]Q;
reg [n-1:0] Q;
always #(posedge Clk or negedge Resetn)
begin
if (Resetn==0)
Q<=0;
else if (E)
Q<=R;
end
endmodule
Are you stuck using Verilog-95 if not you can clean up the code style, if nothing else it helps spot the bugs easier.
NB: Uses spaces to indent your code, not tabs as they mess up the formatting when posting Q's and can look different to people review your code depending on how there editor is setup.
module Adder #(
parameter n = 5
)(
input [n:0] A1, //Inputs do not have to be declared as wires
input [n:0] B1,
input Cin,
output reg [n:0] Q;
);
//Auto sensitivity list with #* lowers chance of bugs
always #* begin
Q = A1 + B1 + Cin;
end
endmodule
Most languages, and I apply this to my verilog keep constants like parameters and localparam in UPPERCASE, everything else is lowercase.
Your shiftlne code be made more readable: readable code to me implies easier to spot the bugs and understand the design intention.
always #(posedge Clk) begin
if( L ) begin
if( C ) begin
Q <= R;
end
else begin
for (k=0;k<(n-1);k=(k+1))
Q[k+1] = Q[k]; //For loop only applies to this line
// should it not be Q[k+1] <= Q[k];
Q[0] <= w;
end
end
end
endmodule

Verilog code adding two integers generated by a for loop

How about this? I'm looking for an output i+j=1+2, 2+3... 4+5.
module add(i,j,b);
input [31:0] i, j; //32 bit unsigned
output [31:0] y;
task ADD(i, j, y);
begin
for (i= 1; i <= 4; i++)
begin
for(j=2; j <= 5; j++)
assign y = i + j;
end
end
$display("y ", y);
endtask
endmodule
Is this intended for synthesis? If so you should probably avoid using tasks until you have learnt when they can be used. I never use them in synthesisable code.
functions on the other hand are often used for synthesis but can not contain timing information. Ie a function can only represent combinatorial logic, that all happens in an instant.
1) That is not how you use assign. The correct use would be:
wire [9:0] a;
assign a = 10'b0;
//or
//a,b both 10 bits driven from other logic
wire [9:0] sum;
assign sum = a + b;
Note how you assign to a wire, this is combinatorial.
2) Your display is outside of the for loop it will only display once at the end.
I would have done this some thing like:
module add(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
assign sum = a + b ;
endmodule
module testharness();
reg [31:0] a;
reg [31:0] b;
wire [31:0] sum;
reg clock;
// Make clock toggle every 10ns (20ns clock period)
initial begin
clock = 0;
forever begin
#10ns clock= ~clock;
end
end
//DUT (Device Under Test)
add add_0 (
.a ( a ),
.b ( b ),
.sum ( sum )
);
// Test program
initial begin
a=0;
b=0;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
a=1;
b=2;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
a=3;
b=4;
#(posedge clock);
$display( "a (%2d) + b (%2d) = sum (%2d)", a, b, sum );
$finish;
end
endmodule
Note how we have used time to separate the results, for more complicated designs you may use flip-flops which means you only get a new result per clock. Or per rising and falling edge if using DDR techniques.
You can now try to modify the test program section to stimulate the DUT as per your requirements.

how to define m*n output in verilog

i am writting verilog code for shift left register which store its value after each shift in sub registers. can i define the output registers as array like this,the provided code is just a simple example to show the concept not my code,
module test(a,b,c);
input a,b;
output [7:0] c [3:0];
endmodule
instead of
module test(a,b,c1,c2,c3,c4);
input a,b;
output [7:0] c1,c2,c3,c4;
endmodule
and for the first way how i can call c[i]
... Yes you can very much use a 2D array at the output, like in your first example. Check out Section 5 of this paper by Stuart Sutherland himself, this should give you some confidence. The section is titled Module Ports.
http://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=1&ved=0CC4QFjAA&url=http%3A%2F%2Fwww.sutherland-hdl.com%2Fpapers%2F2006-SNUG-Europe_SystemVerilog_synthesis_paper.pdf&ei=7KmYUNKPN6GyigKDnoHwDA&usg=AFQjCNGmr3flHrARC-w40xveo8zitcdjfg&cad=rja
Also, elaborating on your first example, you can define your module this way for clarity:
module lshift(clk, reset, a, c);
input wire clk, reset;
input wire [7:0] a;
output reg [7:0] c [0:3]; // <-- defining the unpacked dimension as [0:3] for clarity
always#(posedge clk) begin
if(reset) begin
c[0] <= 8'd0;
...
c[3] <= 8'd0;
end
else begin
c[0] <= a;
c[1] <= c[0];
c[2] <= c[1];
c[3] <= c[2];
end
end
endmodule
... and now you can slice into your array. c[0], c[1] .. c[3] each represents a Byte and c[0][3:0] would mean the lower nibble of the first byte.
... Hope this helps!

Resources