-1

I'm a complete beginner when it comes to Verilog. I have a block ROM which is as follows:

module CDbram_2_0_32 (clk, en, addr, dout);
input clk;
input en;
input [9:0] addr;
output [9:0] dout [0:37];

(*rom_style = "block" *) reg [9:0] data [0:37];

always @(posedge clk)
begin
if (en)
case(addr)
10'd0:data<={10'd19,10'd7,10'd27,-10'd1,10'd14,-10'd1,10'd11,10'd11,-10'd1,10'd19,-10'd1,10'd19,-10'd1,-10'd1,10'd28,10'd23,-10'd1,10'd12,-10'd1,10'd23,-10'd1,10'd4,-10'd1,10'd8,-10'd1,10'd18,-10'd1,-10'd1,10'd18,-10'd1,10'd19,-10'd1,10'd12,-10'd1,-10'd1,10'd15,-10'd1,-10'd1};
10'd1:data<={10'd22,10'd9,-10'd1,10'd1,10'd30,10'd11,10'd25,-10'd1,10'd31,10'd2,10'd19,-10'd1,10'd11,10'd30,-10'd1,10'd20,10'd26,-10'd1,10'd30,-10'd1,10'd14,-10'd1,-10'd1,-10'd1,10'd2,-10'd1,-10'd1,10'd10,-10'd1,-10'd1,-10'd1,10'd25,-10'd1,-10'd1,10'd31,-10'd1,-10'd1,10'd1};
10'd2:data<={-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,-10'd1,10'd31,-10'd1,10'd11,-10'd1,10'd29,-10'd1,10'd5,-10'd1,10'd7,-10'd1,-10'd1,10'd4,-10'd1,-10'd1,10'd6,-10'd1,-10'd1,-10'd1,10'd0,-10'd1};
....(and so on till addr 13)
endcase
end

assign dout = data;

endmodule

What I want to do is run 38 instances of a module (CN) in parallel. Each address of BROM has 38 values, so at each posedge, I want all the module instances to read their respective dout[index] and save the output in P2[index], like this:

for (j=0; j<14; j=j+1) begin: cn_instances
CN inst0 (.data_in(m[j]), .shift_amt(dout[0]), .data_out(p2_temp[0]));  assign p2[0] = p2[0]^p2_temp[0];

I'm sure my code is completely wrong, but I'm not sure where. I know that generating a for loop will only generate more instances, which is not what I want, but a regular for loop doesn't run with module instances. I'm so confused.

`timescale 1ns / 1ps


module P2_inst (
    input clk,             // Clock signal
    input rst,             // Reset signal (active high)
    input en,              // Enable reading (active high)
    input [447:0] message,
    output reg [9:0] dout [0:13],  // Output data from ROM
    output reg [9:0] addr,          // Current address
    output reg [31:0] p2 [0:37]
);

reg [31:0] m [0:13];
assign {m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13] }= message;
reg [31:0] p2_temp [0:37];

CDbram_2_0_32 rom (
    .clk(clk),
    .en(en),       // Enable ROM read
    .addr(addr),   // Current address
    .dout(dout)    // Output data
);
always @(posedge clk or posedge rst) begin
    if (rst) begin
        addr <= 10'd0;  // Reset to address 0
    end
    else if (en) begin
        if (addr < 10'd531) begin  // Stop at last address (531)
        addr <= 10'd0;
genvar j;
for (j=0; j<14; j=j+1)begin: cn_instances
j<=addr;
CN inst0 (.data_in(m[j]), .shift_amt(dout[0]), .data_out(p2_temp[0]));  assign p2[0] = p2[0]^p2_temp[0];
CN inst1 (.data_in(m[j]), .shift_amt(dout[1]), .data_out(p2_temp[1]));  assign p2[1] = p2[1]^p2_temp[1];
....
CN inst37 (.data_in(m[j]), .shift_amt(dout[37]), .data_out(p2_temp[37]));  assign p2[37] = p2[37]^p2_temp[37];

        end
        else begin
            addr <= 10'd0;   // Wrap around (optional)
        end
    end
end

endmodule

Any help is appreciated.

3
  • Your requirements are contradictory. You claim you don’t want 38 instances of a module, yet you want to run them in parallel. That’s the same thing. Commented Jun 17 at 16:08
  • @dave_59 I already have 38 module instances, and I want to run a for loop of 14 iterations through the module instances. I don't want to use a generate for loop because that would create 38*14 instances (from my understanding of generate block). i just want to pass my message that is divided into 14 parts (m[0:13]) through the module instances. But regular for loop using integer doesn't allow module instances in it. Commented Jun 17 at 17:06
  • Use a mod-14 up-counter to increment j and use that as the index for m Commented Jun 20 at 5:05

1 Answer 1

0

There are two parts to verilog program: dynamic and static.

Dynamic is similar to any programming language, like c/c++. This programming is contained within procedural blocks: always..., initial, final. They can use conditional statements and loops in a dynamic manner. There are certain limitation on styles, imposed by the synthesis tools if you want to synthesize that code. But other than that it is just a regular programming language with additional simulation control statements enclosed within begin/end of an always or other blocks.

Static part is a statical hierarchical structure of a design which includes module instances, procedural blocks. As you can imagine, one has to manually define every instance, every always block there statically. 'generate' blocks actually help you with creating this static structure. It allows you to use limited conditional statements and limited types of loops to generate this static structure. They only accept constants, i.e., parameters or special 'genvar' variables as arguments. A result of such a generate block is just a set of instances or always blocks.

So, here is an example:

module top(input myvar[2:0]);
for(genvar i = 0; i < 2; i++) begin: myloop
   mymodule myinst(myvar[i]);
end
endmodule: top

it is equivalent to

module top(input myvar[2:0]);
   mymodule myinst[0](myvar[0]);
   mymodule myinst[1](myvar[1]);
   mymodule myinst[2](myvar[2]);
endmodule: top

So, in your example you created not 38 instance, but 38x14 = 532 instances:

CN inst0[0] (.data_in(m[0]), .shift_amt(dout[0]), .data_out(p2_temp[0]));  
assign p2[0] = p2[0]^p2_temp[0];
CN inst1[0] (.data_in(m[0]), .shift_amt(dout[1]), .data_out(p2_temp[1]));  
assign p2[1] = p2[1]^p2_temp[1];
....
CN inst37[13] (.data_in(m[13]), .shift_amt(dout[37]), .data_out(p2_temp[37]));  
assign p2[37] = p2[37]^p2_temp[37];

You also created 532 assign statements, among those there are 14 which assign to p2[0], then 14 assigning to p2[1] snf do on. In other words every element in assign has 14 inputs. With a large probability the result will be 'x', unless all of the 14 inputs have the same value. Same story with the output of the module, data_out.

Having that in mind, you should be able to design your generate loop in a better manner.

It looks to me that you can use something like the following:

for (genvar j = 0; j < 38; j++) begin: loop
    CN inst (.data_in(m), .shift_amt(dout[j]), .data_out(p2_temp[j]));  
    assign p2[j] = p2[j]^p2_temp[j];
end

The above will create 38 instances of CN. It will pass m as the whole vector and other array elements to it as ports. You have to deal with m within the module or some other way.

It will not create any multiple-driven situation there.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.