How can I use module inside another module? - hardware

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

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.

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 to pass array structure between two verilog modules

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

Why is XST optimizing away my registers and how do I stop it?

I have a simple verilog program that increments a 32 bit counter, converts the number to an ASCII string using $sformat and then pushes the string to the host machine 1 byte at a time using an FTDI FT245RL.
Unfortunately Xilinx XST keeps optimizing away the string register vector. I've tried mucking around with various initialization and access routines with no success. I can't seem to turn off optimization, and all of the examples I find online differ very little from my initialization routines. What am I doing wrong?
module counter(CK12, TXE_, WR, RD_, LED, USBD);
input CK12;
input TXE_;
output WR;
output RD_;
output [7:0] LED;
inout [7:0] USBD;
reg [31:0] count = 0;
reg [7:0] k;
reg wrf = 0;
reg rd = 1;
reg [7:0] lbyte = 8'b00000000;
reg td = 1;
parameter MEM_SIZE = 88;
parameter STR_SIZE = 11;
reg [MEM_SIZE - 1:0] str;
reg [7:0] strpos = 8'b00000000;
initial
begin
for (k = 0; k < MEM_SIZE; k = k + 1)
begin
str[k] = 0;
end
end
always #(posedge CK12)
begin
if (TXE_ == 0 && wrf == 1)
begin
count = count + 1;
wrf = 0;
end
else if (wrf == 0) // If we've already lowered the strobe, latch the data
begin
if(td)
begin
$sformat(str, "%0000000000d\n", count);
strpos = 0;
td = 0;
end
str = str << 8;
wrf = 1;
strpos = strpos + 1;
if(strpos == STR_SIZE)
td = 1;
end
end
assign RD_ = rd;
assign WR = wrf;
assign USBD = str[87:80];
assign LED = count[31:24];
endmodule
Loading device for application
Rf_Device from file '3s100e.nph' in
environment /opt/Xilinx/10.1/ISE.
WARNING:Xst:1293 - FF/Latch str_0
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_1
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
WARNING:Xst:1896 - Due to other
FF/Latch trimming, FF/Latch str_2
has a constant value of 0 in block
. This FF/Latch will be
trimmed during the optimization
process.
The $sformat task is unlikely to be synthesisable - consider what hardware the compiler would need to produce to implement this function! This means your 'str' register never gets updated, so the compiler thinks it can optimize it away. Consider a BCD counter, and maybe a lookup table to convert the BCD codes to ASCII codes.
AFAIK 'initial' blocks are not synthesisable. To initialize flops, use a reset signal. Memories need a 'for' loop like you have, but which triggers only after reset.