Can anyone help me to create a Verilog testbench? - input

Can anyone help me create a testbench or just the input code for my following code? I'm using XILINX.
module fsmb (input rst,clk,a,
output reg x);
parameter sta = 2'b00, stb = 2'b01, stc = 2'b10,
std = 2'b11;
reg[1:0] st, nst;
always #(posedge clk)
begin
if (rst)
st <= 2'b00;
else
st <= nst;
end
always #*
begin
st = nst; x =0'b0;
case (st)
sta: if(a) nst = stb;
else nst = sta;
stb: if(a) nst = stc;
else nst = stb;
stc: begin
if(a) nst = stc;
else nst = std;
x =1'b1;
end
std: begin
if(a) nst = stc;
else nst = sta;
x = 1'b1;
end
default: nst = sta;
endcase
end
endmodule

Testbench 101
Create a new module (tb).
Create a reg for each input of your DUT.
Create a wire for each output of your DUT.
Create an instance of your DUT.
Connect your regs and wires to your DUT.
Generate a clock
Drive your other inputs
Create checkers for your outputs (I'll leave this up to you).
Example:
module tb;
reg rst,clk,a;
wire x;
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
rst = 1;
a = 0;
#50 rst = 0;
#50 $finish;
end
fsmb fsmb (
.clk (clk),
.rst (rst),
.a (a),
.x (x)
);
endmodule
Other simple testbench examples are provided on EDA playgound. You can sign up for a free account and look at samples such as: Published Playgounds -> D flip flop

Xilinx ISE will generate a skeleton test fixture automatically. Go to menu item Project->New Source. The dialog box will ask you to "Select Source Type" click "Verilog Test Fixture" and give it a name like testbench1 and click Next. Then it will then ask you which module in your project to associate with it. Select fsmb. Click Next and Finish.
You still have to tweak the testbench like setting the initial input values, generating a clock, and lifting reset after a few clocks.

Related

Unexpected high impedance state

I've encountered a problem of unexpected high impedance state on output ports of my modules. Code of the module that instantiates other modules is following:
`timescale 1ns/1ps
module column(
input wire clk,
input wire reset,
input wire trigger,
input wire [7:0] latency
);
localparam AMOUNT_OF_REGIONS = 3;
wire [24:0] o_data [0:AMOUNT_OF_REGIONS-1];
wire [1:0] up_in [0:AMOUNT_OF_REGIONS-1];
//same declarations for do_in, up_out, do_out
assign up_in[0] = 0;
assign do_in[AMOUNT_OF_REGIONS-1] = 0;
generate
genvar i;
for (i = 0; i < AMOUNT_OF_REGIONS; i = i + 1) begin : multiple_regions_instantiation
if ((i == 0) || (i == AMOUNT_OF_REGIONS-1)) begin
region tmp(
clk,
reset,
trigger,
latency,
up_in[i],
do_in[i],
up_out[i],
do_out[i],
o_data[i]
);
end
else begin
region tmp(
clk,
reset,
trigger,
latency,
do_out[i-1],
up_out[i+1],
do_in[i-1],
up_in[i+1],
o_data[i]
);
end
end
endgenerate
endmodule
Port declaration of instantiatable modules is like this:
module region(
input wire clk,
input wire reset,
input wire trigger,
input wire [7:0] latency,
input wire [1:0] up,
input wire [1:0] do,
output reg [1:0] to_up,
output reg [1:0] to_do,
output reg [24:0] odata
);
Assignment of an output is made in initial block and looks like this:
initial begin
latency_cnt = 255;
start_cnt = 0;
preset = 0;
read_out = 0;
begin: hit_generation
cnt = 0;
forever begin
cnt = cnt + 1;
fork
#20 hit0 = ($random > 0) ? 1 : 0;
#20 hit1 = ($random > 0) ? 1 : 0;
#20 hit2 = ($random > 0) ? 1 : 0;
#20 hit3 = ($random > 0) ? 1 : 0;
to_up = {hit1, hit0};
to_do = {hit3, hit2};
join
if (cnt == 10000) disable hit_generation;
end
end
end
So, now the problem is, if it AMOUNT_OF_REGIONS == 3 or 2 then everything works fine, but if i'm trying to increase its value then for all the regions that are between 1 and AMOUNT_OF_REGIONS-2 (including), their inputs and outputs are messed up (2'bzz). But 0 region sends info to region 1 pretty well, and AMOUNT_OF_REGIONS-1 region sends the info properly to it's neighbor.
Test bench is just instantiating a column and generates a trigger and clk signals. I've read that if there are only wires connections without attachment to the registers that can cause high impedance state, but as far as i can see, i'm connecting wires to the output registers...Dear all, what could be a problem of it? I'm using Icarus Verilog, if it matters.
Accidentally, i've found the root of my problem. I will leave an answer, may be it will help some day to somebody who will be stuck in situation like this.
I made the wrong port assignment, so, i guess, they was cycled or something like that. The problem was that here:
region tmp(
clk,
reset,
trigger,
latency,
do_out[i-1],
up_out[i+1],
do_in[i-1],
up_in[i+1],
o_data[i]
);
I assigned input ports of module to output of another and it was the mistake...
So the proper way of assigning ports in such situation is like this (full code of instantiation cycle):
generate
genvar i;
for (i = 0; i < AMOUNT_OF_REGIONS; i = i + 1) begin : multiple_regions_instantiation
if (i == 0) begin
region tmp(
clk,
reset,
trigger,
latency,
up_in[i],
do_in[i],
up_out[i],
up_in[i+1], //CHANGED
o_data[i]
);
end
else if (i == AMOUNT_OF_REGIONS-1) begin
region tmp(
clk,
reset,
trigger,
latency,
up_in[i],
do_in[i],
do_in[i-1], //CHANGED
do_out[i],
o_data[i]
);
end
else begin
region tmp(
clk,
reset,
trigger,
latency,
up_in[i], //CHANGED
do_in[i], //CHANGED
do_in[i-1],
up_in[i+1],
o_data[i]
);
end
end
endgenerate
Hope it will help somebody!

Error (10170): expecting "<=", or "=", or "+=", or "-=", or "*=", or "/=", or "%=", or "&=", or "|=", or "^=", etc

module accumulator (
input [7:0] A ,
input reset,
input clk,
output reg carryout,
output reg overflow,
output reg [8:0] S,
output reg HEX0,
output reg HEX1,
output reg HEX2,
output reg HEX3
);
reg signA;
reg signS;
reg [7:0] magA;
reg [7:0] magS;
reg Alarger;
initial begin
S = 9'b000000000;
end
always_ff # (posedge clk, posedge reset) begin
if (reset) begin
S = 9'b000000000;
end
else begin
begin
signA <= A[7]; //Is A negative or positive
signS <= S[7];
S <= A + S;
end
if (signA == 1) begin //A is negative so magnitude is of 2s compliment
magA <= (~A[7:0] + 1'b1);
end
else begin
magA <= A;
end
if (signS == 1) begin //sum is negative so magnitude is of 2s compliment
magS <= (~S[7:0] + 1'b1);
end
else begin
magS <= S;
end
if (magA > magS) begin
Alarger <= 1'b1; //Magnitude of A is larger than magnitude of sum
end
else begin
Alarger <= 1'b0;
end
if ((signA == 1) & (Alarger == 1) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 1) & (Alarger == 0) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 1) & (signA == 1) & (S[7] == 0)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if ((signS == 0) & (signA == 0) & (S[7] == 1)) begin
overflow <= 1'b1;
end
else begin
overflow <= 1'b0;
end
if (S[8] == 1) begin //carryout occurred
carryout <= 1'b1;
overflow <= 1'b0;
S <= 9'b000000000; //sum no longer valid
end
else begin
carryout <= 1'b0;
end
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
end
end
endmodule
I am trying to make an accumulator that adds A (8 digit binary value that can be signed or unsigned) repeatedly to the sum. Once the sum is computed, then sum and A should display the value on 4 hex display LEDs (2 LEDs for A and 2 LEDs for sum). However, I am having a hard time getting it to compile. I have searched the error code and it seems like a general error for a syntax error and can have several meanings.
The error is the result of these two lines:
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
Here, it appears you have a module named display_hex which converts an 8-bit value into the needed digits for a seven segment display. You are trying to use the module as if it were a function and modules are very much NOT functions. Modules in Verilog (or SystemVerilog as you are using, but the difference is really token at this point) can be though of as a group of hardware that takes in some inputs and spits out some outputs; and its important to note that they are static things. They either exist in the design or they do not; just like using ICs on a breadboard. The top module is the breadboard and the modules you declare under that module are components you are plugging into the board. The inputs and outputs are the various connections (pins) you must wire up to make everything work.
That said, always blocks (like the always_ff you are using) form a way of describing the logic and registers inside modules. Thus, you do thinks like assign logic/reg variables inside them to describe how the hardware behaves. If you look at your logic, you'll notice that the module declarations are dependent on reset; ie if reset is asserted, these modules wont exist, which doesnt make any sense. Electrical signals don't make entire ICs in a circuit disappear! Thus, you need to pull your module declaration out of your logical description of your acculumator, like so:
module accumulator (
...
);
...
display_hex h1 //display of A
(
.bin (magA),
.hexl (HEX2),
.hexh (HEX3)
);
display_hex h2 //display of sum
(
.bin (S[7:0]),
.hexl (HEX0),
.hexh (HEX1)
);
...
always_ff #(posedge clk, posedge reset) begin
// Your accumulator logic here
...
end
endmodule
Notice that the module declarations for the display_hex modules are stand alone, as I am declaring these modules exist, not dependence on anything!
However, there are a number of issues with your design besides that:
As you are using SystemVerilog constructs (always_ff), you should declare all of your variables type logic, not reg or left blank (ie, input clk should be input logic clk, reg signA should be logic signA). The logic type just makes everything easier, so use it :)
In your always_ff block, you do reset correctly except that the assignment should really be NBA (use S <= 9'b0;, not S = 9'b0; in the if (reset))
You use NBA inside your always_ff, which is correct, however, it appears you need to use these values right away in the following logic. This will not work as you expect, or at least it will not act within the same clock cycle. To fix this, youll need to decide what should be a register and what should just be values resulting from intermediate logic, then create a separate always_comb for the intermediate values.
I am making the assumption that the HEX variables are meant for seven segment displays, so they should probably declared at least [6:0] HEXn
I was not able to reproduce the exact error, but moving the instantiations of display_hex outside always_ff resolves the main issue:
module accumulator
(
/* ... */
);
// ...
always_ff # (posedge clk, posedge reset) begin
/* ... */
end
display_hex h1 (
/* ... */
);
display_hex h2 (
/* ... */
);
endmodule
Another thing: The code drives variable S from initial as well as always. This creates multiple drivers and the code will not compile. To fix this, remove the initial completely, you don't need it since S will be set to 0 when reset is asserted.
OR
You can move all the logic into the initial block; it'd look something like this (but this, most probably, won't synthesize):
initial begin
S = 0;
forever begin
wait #(posedge clock);
// Do stuff here ..
end
end

Strange delay of one cycle in modules in verilog

i'm beginner in verilog and digital circuits, and i have one doubt in the code below. In this code i made a state machine that saves values in a "reg" into another module in verilog. I made this code just to explain my doubt:
//STATE MACHINE
module RegTest(clk,enable,reset, readData1_out);
parameter State1 = 0;
parameter State2 = 1;
parameter State3 = 2;
parameter State4 = 3;
parameter State5 = 4;
parameter State6 = 5;
parameter State7 = 6;
parameter State8 = 7;
parameter State9 = 8;
parameter State10 = 9;
parameter Beg = 10;
input clk, enable, reset;
output readData1_out;
wire clk,enable, reset;
reg[5:0] State;
reg writeEn ;
reg [15:0] writeData;
wire [15:0] readData1;
wire writeEn_out = writeEn;
RegFile registrador_component (
.dataIn(writeData),
.dataOut(readData1),
.clock(clk),
.writeEnable(writeEn)
);
defparam
registrador_component.WIDTH = 16;
always #(posedge clk or posedge reset) begin
if (reset)
begin
State = Beg;
end else begin
case (State)
Beg:
begin
State = State1;
end
State1:
begin
writeEn = 1 ;
writeData = 10;
State = State2;
end
State2:
begin
writeEn = 0 ;
State = State3;
end
State3:
begin
writeEn = 1;
writeData = readData1 + 10;
State = State4;
end
State4:
begin
writeEn = 0 ;
State = State5;
end
State5:
begin
writeEn = 1 ;
writeData = readData1 + 10;
State = State6;
end
State6:
begin
writeEn = 0 ;
State = State7;
end
State7:
begin
writeEn = 1 ;
writeData = readData1 + 10;
State = State8;
end
State8:
begin
writeEn = 0 ;
State = State9;
end
endcase
end
end
endmodule
//Example of a register file
module RegFile(clock, writeEnable, dataIn, dataOut);
parameter WIDTH = 16;
input clock, writeEnable;
input [WIDTH-1 : 0] dataIn;
output [WIDTH-1 : 0] dataOut;
wire [WIDTH-1 : 0] dataOut;
reg [WIDTH-1 : 0] wha;
assign dataOut = wha;
always#( posedge clock)
begin
if (writeEnable)
wha = dataIn;
end
endmodule
My doubt is, why do I need to wait 1 cycle to get the value that is stored in RegFile?
Why can't I skip the State2 for example?
You do in fact have 2 clock cycles of delay in the code you wrote above. It would help if you simulated this so you can see it for yourself, but I'll describe it.
On the first cycle, WriteEnable goes high. It takes 1 full clock cycle to be valid to other parts of the logic. So after the first clock cycle is done, WriteEnable will be available for use elsewhere.
On the second cycle, your regFile module can "see" the fact that WriteEnable went high previously. It then will put dataIn into wha signal, which gets passed to dataOut. So after the second clock cycle is done, dataOut will be available for use elsewhere. (It gets used on the third clock cycle in State 3).
This is why you need to go to state 2. State 2 allows for the 1 extra clock cycle needed for RegFile to register the output data.
Clock cycle delay is an extremely important concept to understand, so it's good that you're putting in the time when you are still new to fully grasp it.
For more information see this tutorial here, it explains registers and clock cycle delay and will be useful for you.
Clock Cycle Delays and Registered Logic

Data is not picked up from instantiated outputs

I have instantiated a stopwatch module into this multiplexer module. The stopwatch is working as it is supposed to and is producing the expected output. This is also picked up by the instantiated registers. But, if I want to use this data further down the module, it does not work.
Here is the simulation showing my problem:
The values picked up from the stopwatch module are working perfectly. These values are then transferred to the registers regd0, regd1, regd2, regd3 which, instead of displaying the values are displaying 0?
Here is the code that produced the above simulation:
module muxer(
input clock,
input reset,
input [1:0] select,
output a,
output b,
output c,
output d,
output e,
output f,
output g,
output dp,
output [3:0] an
);
reg go_hi, go_start;
wire[3:0] wire_d0, wire_d1, wire_d2, wire_d3; // timer registers that will hold the individual counts
wire[3:0] wire_hd0, wire_hd1, wire_hd2, wire_hd3; //regsiters to hold the "hi" values
reg [3:0] regd0, regd1, regd2, regd3; //registers for LED multiplexing
//instantiate the "hi" module
say_hi sayhi(.clock(clock), .reset(reset), .go(go_hi), .hi_d0(wire_hd0), .hi_d1(wire_hd1), .hi_d2(wire_hd2), .hi_d3(wire_hd3)) ;
//instantiate the stopwatch module
stopwatch timer(.clock(clock), .reset(reset), .start(go_start), .d0(wire_d0), .d1(wire_d1), .d2(wire_d2), .d3(wire_d3) );
always # (select)
begin
case(select)
00: //hi
begin
go_start = 0; //make sure timer module is off
go_hi = 1'b1; //enable go signal to display "hi"
regd0 = wire_hd0; //transfer values to the multiplexing circuit
regd1 = wire_hd1;
regd2 = wire_hd2;
regd3 = wire_hd3;
end
01: //timer
begin
go_hi = 0; //make sure "hi" module is off
go_start = 1'b1; //enable start signal to start timer
regd0 = wire_d0;
regd1 = wire_d1;
regd2 = wire_d2;
regd3 = wire_d3;
end
10: //stop timer
begin
go_hi = 0;
go_start = 1'b0;
end
endcase
end
//The Circuit for 7 Segment Multiplexing -
localparam N = 8; //18 for implementation, 8 for simulation
reg [N-1:0]count;
always # (posedge clock or posedge reset)
begin
if (reset)
count <= 0;
else
count <= count + 1;
end
reg [6:0]sseg;
reg [3:0]an_temp;
reg reg_dp;
always # (*)
begin
case(count[N-1:N-2])
2'b00 :
begin
sseg = regd0;
an_temp = 4'b1110;
reg_dp = 1'b1;
end
2'b01:
begin
sseg = regd1;
an_temp = 4'b1101;
reg_dp = 1'b0;
end
2'b10:
begin
sseg = regd2;
an_temp = 4'b1011;
reg_dp = 1'b1;
end
2'b11:
begin
sseg = regd3;
an_temp = 4'b0111;
reg_dp = 1'b0;
end
endcase
end
assign an = an_temp;
reg [6:0] sseg_temp;
always # (*)
begin
case(sseg)
4'd0 : sseg_temp = 7'b1000000; //display 0
4'd1 : sseg_temp = 7'b1111001; //display 1
4'd2 : sseg_temp = 7'b0100100;// display 2
4'd3 : sseg_temp = 7'b0110000;
4'd4 : sseg_temp = 7'b0011001;
4'd5 : sseg_temp = 7'b0010010;
4'd6 : sseg_temp = 7'b0000010;
4'd7 : sseg_temp = 7'b1111000;
4'd8 : sseg_temp = 7'b0000000;
4'd9 : sseg_temp = 7'b0010000;
4'd10 : sseg_temp = 7'b0001001; //to display H
4'd11 : sseg_temp = 7'b0000111; //to display I
default : sseg_temp = 7'b0111111; //dash
endcase
end
assign {g, f, e, d, c, b, a} = sseg_temp;
assign dp = reg_dp;
endmodule
My guess is that select does not equal 01. You should show that in waves as well.
Here are a couple of other observations.
If you want regd0 to model combinational logic, you should change always #(select) to always #*. Same for d1-d3. Currently, I think you are modeling latches.
In your case statement 10 refers to decimal 10. You probably wanted 2'b10.

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.