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

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.

Related

Verilog module output reg driving output reg?

So I'm trying to instantiate a module within a module. The root module has output ports that drive the output pins and I want the inner module to drive those ports directly but I can't get it work anyway round.
/*
A root module for the 005_135-scanner_mainboard_revA_sch-pcb. Can be used as a test bench for testing peripheral devices but has been designed to be the master root module for the final code.
All IO is included and reset pins on peripheral devices driven active reset with data lines driven to an appropriate value (located in the ‘initial block’).
George Waller. 09/08/15.
*/
module root_module( ft_reset, ft_usb_prsnt, ft_bus_pwrsav, ft_bus_oe, ft_bus_clkout, ft_bus_siwu, ft_bus_wr, ft_bus_rd, ft_bus_rxf, ft_bus_txe, ft_bus_d,
mtr_fault, mtr_config, mtr_m1, mtr_m0, mtr_rst, mtr_out_en, mtr_step, mtr_dir,
ccd_driver_oe, ccd_p1, ccd_p2, ccd_cp, ccd_rs, ccd_sh,
dac1_sdin, dac1_sclk, dac1_sync, dac2_sdin, dac2_sclk, dac2_sync,
adc_pwrdn, adc_encode, adc_d,
fpga_reset,
clk,
gpio,
led_ctrl,
leds);
//Input declarations
input wire ft_usb_prsnt, ft_bus_clkout, ft_bus_rxf, ft_bus_txe,
mtr_fault,
fpga_reset,
clk;
input wire [7:0] adc_d;
//Output declarations
output reg ft_reset, ft_bus_pwrsav, ft_bus_oe, ft_bus_siwu, ft_bus_wr, ft_bus_rd,
mtr_config, mtr_m1, mtr_m0, mtr_rst, mtr_out_en, mtr_step, mtr_dir,
ccd_driver_oe, ccd_p1, ccd_p2, ccd_cp, ccd_rs, ccd_sh,
adc_pwrdn, adc_encode,
led_ctrl;
output reg dac1_sdin, dac1_sclk, dac1_sync, dac2_sdin, dac2_sclk, dac2_sync;
output reg [7:0] leds;
//Input output declarations.
inout reg [7:0] ft_bus_d;
inout reg [16:0] gpio;
//Variables go here
integer count, count1, state, pixel_n, line_n, t_int;
integer data[8];
reg en;
//Initial values on start up.
initial
begin
//IO initial setup values.
ft_reset = 1; ft_bus_pwrsav = 1; ft_bus_oe = 1; ft_bus_siwu = 0; ft_bus_wr = 1; ft_bus_rd = 1; //NEED TO APPLY REAL VAULES!!!
mtr_config = 1; mtr_m1 = 1; mtr_m0 = 1; mtr_rst = 1; mtr_out_en = 1; mtr_step = 0; mtr_dir = 0;
ccd_driver_oe = 1; ccd_p1 = 0; ccd_p2 = 0; ccd_cp = 0; ccd_rs = 0; ccd_sh = 0;
dac1_sdin = 0; dac1_sclk = 0; dac1_sync = 0; dac2_sdin = 0; dac2_sclk = 0; dac2_sync = 0;
adc_pwrdn = 0; adc_encode = 0;
led_ctrl = 0;
leds = 0;
gpio = 0;
ft_bus_d = 0;
//Variables setup values.
count = 0;
count1 = 0;
state = 0;
pixel_n = 0;
line_n = 0;
t_int = 10000; //t_int = integration time. integration time (seconds) = t_int * 10x10^-9.
end //End initial
//Some other code goes here.
always #(posedge ft_bus_clkout)
begin
if(count == 50000000)
begin
en <= 1;
count = 0;
end
else
begin
en <= 0;
count = count + 1;
end
end //End always
AD5601_module AD5601(.en(en), .clk(clk), .data(127),.sdout(dac1_sdin),
.sclk(dac1_sclk), .sync(dac1_sync));
endmodule //End module.
And the inner module:
module AD5601_module(en, clk, data, sdout, sclk, sync);
input wire clk;
input wire en;
input wire [7:0] data;
output reg sdout, sclk, sync;
integer sclk_count;
integer data_state;
integer delay_counter;
integer pd[2];
initial
begin
sclk_count = 0;
data_state = 99;
delay_counter = 0;
pd[0] = 0;
pd[1] = 0;
sdout = 0;
sclk = 0;
sync = 1;
end
always # (posedge en)
begin
if(data_state == 99)data_state <= 0;
end
always # (posedge clk)
begin
if(sclk_count == 49)
begin
sclk_count = 0;
sclk = ~sclk;
end
else sclk_count = sclk_count + 1;
end
always # (posedge sclk)
begin
case(data_state)
0: begin
sync = 0;
sdout <= pd[1];
data_state <= 1;
end
1: begin
sdout <= pd[0];
data_state <= 2;
end
2: begin
sdout <= data[7];
data_state <= 3;
end
3: begin
sdout <= data[6];
data_state <= 4;
end
4: begin
sdout <= data[5];
data_state <= 5;
end
5: begin
sdout <= data[4];
data_state <= 6;
end
6: begin
sdout <= data[3];
data_state <= 7;
end
7: begin
sdout <= data[2];
data_state <= 8;
end
8: begin
sdout <= data[1];
data_state <= 9;
end
10:begin
sdout <= 0;
if(delay_counter == 6)
begin
data_state <= 99;
delay_counter <= 0;
sync = 1;
end
else delay_counter = delay_counter + 1;
end
endcase
end
endmodule
So with the code as is I get the error
'output or inout port should be connected to a structural net
expression'
.
If I change the outputs in the root module or the inner module to wire I get the error 'the expression on the left hand side should be of a variable type'.
So at this point I have no idea how you nest outputs! Some help would be appreciated!
Thanks
inout ports should be a net type (wire or tri) and not a reg. A reg does not have conflict resolution (when there are two or more active driver). An inout should not be assigned in a procedural block (e.g. always-block, initial-block). It should be a simple assign statement as below. The designer must ensure there is only on active driver on the IO at any point.
assign io_port_name = driver_enable ? io_out_value : 'bz; // io_out_value should be a flop
An output should only be declared an output reg if it is assigned in a procedural block (e.g. always-block, initial-block) within the current module. All other outputs should be output or output wire (these identifiers are synonymous; the former is implicit while the latter is explicit). An should only be assigned within one always. FPGAs allow initial blocks, ASIC/IC does not.
If SystemVerilog is enabled, replace output reg with output logic. logic can be used for flops and single directional nets. logic is not recommended for inout; logic like reg does not have conflict resolution.
The arrays integer data[8]; and integer pd[2]; are SystemVerilog syntax and not compatible with Verilog. Either enable SystemVerilog or change to integer data[0:7]; and integer pd[0:1];
SystemVerilog can be enabled per file by changing the file extension from .v to .sv; recommended. Simulators/synthesizers typically have a switch to force all Verilog to be treated as SystemVerilog; not recommended, refer to the simulator/synthesizer manual if desired to go this route.

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.

