Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Verilog - generate multiple interconnected modules

Status
Not open for further replies.

ktsangop

Junior Member level 1
Joined
Apr 2, 2008
Messages
15
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,424
verilog generate

Hi everybody!

I have the following code that works as a shift register :

module sreg (C, SI, SO);
input C,SI;
output SO;
reg [7:0] tmp;

always @(posedge C)
begin
tmp = tmp << 1;
tmp[0] = SI;
end
assign SO = tmp[7];
endmodule


And I want to create multiple instances of the sreg module which are interconnected with eachother. They will all have the same clock and do the same job plus the output of every shift register will provide the input to the next one. Just like the image below :
e3beyzlni9y8hjknmnx1.png


Can anybody please help me on how to do this using the generate/endgenerate statements in verilog?
I understand that i have to put them all inside a higher level module, but cannot find out how the ports will be connected.

Thanks in advance!
 

verilog generate statement

You should use a construct like this
Code:
wire sdata[SIZE+1:0];
genvar i;
generate
for(i=0; i<SIZE; i=i+1) begin:sreggen
  sreg s(clk, sdata[i], sdata[i+1]);
end
endgenerate
 

    ktsangop

    Points: 2
    Helpful Answer Positive Rating
generate verilog

Thanks a lot FvM!!!
That's exactly what i was trying to do but wasn't sure of how to declare the wires...

So the line:
wire sdata[SIZE+1:0];
does not declare a bus of wires right?
just a number of wires that can be placed wherever needed and be referenced by their index?

Thanks again!
 

generate statement in verilog

Yes, the point is that you need an indexed bitvector to connect the modules. The signal declaration isn't different from a bus, but it isn't used as such Please notice, that I didn't check the posted example, I'm mainly using VHDL, but the generate operation is basically identical, so I'm quite sure that it works this way.
 

generate in verilog

It works fine i tested it!
I added something like those two lines
assign sdata[0]=SI;
assign SO=sdata[size+1];
to assign the input to the first wire and the last wire to the output & it worked.

Thanks again!
 

verilog generate example

So now if i want to drive all the shift registers' outputs to the main output also like this :


Is there anyway i can do it?
Depending on some condition the output will be fed by one of the shift registers' outputs.

Thanks in advance.
 

verilog generate statement example

No problem generally, but I don't what condiltion you intend. As an exmaple, it could be an XOR of bits (parity calculation). This could be easily coded. However a calculation merging the elements of a bitvector can't be coded as generate loop, it must use a for loop in a combinational process instead. As a generate loop, the code of a for loop isn't executed sequentially in time rather than immediately in parallel, but unlike an generate statement, the evaluation of statements has a sequential order and a variable signal can be assigned more than once:

Code:
output reg p;

always @(*)
begin
  integer i;
  p=1'b0;
  for (i=0;i<=SIZE;i=i+1)
    p=p^sdata[i+1]; // XOR of all bits 
end
 

generate statement verilog

Hi,
I am ramping up my knowledge of Verilog and I have a use for the generate command. However, in my case, I need to duplicate modules that have multi-bit busses, so I am not getting the syntax correctly.

Take the case of the following common example using an adder:
Code:
module Adder (co, sum, a, b, ci);
        parameter SIZE=4;
        output [SIZE-1:0] sum;
        output            co;
        input  [SIZE-1:0] a, b;
        input             ci;
        wire   [SIZE:0]   c;

        genvar i;

        assign c[0] = ci;
        assign co = c[SIZE];

        generate
                for(i=0; i<SIZE; i=i+1)
                        begin:addbit
                          wire n1,n2,n3;
                          xor g1 (n1, a[i], b[i]);
                          xor g2 (sum[i], n1, c[i]);
                          and g3 (n2, a[i], b[i]);
                          and g4 (n3, n1, c[i]);
                          or  g5 (c[i+1], n2, n3);
                        end
        endgenerate
endmodule

How would this work if a, b and sum were 2-bit busses? In my real case, I am trying to implement an AES-128 function, so I need to duplicate my round function 13 times and I have a 128-bit input to each module.

thanks!
 

generate statements in verilog

Hi Korgull, your question is a bit unclear. I don't see any obvious problem in the Adder module. I tried it in ModelSim with SIZE set to 2. What problem do you see?
 

generate loop verilog

echo47 said:
Hi Korgull, your question is a bit unclear. I don't see any obvious problem in the Adder module. I tried it in ModelSim with SIZE set to 2. What problem do you see?

This example is fine the way it is. However, my question is in regard to "what if" each of the full adders (or any other type of instance) had two bits for each input. So, if a, b and sum were already 2-bit inputs (therefore, with a size of 4, "a" would have 8 inputs, "b" would have 8 input and "sum" would have 8 inputs). I am thinking it might be some sort of an indexed array.. Something like this, but I can't get the syntax correct...

