How to pass array structure between two verilog modules - module

I am trying to pass a array structure as reg [0:31]instructionmem[0:31] between two modules.
I coded it as follows :
Module No 1:
module module1(instructionmem);
output reg [0:31]instructionmem[0:31];
------------------
----lines of code---
---------------
endmodule
Module No 2:
module module2(instructionmem);
input [0:31]instructionmem[0:31];
--------------------------------
-----line of code---------------
-------------------------------
endmodule
Testbench:
module test_bench();
wire [0:31]instructionmem[0:31];
module1 m1(instructionmem);
module2 m2(instructionmem);
endmodule
I am getting errors for this implementation. So how can we send such array structures ?

This is not possible in Verilog. (See sec. 12.3.3, Syntax 12-4 of the Verilog 2005 standard document, IEEE Std. 1364-2005.)
Instead you should "flatten" the array and pass it as a simple vector, e.g.:
module module1(instructionmem);
output [32*32-1:0] instructionmem;
reg [31:0] instructionmem_array [31:0];
genvar i;
generate for (i = 0; i < 32; i = i+1) begin:instmem
assign instructionmem[32*i +: 32] = instructionmem_array[i];
end endgenerate
endmodule
module module2(instructionmem);
input [32*32-1:0] instructionmem;
reg [31:0] instructionmem_array [31:0];
integer i;
always #*
for (i = 0; i < 32; i = i+1)
instructionmem_array[i] = instructionmem[32*i +: 32];
endmodule
module test_bench(instructionmem);
output [32*32-1:0] instructionmem;
module1 m1(instructionmem);
module2 m2(instructionmem);
endmodule

Related

Checker not found. promblem in verilog modelsim