Conditional code in Verilog in a generate loop

I am trying to encode conditional behavior for Verilog statements in a generate loop. For example, the code below returns an error.
module <something> (out);
parameter [4:0] someParam = 0;
output [5:0] out;
genvar l, m;
for(l=0; l<5; l=l+1) begin:STAGE_1
m = 0;
if(someParam[l] < 2)
m = l+2;
else begin
m = l-2;
end
if (m>16) assign out[l] = 1'b0;
else assign out[l] = 1'b1;
end
endmodule
The problem is that the variable m is not a constant and the code errors out. Is there any way I can use compile time variable inside a generate statement which would allow some functionality like the variable m above?
Thanks.
I didnt understand what you intended to calculate due to some errors in your code.
In general, for you to use a parameter in a statement you can use an always block with a if statement as following:
module <something> (out);
parameter [4:0] someParam = 0;
output out; // in this case out is only one bit. it can be more of course.
integer l,m; // no need for genver when not using generate
always (*) begin
m = 0;
for (l=0; l<5; l=l+1) begin:STAGE_1
if (someParam[l] == 1'b1) // nothing good comes for checking if a bit is less then 2
m = m+1; // just counting bits in someParam. doing +-2 does not make sense.
end
if (m >= 3)
out = 1'b1;
else
out = 1'b0;
end
The above is a majority function.
Good luck

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

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.