Code:
        parameter SIZE=4;        
        output [SIZE-1:0] [1:0] sum;  // I know this syntax is wrong
        output            co;
        input  [SIZE-1:0] [1:0] a, b;  // wrong syntax too...
        input             ci;
        wire   [SIZE:0]   c;

I'll clarify some more. Like the example at the top of the thread, I can do the following:

Code:
assign c[0]=ci;
assign co=c[SIZE];

I get this, but if CI and CO are say, 2-bit inputs (like I said, I will have a 128-bit input that feeds a serial circuit and passing a 128-bit output). How is it declared here?

Code:
assign c[0]=ci;  // ci is 2-bits, what is the declaration for c[0]?
assign co=c[SIZE]; // same thing here

Better yet.. what if the input for the example I originally gave was not "a" and "b", rather it was just a 2-bit bus named "a"?

thanks for the quick reply!
 

verilog generate loop

Ok, I think I now understand!

Verilog unfortunately doesn't allow passing an array through a module port.
Even though you can easily declare an array of 128 two-bit signals like this:
wire [1:0] sum [0:127];
however, the language won't let you pass that through a module I/O port.

Instead, could do something clumsy such as combining all those two-bit signals into one 256-bit signal, and pass that through the port. When I do that sort of thing, my module becomes an ugly mess of 'for' loops. Does anyone know a cleaner approch?
 

verilog generate module

Bummer.. I have to wonder why it wasn't taken that far? I am trying to replicate some VHDL code that apparently CAN do this sort of thing. What good is replicating just a bunch of single-bit port entities?
 

verilog generate instance

I wonder if SystemVerilog can do it. That could be an option if your tools support SV.
 

verilog generate syntax

echo47 said:
I wonder if SystemVerilog can do it. That could be an option if your tools support SV.

I'm not sure about either case. However, I am using the Cadence AMS environment for my simulation.

Looks like I will have to explicitly state them in my structural netlist.. of maybe I should just learn VHDL..

thanks
 

Can anyone help me, how can i make the output of Sum1, Sum2, Sum3, Sum4, Cout4 in a 7segment display..this my example of verilog hdl program...


module behavrioal_adder (Cin, A, B, C, D, E, F, G, H, Sum1, Sum2,
Sum3, Sum4, Cout4);
input Cin, A, B, C, D, E, F, G, H;
output Sum1, Sum2, Sum3, Sum4, Cout4;
wire Cout1, Cout2, Cout3;

full_adder and1 (A, B, Cin, Cout1, Sum1);
full_adder and2 (C, D, Cout1, Cout2, Sum2);
full_adder and3 (E, F, Cout2, Cout3, Sum3);
full_adder and4 (G, H, Cout3, Cout4, Sum4);

endmodule

the submodule.....
module full_adder (A, B, Cin, Cout, Sum);

input A, B, Cin;
output Sum , Cout;
wire one, two, three;

and (one, A, B);
xor (two, A, B);
and (three, two, Cin);
xor (Sum, two, Cin);
or (Cout, one, three);

endmodule
 

You just need to decode {sum4, sum3, ....} like

Code:
reg [6:0] segment;

always @ (sum1 or sum2 or ....) begin
  case({sum4, sum3, sum2, sum1})
     4'b0000: segment = 7'b0111111;
     4'b0001: segment = 7'b0000110;
     4'b0010: segment = 7'b1011011;
       .....
   endcase
end
 

You just need to decode {sum4, sum3, ....} like

Code:
reg [6:0] segment;

always @ (sum1 or sum2 or ....) begin
  case({sum4, sum3, sum2, sum1})
     4'b0000: segment = 7'b0111111;
     4'b0001: segment = 7'b0000110;
     4'b0010: segment = 7'b1011011;
       .....
   endcase
end

but it is a 5bit output, and it will display 0 - 31, how can i do this?..mean by using two 7 segment display?..
 

but it is a 5bit output, and it will display 0 - 31, how can i do this?
Involves a binary-to-decimal converter, in this case a /10 divider, with quotient and remainder
output. It may be easier to decode the 32 cases explicitely to both 7-segment displays.
 

but it is a 5bit output, and it will display 0 - 31, how can i do this?..mean by using two 7 segment display?..
It's quite clear you need 2 of them to display 0-31 and the idea is still the same as my code, or as being said, using the quotient and remainder approach.
 

It's quite clear you need 2 of them to display 0-31 and the idea is still the same as my code, or as being said, using the quotient and remainder approach.

how can i decode those 5 input variable into only one variable, i am still new in this thing, need to learn from you all the experts
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top