Unresolved reference to 'fulladder' in Verilog - verilog

I am having some issues when attempting to run a simulation. It seems there is an issue with my instances of my first 2 modules inside of my 3rd module. The code is compiling okay, but I am running into trouble when I try to run a simulation.
I am not really sure if the problem is in my code or my test bench.
module fulladder
(
input [15:0] x,
input [15:0] y,
output [15:0] O
);
assign O = y + x;
endmodule
module shifter
(
input [15:0] in,
input [2:0] N,
output [15:0] O
);
reg [7:0] out_reg;
assign O = out_reg;
always #(N or in) begin
case (N)
7 : out_reg <= { in[7:0],7'b0};
6 : out_reg <= { in[7:0],6'b0};
5 : out_reg <= { in[7:0],5'b0};
4 : out_reg <= { in[7:0],4'b0};
3 : out_reg <= { in[7:0],3'b0};
2 : out_reg <= { in[7:0],2'b0};
1 : out_reg <= { in[7:0],1'b0};
0 : out_reg <= in[7:0];
endcase
end
endmodule
module my_multiplier(Rst, Ld, clk, A, B, O);
input clk;
input [7:0]A, B;
input Rst, Ld;
output [15:0] O;
reg Done;
reg [15:0] Otemp;
reg [15:0] O;
reg [7:0] Atemp;
reg [1:0] state;
reg [1:0] C;
parameter S0 = 2'b00, S1 = 2'b01, S2 = 2'b10, S3 = 2'b11;
always #(posedge clk or posedge Rst)
begin
case(state)
S0: begin
Done <= 0;
if (Ld == 1)
begin
C <= 0;
Atemp <= A;
state <= S1;
end
else
state <= S0;
end
S1: if (B[C] == 1)
begin
shifter ( A, C, Atemp);
O <= Otemp;
C <= C + 1;
state <= S2;
end
else
begin
Atemp <= 0;
O <= Otemp;
C <= C + 1;
state <= S2;
end
S2: begin
O <= Otemp;
if (C == 3)
state <= S3;
else
state <= S2;
end
S3: begin
Done <= 1;
state <= S0;
end
default
state <= S0;
endcase
fulladder (Atemp, O, Otemp);
end
endmodule
module my_multiplier_tb;
reg clk_tb;
reg [7:0]A_tb, B_tb;
reg Rst_tb, Ld_tb;
wire [15:0] O_tb;
my_multiplier dut( Rst_tb, Ld_tb, clk_tb, A_tb, B_tb, O_tb );
always #5 clk_tb = ~clk_tb;
initial begin
A_tb = 8'd8;
B_tb = 8'd7;
#15 Ld_tb = 1; // set Load to begin multiplication
#10 Ld_tb = 0; // wait 1 clock cycle
#300
$monitor($time, "\t A=%d,\t B=%d,\t O=%d", A_tb, B_tb, O_tb);
$finish;
end
endmodule

The problem is in the my_multiplier module where you have multiple syntax errors. If you sign up for a free account on edaplayground and post your code there, you may see more helpful compile errors there.
You must not place a module instance inside an always block. These 2 lines must be moved outside the always:
fulladder (Atemp, O, Otemp);
shifter ( A, C, Atemp);
Once you do that, you need to add instance names, like i0 and i1 below:
fulladder i0 (Atemp, O, Otemp);
shifter i1 ( A, C, Atemp);

Related

Vivado Behavioral Simulations showing undefined (XX) output

I'm attempting to run a behavioral simulation on my Verilog code in Vivado. However, after the simulation runs, instead of getting outputs, they are shown as red lines with XX, which I believe means they are undefined.
I've attempted to change the timescale at the top of the Verilog files, as shown in Xilinx forum post, but this did not fix my issue.
Here is my Verilog program:
module ctrl(
input clk,
input [5:0] A,
input [5:0] B,
input [3:0] C,
output reg [6:0] led
);
always #(posedge clk)
begin
case(C)
4'b0000:
//A + B
led <= A + B;
4'b0001:
//A - B
led <= A - B;
4'b0010:
//A++
led <= A + 1'b1;
4'b0011:
//A--
led <= A - 1'b1;
4'b0100:
//B++
led <= B + 1'b1;
4'b0101:
//B--
led <= B - 1'b1;
4'b0110:
//A & B
led = (A & B);
4'b0111:
//A | B
led = (A | B);
4'b1000:
//A ^ B
led = (A ^ B);
4'b1001:
//~A
led = {1'b0,~A[5:0]
4'b1010:
//~B
led = {1'b0,~B[5:0]};
4'b1011:
//A << B
led = A << B;
4'b1100:
//B << A
led = B << A;
4'b1101:
//Light LED[0] if A > B
if(A > B)
led = 7'b0000001;
else
led = 7'b0000000;
4'b1110:
//Light LED[0] if A < B
if(A < B)
led = 7'b00000001;
else
led = 7'b0000000;
4'b1111:
//Light LED[0] if A=B
if(A == B)
led = 7'b0000001;
else
led = 7'b0000000;
default:
//Unimplemented opcode
led <= 7'b1111111;
endcase
end
endmodule
The testbench
module ctrl_testbench();
reg[5:0] A;
reg[5:0] B;
reg[3:0] C;
wire[6:0] led;
ctrl dut (
.A(A),
.B(B),
.C(C),
.led(led)
);
initial begin
A = 6'b000001;
B = 6'b000001;
C = 4'b0000;
#100;
A = 6'b000000;
B = 6'b000000;
C = 4'b0000;
#100;
A = 6'b000010;
B = 6'b000010;
C = 4'b0001;
end
endmodule
The timing diagram then gives this after the behavioral simulation is run. As you can see A-C (The inputs) are populated correctly, however LED (the output) is red and shows XX.
I'm trying to show the actual outputs.
You need to create a clock signal and drive the clk input of your DUT:
module ctrl_testbench();
reg[5:0] A;
reg[5:0] B;
reg[3:0] C;
wire[6:0] led;
reg clk;
initial begin
clk = 0;
forever #5 clk = ~clk;
end
ctrl dut (
.clk(clk),
.A(A),
.B(B),
.C(C),
.led(led)
);
initial begin
A = 6'b000001;
B = 6'b000001;
C = 4'b0000;
#100;
A = 6'b000000;
B = 6'b000000;
C = 4'b0000;
#100;
A = 6'b000010;
B = 6'b000010;
C = 4'b0001;
$finish;
end
endmodule
It was convenient for me to create 2 initial blocks. The first never ends due to forever, and the second is necessary to end the simulation with $finish. It is common to separate out distinct functionality using multiple initial blocks.

How to change the code. verilog testbench code

I make a design for an adder but the result is wrong.
module FMUL(CLK, St, F1, E1, F2, E2, F, V, done);
input CLK;
input St;
input [3:0] F1;
input [3:0] E1;
input [3:0] F2;
input [3:0] E2;
output[6:0] F;
output V;
output done;
reg[6:0] F;
reg done;
reg V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
initial
begin
State = 0;
PS1 = 0;
NS1 = 0;
Nextstate=0;
end
always #(PS1 or St or Mdone or X or A or B)
begin : main_control
Load = 1'b0;
Adx = 1'b0;
NS1 = 0;
SM8 = 1'b0;
RSF = 1'b0;
LSF = 1'b0;
V = 1'b0;
F = 7'b0000000;
done = 1'b0;
case (PS1)
0 :
begin
F = 7'b0000000;
done = 1'b0;
V = 1'b0;
if(St == 1'b1)
begin
Load = 1'b1;
NS1 = 1;
end
end
1 :
begin
Adx = 1'b1;
NS1 = 2;
end
2 :
begin
if(Mdone == 1'b1)
begin
if(A==0)
begin
SM8 = 1'b1;
end
else if(A == 4 & B == 0)
begin
RSF = 1'b1;
end
else if (A[2] == A[1])
begin
LSF = 1'b1;
end
NS1 = 3;
end
else
begin
NS1 = 2;
end
end
3 : begin
if(X[4] != X[3])
begin
V = 1'b1;
end
else
begin
V = 1'b0;
end
done = 1'b1;
F = {A[2:0],B};
if(St==1'b0)
begin
NS1 = 0;
end
end
endcase
end
always #(State or Adx or B)
begin : mul2c
AdSh = 1'b0;
Sh = 1'b0;
Cm = 1'b0;
Mdone = 1'b0;
Nextstate = 0;
case(State)
0 :
begin
if(Adx==1'b1)
begin
if((B[0]) == 1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 1;
end
end
1,2 :
begin
if((B[0])==1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = State + 1;
end
3:
begin
if((B[0])==1'b1)
begin
Cm = 1'b1;
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 4;
end
4:
begin
Mdone = 1'b1;
Nextstate = 0;
end
endcase
end
wire [3:0] addout;
assign addout = (Cm == 1'b0)? (A+C) : (A-C);
always #(posedge CLK)
begin : update
PS1 <= NS1;
State <= Nextstate;
if(Load == 1'b1)
begin
X <= {E1[3], E1};
Y <= {E2[3], E2};
A <= 4'b0000;
B <= F1;
C <= F2;
end
if(Adx == 1'b1)
begin
X <= X+Y;
end
if(SM8 == 1'b1)
begin
X <= 5'b11000;
end
if(RSF == 1'b1)
begin
A <= {1'b0, A[3:1]};
B <= {A[0], B[3:1]};
X <= X+1;
end
if(LSF == 1'b1)
begin
A <= {A[2:0], B[3]};
B <= {B[2:0], 1'b0};
X <= X+31;
end
if(AdSh == 1'b1)
begin
A <= {(C[3]^Cm), addout[3:1]};
B <= {addout[0], B[3:1]};
end
if(Sh == 1'b1)
begin
A <= {A[3], A[3:1]};
B <= {A[0], B[3:1]};
end
end
endmodule
test bench.
module tb_FMUL();
wire[6:0] F;
wire done;
wire V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
reg CLK;
reg St;
reg [3:0] F1;
reg [3:0] E1;
reg [3:0] F2;
reg [3:0] E2;
FMUL u0(CLK, St, F1, E1, F2, E2, F, V, done);
always
begin
#10 CLK <= ~CLK;
end
initial
begin
#100 F1 = 2.125;
E1 = 5; F2 = 5.1; E2 = 1; St=0;
#100 F1 = 1.125;
E1 = 5; F2 = 2.1; E2 = 2; St=0;
#100 F1 = 5.125;
E1 = 5; F2 = 3.1; E2 = 3; St=0;
end
endmodule
The simulation results waveform.
enter image description here
I refer to the book.There is no code test bench.
So I made. But did't operate.
also CLK not is not changed.
please review the testbench code.
You have (at least) two problems:
Your clock needs to be initialised (eg to 1'b0):
initial CLK = 1'b0;
The initial value of any wire or reg in Verilog is 1'bx; ~1'bx is 1'bx; so CLK remains at 1'bx.
Your simulation doesn't stop. I added a call to $finish in the main initial block.
https://www.edaplayground.com/x/r4U

How to execute task concurrently with other statements in an always block?

I am writing code for 8*4 RAM in Verilog. For each binary cell of memory, I am using an SR flip-flop. Initially, each cell is assigned 1'bx. The logic seems to be correct, but the output isn't. It is probably because statements are not getting executed concurrently. Can anyone suggest how can I get the task SRFlipFlop to get executed concurrently with other statements?
module memory(addr, read_data, rw, write_data, clk);
// read_data is the data read
// rw specifies read or write operation. 1 for read and 0 for write
// write data is the data to be written
// addr is the address to be written or read
task SRFlipFlop;
input d,r,s,clk; // d is the value initially stored
output q;
begin
case({s,r})
{1'b0,1'b0}: q<=d;
{1'b0,1'b1}: q<=1'b0;
{1'b1,1'b0}: q<=1'b1;
{1'b1,1'b1}: q<=1'bx;
endcase
end
endtask
task decoder; // a 3 to 8 line decoder
input [2:0] A;
input E;
output [7:0] D;
if (!E)
D <= 16'b0000000000000000;
else
begin
case (A)
3'b000 : D <= 8'b00000001;
3'b001 : D <= 8'b00000010;
3'b010 : D <= 8'b00000100;
3'b011 : D <= 8'b00001000;
3'b100 : D <= 8'b00010000;
3'b101 : D <= 8'b00100000;
3'b110 : D <= 8'b01000000;
3'b111 : D <= 8'b10000000;
endcase
end
endtask
output reg [3:0] read_data;
input [3:0] write_data;
input [2:0] addr;
input rw, clk;
reg [3:0] memory [7:0];
reg [3:0] r [7:0];
reg [3:0] s [7:0];
reg [3:0] intermediate;
reg [3:0] select [7:0];
reg [7:0] out;
reg [7:0] out1;
integer i,j,k,l;
initial
begin
for (i = 0; i <= 7; i=i+1)
begin
for (j = 0; j <= 3; j=j+1)
begin
memory[i][j] = 1'bx;
r[i][j] = 1'b0;
s[i][j] = 1'b0;
select[i][j] = 1'b0;
end
end
end
always #(posedge clk)
begin
decoder(addr, 1'b1, out);
for (i = 0; i <= 7; i=i+1)
begin
if (out[i] == 1'b1)
begin
for (j = 0; j <= 3; j=j+1)
begin
select[i][j] <= 1'b1;
s[i][j] <= write_data[j] & !rw & select[i][j];
r[i][j] <= !write_data[j] & !rw & select[i][j];
SRFlipFlop(memory[i][j],r[i][j],s[i][j],clk,intermediate);
memory[i][j] <= intermediate;
read_data[j] <= memory[i][j];
end
end
end
end
endmodule
Your code style is very software-oriented. Personally I like to know how my code will look as a circuit, so instead of using nested for loops and tasks I will use modules and generate-loops to create my circuits.
I have not been able to make your code work, but I suspect that the error is in the fact that s and r are not reset to zero on every iteration.
I have created a functioning design here:
http://www.edaplayground.com/x/Guc
Instead of using the initial block to initialize values I have added an asynchronous reset.
The SRFF-task has been converted to a module. A RAMblock module instantiates four SRFF-modules. 8 RAMblocks are instantiated in the memory module.
I have converted your packed(reg [] a []) arrays into unpacked arrays(reg [][] a) to be able to perform bitwise operations on several bits without for-loops.
If you have questions about the code, feel free to message me.
Edit: Perhaps the most important thing to note in this design is that I separate the sequential circuitry from the combinatorial. This way it is much easier to control what should be updated on the posedge of clk and what should just be a combinatorial reaction to the changes performed at the posedge.

wrong output value in 8 bit alu

I want to write an eight bit ALU. I have written this code but when I simulate it, the output has x value,why did it happen? and I have another problem that I do not know how can I show 8 bit parameter in Modelsim simulation while I have just two value 0 or 1?
module eightBitAlu(clk, a, b,si,ci, opcode,outp);
input clk;
input [7:0] a, b;
input [2:0] opcode;
input si;
input ci;
output reg [7:0] outp;
always #(posedge clk)
begin
case (opcode)
3'b000: outp <= a - b;
3'b000 : outp <= a + b;
3'b001 : outp =0;
3'b010 : outp <= a & b;
3'b011 : outp <= a | b;
3'b100 : outp <= ~a;
endcase
end
endmodule
and this is my test module
module test_8bitAlu();
reg clk=0,a=3,b=1,si=0,ci=0,opcode=1;
eightBitAlu alu(clk, a, b,si,ci, opcode,outp);
initial begin
#200 clk=1;
#200 opcode=0;
#200 opcode=2;
#200 opcode=3;
#200 opcode=4;
#200;
end
endmodule
a and b are only 1 bit wide leaving the top 7 bits of your input ports un-driven.
reg clk=0,a=3,b=1,si=0,ci=0,opcode=1;
is equivalent to :
reg clk = 0;
reg a = 3;
reg b = 1;
reg si = 0;
reg ci = 0;
reg opcode = 1;
What you need is:
reg clk = 0;
reg [7:0] a = 3;
reg [7:0] b = 1;
reg si = 0;
reg ci = 0;
reg [2:0] opcode = 1;
wire [7:0] outp;
Further improvemnets would be to include the width on the integer assignment ie:
reg clk = 1'd0;
reg [7:0] a = 8'd3;
b for binary, d for decimal, o for octal and h for hexadecimal in width'formatValue
Note
outp if not defined will be an implicit 1 bit wire.
Your clock in the testharness also only has 1 positive edge. You may prefer to define your clock as:
initial begin
clk = 1'b0;
forever begin
#100 clk = ~clk;
end
end
A complete version of the above is demonstrated at EDAplayground.

my output contineously vary

module multiplier(prod, busy, mc, mp, clk, start);
output [15:0] prod;
output busy;
input [7:0] mc, mp;
input clk, start;
reg [7:0] A, Q, M;
reg Q_1;
reg [3:0] count;
wire [7:0] sum, difference;
always #(posedge clk)
begin
if (start) begin
A <= 8'b0;
M <= mc;
Q <= mp;
Q_1 <= 1'b0;
count <= 4'b0;
end
else
begin
case ({Q[0], Q_1})
2'b0_1 : {A, Q, Q_1} <= {sum[7], sum, Q};
2'b1_0 : {A, Q, Q_1} <= {difference[7], difference, Q};
default: {A, Q, Q_1} <= {A[7], A, Q};
endcase
count <= count + 1'b1;
end
end
alu adder (sum, A, M, 1'b0);
alu subtracter (difference, A, ~M, 1'b1);
assign prod = {A, Q};
assign busy = (count < 8);
initial
begin
$monitor($time,"prod=%b, busy==%b, mc=%b, mp=%b, clk=%b, start=%b",
prod, busy, mc, mp, clk, start);
end
endmodule
module alu(out, a, b, cin);
output [7:0] out;
input [7:0] a;
input [7:0] b;
input cin;
assign out = a + b + cin;
endmodule
----------------------------------testbench----------------------------------------------
module multi_tst_tst;
reg clk, start;
reg [7:0] a, b;
wire [15:0] ab;
wire busy;
multiplier multiplier1 (ab, busy, a, b, clk, start);
initial begin
clk = 0;
a =8'b11100000; b =8'b00100000; start = 1; #10 start = 0;
end
always #5 clk = !clk;
//$strobe("ab: %d busy: %d at time=%t", ab, busy, $stime);
endmodule
This is code for booth multiplier My question when data a and b are available it will start multiplying and its continue if i want to check my answer i have to do #80 $stop but how can i modified my code such that when busy flag goes to zero my output must be at data line and wait for other input please give me some suggestion i am trying this till yesterday i know manually i can use $finish or $stop but i don't want that i want automatically my simulation stop and as another input available it will start again that why i use busy flag
You can wait until busy is deasserted. Something like this:
initial begin
clk = 0;
a =8'b11100000; b =8'b00100000; start = 1;
#10 start = 0;
#(negedge busy); // waits until busy goes from 1 to 0
$finish;
end
For a more detailed test, testing (almost) every possible input:
initial begin
clk = 0;
for (a=8'd0;a<8'd255;a=a+1) begin
for (b=8'd0;b<8'd255;b=b+1) begin
start = 1;
#10 start = 0;
#(negedge busy); //wait until multiplier ends
#(posedge clk); //waits one clock cycle before moving to the next pair of numbers
end
end
end

Resources