How do I run the verilog code on a testbench? - verilog

I wrote the code for a ripple carry adder. Testbench is also available. How do I run this test bench on my Verilog code? I don't have a simulator. I am using the iverilog compiler.
ripple_carry_adder.v
module half_adder(a,b,sum,carry);
input a,b;
output sum,carry;
assign sum=a^b;
assign carry=a&b;
endmodule
module full_adder(a,b,cin,sum,cout);
input a,b,cin;
output sum,cout;
wire t1,t2;
half_adder h(a,b,t1,t2);
assign cout=t1&cin;
assign sum=t1^cin;
assign cout=t2|cout;
endmodule // full_adder
module ripple_carry_adder(input1,input2,answer);
input [31:0] input1,input2;
output [31:0] answer;
wire [31:0] carry;
full_adder f(input1[0],input2[0],1'b0,answer[0],carry[0]);
genvar i;
generate
for(i=1;i<=31;i=i+1)
begin : my_mabel
full_adder f(input1[i],input2[i],carry[i-1],answer[i],carry[i]);
end
endgenerate
endmodule
testbench
module test;
reg [31:0] input1,input2, expected;
wire [31:0] actual;
integer seed;
ripple_carry_adder dut(input1,input2,actual);
initial begin
seed = 0;
repeat(10) begin
input1 = $random(seed);
input2 = $random(seed);
expected = input1 + input2;
#1;
if(actual!=expected) $display("ERROR: %0d+%0d was %0d expected %0d",
input1,input2,actual, expected);
#9;
end
end
endmodule

Use:
$ iverilog -o ripple ripple_carry_adder.v ripple_carry_adder_tb.v
$ vvp ripple
to compile and run your code in terminal. You might add a $monitor to your testbench to be able to print some more results than just errors.
There is also a companion program called GTKWave that allows you to plot waveforms.

Related

why output of 2nd function call to 4 bit adder is X(don't care)?

I am new to verilog, I was building a 32-bit adder using structural modelling. So I made a 1-bit full adder, then used that to construct a 4-bit adder, and that was used to create an 8- bit adder.
Everything works fine until the 4-bit adder but when I use the 4-bit adder as a function this error pops up.
module adder_1bit(Sum,CarryOut,A,B,CarryIn);
output Sum,CarryOut;
input A,B,CarryIn;
assign Sum = A^B^CarryIn;
assign CarryOut = (A&B) | (B&CarryIn) | (A&CarryIn);
endmodule
module adder_4bit(Sum,CarryOut,A,B,CarryIn);
output [3:0] Sum;
output CarryOut;
input [3:0] A,B;
input CarryIn;
wire w[2:0];
assign CarryIn = 1'b0;
adder_1bit add0(Sum[0],w[0],A[0],B[0],CarryIn);
adder_1bit add1(Sum[1],w[1],A[1],B[1],w[0]);
adder_1bit add2(Sum[2],w[2],A[2],B[2],w[1]);
adder_1bit add3(Sum[3],CarryOut,A[3],B[3],w[2]);
endmodule
module adder_8bit(Sum,CarryOut,A,B,CarryIn);
output [7:0] Sum;
output CarryOut;
input [7:0] A,B;
input CarryIn;
wire w;
assign CarryIn = 1'b0;
adder_4bit add4(Sum[3:0],w,A[3:0],B[3:0],CarryIn);
adder_4bit add5(Sum[7:4],CarryOut,A[7:4],B[7:4],w);
endmodule
When I run with the following testbench code I get MSB 4-bit get as don't care
module adder_test;
reg [7:0] A,B;
reg CarryIn;
wire [7:0] Sum;
wire CarryOut;
adder_8bit UUT (Sum,CarryOut,A,B,CarryIn);
initial
begin
A = 8'b00101011;
B = 8'b01010110;
CarryIn = 1'b0;
#10;
end
endmodule
Simulation Result
Your problem is in this statement: assign CarryIn = 1'b0;
The following happens:
module adder_4bit(Sum,CarryOut,A,B,CarryIn);
...
assign CarryIn = 1'b0;
In this case you have carryIn driven by two drivers:
the input port
the assign statement
Unless the value of the port is the same as your driver (1'b0) the resulting value of carryIn will always be 'x'. This interferes with all your results.
To fix the issue just move this statement to your test bench:
module adder_test;
...
wire CarryOut = 0;

4-bit counter using T-flipflop in verilog

I'm trying to design a 4-bit counter with T-flipflop, here's what i did:
1- From a D-flipflop to T-flipflop:
module T_FlipFlop( clk,T, Q);
input wire clk;
input wire T;
output reg Q;
wire D;
initial
begin
Q<=1'b0;
end
assign D= T ^ Q;
always #(negedge clk)
begin
Q<=D;
end
endmodule
with RTL shematic :
following this "D_ff to T_ff" conversion:
2- Then, i instantiated 4 T-flipflops in the top module and connected the output of each flipflop to the clk of the next one:
module Counters_FreqDividers( sysclk,Q1,Q2,Q3,Q4);
input sysclk;
output wire Q1;
output wire Q2;
output wire Q3;
output wire Q4;
T_FlipFlop num_1(.clk(sysclk),.T(1'b1),.Q(Q1));
T_FlipFlop num_2(.clk(Q1),.T(1'b1),.Q(Q2));
T_FlipFlop num_3(.clk(Q2),.T(1'b1),.Q(Q3));
T_FlipFlop num_4(.clk(Q3),.T(1'b1),.Q(Q4));
endmodule
with RTL schematic :
to follow this diagram:
We know that T-flipflop is just a JK-flipflop with J and K connected to each other and that's what we have here, so consider them as T-flipflops.
3-The simulation:
4- Finally, my questions:
1) why Q1 is the ONLY output that operates properly?
2) Why Q2, Q3, Q4 starts with 1 although i have initialized them as 0?
I can't figure out what's missing, i tried to play around but nothing worked and i'm stuck here!
Edit: my testbench:
module test;
// Inputs
reg sysclk;
// Outputs
wire Q1;
wire Q2;
wire Q3;
wire Q4;
// Instantiate the Unit Under Test (UUT)
Counters_FreqDividers uut (
.sysclk(sysclk),
.Q1(Q1),
.Q2(Q2),
.Q3(Q3),
.Q4(Q4)
);
initial begin
// Initialize Inputs
sysclk <= 1'b1;
#200 $finish();
end
always #5 sysclk=~sysclk;
endmodule

How to use float numbers with quartus megawizard ALTMULT_ACCUM(MAC)?

I am using the below mentioned module and testbench to use MAC megawizard in quartus, can anyone tell me how can I use floating point numbers for the same megawizard?
Testbench
`timescale 1ns/1ps
module projecttry2_tb;
reg [15:0] A, B;
wire [31:0] P;
reg clk;
projecttry2 M(.A(A),.B(B),.P(P),.clk(clk));
initial
begin
clk = 1;
forever #25 clk = ~clk;
end
initial
begin
A=3008;
B=255;
#50
A=5859;
B=255;
#50
A=1133;
B=255;
#50
A=0;
B=0;
end
endmodule
Design Module
module projecttry2(A,B,P,clk);
input [15:0] A,B;
output [31:0] P;
input clk;
mult_acc mult_acc_inst (
.clock0(clk),
.dataa(A),
.datab(B),
.result (P)
);
endmodule
ALTFP_MULT is available and documented on page 40 of Floating-Point Megafunctions.

Four Bit Adder Understanding

Can someone explain to me what I am doing wrong. I don't know if I just don't understand the concept or what. I have looked at two solid examples, both of which provide thorough code but maybe I am wiring things wrong or something.
1st - I have created an file called Adder and below is my code. This works completely fine, I have created/ran a test bench file with this so I know this does exactly what is intended. However, am I supposed to somehow connect my FullAdder file or the test bench for the FullAdder file to the Adder file? Are these completely separate files and are never connected?
module Adder (a,b,ci,co,s);
input a,b,ci;
output co,s;
assign s=a^b^ci;
assign co=(a&b)|(a&ci)|(b&ci);
endmodule
2nd - Below is my code for the FullAdder file. I am not sure if this is correct but let me know where I can make possible changes. I assume the test bench I create will be linked to this FullAdder file? The syntax for this file checks out alright, so maybe it is the test bench that is causing problems for me...
module FullAdder(a,b,ci,s);
input [3:0] a,b;
input ci;
output [3:0] s;
wire [2:0] co; // Is the wire correct here? I created this off something I saw.
Adder ADD1(a[0],b[0],ci,s[0],co[0]);
Adder ADD2(a[1],b[1],co[0],s[1],co[1]);
Adder ADD3(a[2],b[2],co[1],s[2],co[2]);
Adder ADD4(a[3],b[3],co[2],s[3],s[4]);
endmodule
3rd - I don't understand the test bench and wiring everything all together. I have looked at these two links which have two different ways of doing this.
Link 1 Link 2. I have tried to replicate link 2, but can't seem to get it working. Help?
Adder ADD4(a[3],b[3],carry[2],s[3],s[4]);
This instantiation assumes that s is a vector with an element in position 4, but your definition of s is [3:0] so 4 is not a valid position. Change it to
output [4:0] s;
It's desiderabel to use the Verilog 2001 module definition style (resembles ANSI C). Your module would be like this:
module FullAdder (
input wire [3:0] a,
input wire [3:0] b,
input wire ci,
output wire [4:0] s
);
wire [2:0] co;
Adder ADD1(a[0],b[0],ci,s[0],co[0]);
Adder ADD2(a[1],b[1],co[0],s[1],co[1]);
Adder ADD3(a[2],b[2],co[1],s[2],co[2]);
Adder ADD4(a[3],b[3],co[2],s[3],s[4]);
endmodule
Regarding your test bench (link 2) you mispelled some names: the name of 1-bit address is called "adder", not "Adder". Change either the definition or the instance name. The name of the ports are a,b,cin and s, not p,q,ci and r. These last are the signals (wires) you will connect to your ports.
As this adder has a limited set of inputs, I'd suggest to do an exhaustive test bench. So instead of probing two sample values for a,b and cin, try all the posibilities, and check that the result is the expected one. Something like this:
// Code your testbench here
module test_bench;
// Inputs
reg [3:0] p;
reg [3:0] q;
reg ci;
// Outputs
wire [4:0] r;
// Instantiate the Unit Under Test (UUT)
FullAdder uut (
.a(p),
.b(q),
.ci(ci),
.s(r)
);
initial begin
ci = 1'b0;
repeat (2) begin
p = 4'b0000;
repeat (16) begin
q = 4'b0000;
repeat (16) begin
#10;
$display ("%b + %b + %b = %b", p, q, ci, r);
if (r != (p+q+ci)) begin
$display ("ERROR!. Expected %b", p+q+ci);
$finish;
end
#10;
q = q + 1;
end
#10;
p = p + 1;
end
#10;
ci = !ci;
end
$display ("EVERYTHING OK!");
$finish;
end
endmodule
See http://www.edaplayground.com/x/HR5

Why is it giving error in module part1?

In my previous question I said that I was asked to design a bottling system that fills bottles with the desired number of tablets. In part1 of my project, the user will press the button on FPGA to identify how many tablets will be put in the each bottle and the desired number will be displayed.This is the code of part 1 I have written for my project and I have no idea why it is giving errors in module part1.
module count(clk,clr,cntEn,dout);
input clk,clr,cntEn;
output reg [8:0] dout ;
always#(posedge clk)
begin
if(clr)
dout<=0;
else if(cntEn)
dout<=dout+1;
end
endmodule
module sevenseg(num,dout);
input [3:0] num;
output reg [6:0] dout;
always#(*) begin
case(num)
0:dout=7'b1111110;
1:dout=7'b1100000;
2:dout=7'b1011011;
3:dout=7'b1001111;
4:dout=7'b1100110;
5:dout=7'b1101101;
6:dout=7'b1111101;
7:dout=7'b0000111;
8:dout=7'b1111111;
9:dout=7'b1101111;
endcase
end
endmodule
module part1(clk,clr,cntEn,dout);
input clk, clr, cntEn;
output dout;
wire w1;
begin
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
end
endmodule
The error was pointed out byljk07, the begin end in module 1 are not required, some parsers might just ignore them others will throw an error. it should be:
module part1(clk,clr,cntEn,dout);
input clk, clr, cntEn;
output dout;
wire w1;
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
endmodule
I think it is also worth pointing out that unless your constrained to Verilog-95 then adopting an ANSI style port declaration is preferred, as it lead to easier to maintain code.
module part1(
input clk, clr, cntEn,
output dout
);
wire w1;
count count_1 (clk, clr, cntEn, w1);
sevenseg sevenseg_1(w1, dout );
endmodule
Module sevenseg also has an incomplete case statement which will lead to implied latches. either add a default or fully specify the output for all options of num:
module sevenseg(num,dout);
input [3:0] num;
output reg [6:0] dout;
always #(*) begin
case(num)
0:dout=7'b1111110;
1:dout=7'b1100000;
2:dout=7'b1011011;
3:dout=7'b1001111;
4:dout=7'b1100110;
5:dout=7'b1101101;
6:dout=7'b1111101;
7:dout=7'b0000111;
8:dout=7'b1111111;
9:dout=7'b1101111;
default: dout='b0;
endcase
end
endmodule

Resources