module Vr_ALU (A, B, ALUCtrl, ALUOut, Zero);
input [31:0] A;
input [31:0] B;
input [2:0] ALUCtrl;
output [31:0] ALUOut;
output Zero;
wire [31:0] sig_a;
wire [31:0] sig_b;
wire [31:0] sig_sum;
wire sig_cin;
wire sig_cout;
always #(*) begin
if(ALUCtrl==2'b010)
Vr_ripple_adder_M_bits U1(.A(sig_a), .B(sig_b), .CIN(sig_cin), .S(sig_sum), .COUT(sig_cout));
else if(ALUCtrl==2'b110)
Vr_ripple_adder_M_bits U2(.A(sig_a), .B(~sig_b), .CIN(~sig_cin), .S(sig_sum), .COUT(~sig_cout));
else ALUOut = 2'bx;
end
assign Zero = (ALUCtrl==2'b110 && ALUOut==0)? 1:0;
endmodule
at this code, I try to make module work as adder when ALUCtrl is 010, and as subtractor when ALUCtrl is 110. But I'm having 'checker not found. Instantiation must be of a visible checker' problem.
Need help.
You cannot instantiate modules in always blocks. You cannot instantiate module conditionally. Modules represent hardware and as such they are always present.
Instead you can use muxes to switch inputs in your module. For example,
reg[31:0] sig_b_temp;
reg sig_cin_temp;
reg sig_cout_temp;
reg sig_cout; // uou need 'reg' for this example.
// muxes
always #(*) begin
if(ALUCtrl==2'b010) begom
//inuts
sig_cin_temp = sig_sin;
sig_b_temp = sig_b;
//outputs
sig_cout = sig_cout_temp;
end
else begin
//inputs
sig_cin_temp = ~sig_sin;
sig_b_temp = ~sig_b;
//output
sig_cout = ~sig_cout_temp;
end
end
//single module instance
Vr_ripple_adder_M_bits U1(.A(sig_a),
.B(sig_b_temp),
.CIN(sig_cin_temp),
.S(sig_sum),
.COUT(sig_cout_temp));
Note, the code above will not compile with

Verilog HDL syntax error at test_bench_lb2.v(14) near text "genvar"; expecting "end"

I am new one in Verilog and I need to write a simple test bench, but I get an error and I cannot understand why it is
Here is my code
`timescale 1 ns / 1 ns
module test_bench_lb2;
reg [12:0] in_lines_tb;
wire [4:0] out_lines_tb;
wire error_tb;
localparam PERIOD = 10;
initial
begin
genvar i;
for(i = 0; i <= 8000; i = i + 1)
begin
in_lines_tb = i;
#PERIOD;
end
#(PERIOD*20) $stop;
end
initial
begin
$monitor("time = %time in_lines = %b out_lines = %b error = %b",
$time, in_lines_tb, out_lines_tb, error_tb);
end
DESHIFRATOR inst1(.in_lines(in_lines_tb), .out_lines(out_lines_tb), .error(error_tb));
endmodule
This
genvar i;
should be this
integer i;
A genvar is a special kind of variable used in a construct called a generate loop. You code uses an ordinary for loop.

How to resolve the delay problem between two modules in Verilog

I am trying to implement BIST (Built-in self-test). Test pattern generator(TPG) module generates test patterns using LFSR per posedge clk (always #1 clk = ~clk). I am using 32 stage LFSR. Each value of TPG module is sent to the AES encryption module which gives ciphertext after #141 delay. During this #141 delay many of the TPG module outputs are lost. How to solve this problem?
I thought a solution is to store thousand test pattern values in the array (reg [127:0] arr [0:999]) and then send each test pattern to the AES encryption module. Is this a good solution because I think it is making chip memory bigger. If it is then what should I do? The code snippet is given below.
wire [127:0] state_byte;
TPG T (clk, rst, bistMode, state_byte);
AES_encryption ENC_TB(key_byte, state_byte, clk, rst, encryptionEnable, state_out_byte, load, ready);
codes of TPG module is given below:
module TPG (input wire clk, input wire rst, input wire sel, output reg[127:0] valueO);
integer i;
reg [31:0] patternGenerate[0:3],temp;
always #(posedge clk)begin
if(sel == 1)begin
if(rst)begin
valueO = 128'b0;
temp = 32'b11111111111111111111111111111111;
end
else
begin
for(i=0;i<4;i=i+1)begin
temp = {(temp[31] ^ temp[25] ^ temp[22] ^ temp[21] ^ temp[15] ^ temp[11] ^ temp[10] ^ temp[9] ^ temp[7] ^ temp[6] ^ temp[4] ^ temp[3] ^ temp[1] ^ temp[0]), temp[31:1]};
patternGenerate[i] = temp;
end
valueO = {patternGenerate[3],patternGenerate[2],patternGenerate[1],patternGenerate[0]};
end
end
end
endmodule

Variable assignment in SystemVerilog generate statement

I have created a simple module that I replicate several times using the Verilog generate statement. However, it seems that the generate statement somehow effects variable assignment in the module. Here's the code:
module test();
timeunit 10ns;
timeprecision 1ns;
wire[3:0] out;
reg[3:0] values[0:4] = {5, 6, 7, 8, 9};
logic clk;
generate
genvar i;
for (i=0; i < 5; i++) begin: M1
MUT mut(
.out,
.in(values[i]),
.clk
);
end
endgenerate
initial begin
#1 clk = 0;
$monitor("%b %b %b %b %b\n", M1[0].mut.out, M1[1].mut.out, M1[2].mut.out, M1[3].mut.out, M1[4].mut.out);
#10 $stop;
end
always #1 clk++;
endmodule
module MUT(output [3:0] out, input [3:0] in, input clk);
reg[3:0] my_reg[0:7];
assign out = my_reg[7];
always #(posedge clk) begin
my_reg[7] <= in; //5
end
endmodule
The expected output of this test program would be 0101 0110 0111 1000 1001, however the output I get is xxxx xxxx xxxx xxxx. It seems that the values in the values variable in the test module are not getting assigned to the out variable in the MUT module. However, when I replace my_reg[7] <= in; with say, my_reg[7] <= 5;, the code works as expected. The code also works when I assign directly to out (after declaring it as register) i.e. out <= in;. There's no problem if I replicate the MUT modules 'manually' without using any generate statements.
You are not connecting the outputs to separate wires. So they are implicitly tied together(like how it did for clock) resulting multiple drivers for a bit.
Just add
wire[3:0] out[0:4];
generate
genvar i;
for (i=0; i < 5; i++) begin: M1
MUT mut(
.out(out[i]), // Connect to different wires
.in(values[i]),
.clk
);
end
endgenerate
Try to initialize clk variable with 0.

How can I use module inside another module?

I am trying to design a simple 8-bit 2's complementor. Here is my code:
twos_complement_of_8bits.v
//`include "complementor.v"
module twos_complement_of_8bits(output [7:0] out, input [7:0] in);
integer i;
initial
begin
for(i = 0; i <= 7; i = i + 1)
complementor C(out[i], in[i]);
end
assign out = out + 1;
endmodule
I got an error at this line:
complementor C(out[i], in[i]);
Syntax error near 'C' found.
How can I fix it?
I think you can eliminate your complementor module, then change your twos_complement_of_8bits as follows:
module twos_complement_of_8bits (output [7:0] out, input [7:0] in);
assign out = ~in + 1;
endmodule
If that doesn't give you the output you want, please show some expected output values.
In more complicated situations, you can place arrays of instances of modules or use a generate block.
Here is an example of how to use a generate block:
module twos_complement_of_8bits (output [7:0] out, input [7:0] in);
wire [7:0] out_ones;
genvar i;
generate
for (i=0; i<=7; i=i+1) begin
complementor C[i] (out_ones[i], in[i]);
end
endgenerate
assign out = out_ones + 1;
endmodule