I just started building up-count timer in Verilog, and I keep getting unknown as output.
I'm using 50MHz osciliator and these variables for the code:
min : sec : 1/100 sec
a b : c d : e f
For example, I want the timer to be:
00:00:99 > 00:01:00
...
00:59:99 > 1:00:00
module timer (clk,
a,
b,
c,
d,
e,
f,
count);
input clk;
input [18:0]count;
output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;
always#(posedge clk)
begin
if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
always#(posedge clk)
begin
if (e == 4'b1010) e = 4'b0000;
else if (f == 4'b1010) e = e +4'b0001;
end
always#(posedge clk)
begin
if (d == 4'b1010) d = 4'b0000;
else if (e == 4'b1010) d = d +4'b0001;
end
always#(posedge clk)
begin
if (c == 4'b1010) c = 4'b0000;
else if (d == 4'b1010) c = c +4'b0001;
end
always#(posedge clk)
begin
if (b == 4'b1010) b = 4'b0000;
else if (c == 4'b0101) b = b +4'b0001;
end
always#(posedge clk)
begin
if (a == 4'b1010) a = 4'b0000;
else if (c == 4'b1010) a = a +4'b0001;
end
endmodule
< test bench >
`timescale 1ns / 1ps
module tb_timer();
parameter clk_period = 10;
parameter N = 19;
reg clk;
reg [N-1:0]count;
wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;
//instatiate the module
timer U0(
.count(count),
.clk(clk),
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f));
// clk signal
always begin
clk =0;
forever #(clk_period/2)clk = ~clk;
end
// count signal
always begin
f = 1'b0
count = 1'b0;
forever #clk_period count = ~count;
end
//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end
endmodule
Assuming you declared f as wire in the testbench and connected it to the f output of timer, my simulator gives me a compile error on this line:
f = 1'b0;
It is illegal to drive a wire with a procedural assignment.
Your instinct is correct; you need to initialize f. It is declared as reg inside timer, which means that it initializes to X.
This is typically done by adding a reset input signal to your design which you drive from your testbench. Assert the reset for the first few clock cycles, then release it. You should probably reset all your registers in the design.
always#(posedge clk or posedge reset)
begin
if (reset) f = 4'b0000;
else if (f == 4'b1010) f = 4'b0000;
else if (count == 19'd500000) f = f+4'b0001;
end
These are the Verilog code that worked.
Thank you for the help!
module timer (clk,
reset,
a,
b,
c,
d,
e,
f,
count);
input clk;
input reset;
input [18:0]count;
output reg[3:0]a;
output reg[3:0]b;
output reg[3:0]c;
output reg[3:0]d;
output reg[3:0]e;
output reg[3:0]f;
always#(posedge clk or negedge reset)
begin
if (~reset) f <= 4'b0000;
else if (f == 4'b1010) f <= 4'b0000;
else if (count == 19'd500000) f <= f + 4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) e <= 4'b0000;
else if (e == 4'b1010) e <= 4'b0000;
else if (f == 4'b1010) e <= e +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) d <= 4'b0000;
else if (d == 4'b1010) d <= 4'b0000;
else if (e == 4'b1010) d <= d +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) c <= 4'b0000;
else if (c == 4'b1010) c <= 4'b0000;
else if (d == 4'b1010) c <= c +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) b <= 4'b0000;
if (b == 4'b1010) b <= 4'b0000;
else if (c == 4'b0101) b <= b +4'b0001;
end
always#(posedge clk or negedge reset)
begin
if (~reset) a <= 4'b0000;
if (a == 4'b1010) a <= 4'b0000;
else if (b == 4'b1010) a <= a +4'b0001;
end
endmodule
// <test bench>
`timescale 1ns / 1ps
module tb_timer();
parameter clk_period = 10;
parameter N = 19;
reg clk;
reg [N-1:0]count;
reg reset;
wire [3:0]a;
wire [3:0]b;
wire [3:0]c;
wire [3:0]d;
wire [3:0]e;
wire [3:0]f;
//instatiate the module
timer U0(
.reset(reset),
.count(count),
.clk(clk),
.a(a),
.b(b),
.c(c),
.d(d),
.e(e),
.f(f));
//reset signal
initial begin
reset = 1;
#13 reset = 0;
#(clk_period)reset =1;
end
// clk signal
always begin
clk =0;
forever #(clk_period/2)clk = ~clk;
end
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
//reset signal
initial begin
reset = 1;
#12 reset = 0;
#(clk_period) reset = 0;
end
endmodule
< Things that I've missed >
The initial value of Flip Flop must be set only when there is reset input.
In testbench, counter should be
// count signal
always begin
count = 0;
forever #(clk_period/5)count = count + 19'b0000000000000000001;
end
The initial block is only executed once and it doesn't synthesis as hardware.
Related
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);
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.
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
I have written a verilog code for a simple coffee vending machine with inputs
25ps,50ps,75ps and 1
as
"00","01","10" and "11"
respectively. Coffee cost is 1 rs. If more than 1rs is inserted, the balance will be returned. That balance will be
01, 10, 11
as
25ps, 50ps, 1rs
respectively. I simulate this without test bench. simulation takes double clock pulse for output.(when i put 25 ps 8 times or 8 clock pulses is required for getting output. expected clock pulse is 4). Why this is happens? and also i didn't get output when using the test bench.
please help me to correct the test bench and my programme. Is clock frequency divider is necessary while doing the programme in fpga board to see output? It is working as expected when i programmed into fpga board.Im using Xilinx vivado 2015.2 tool and zynq board.Please help me to solve these issues
//programme
module main(
input clk,
input rst,
input [1:0] money,
output coffee,
output [1:0] balance
);
reg coff;
reg [1:0] bal;
reg [2:0] pr_st;
reg [2:0] nx_st;
parameter [2:0] A=3'b000;
parameter [2:0] B=3'b001;
parameter [2:0] C=3'b010;
parameter [2:0] D=3'b011;
parameter [2:0] E=3'b100;
parameter [2:0] F=3'b101;
parameter [2:0] G=3'b110;
parameter [2:0] H=3'b111;
always # (posedge clk or posedge rst)
begin
if(rst)
pr_st <= A;
else
pr_st <= nx_st;
end
always #(posedge clk)
begin
case(pr_st)
A : if(money == 2'b00) // input money is 25ps
begin
nx_st <= B;
end
else if(money == 2'b01) // input money is 50ps
begin
nx_st <= C;
end
else if(money == 2'b10) // input money is 75ps
begin
nx_st <= D;
end
else if(money == 2'b11)
begin
nx_st <= E;
end
B : if(money == 2'b00)
begin
nx_st <= C;
end
else if(money == 2'b01)
begin
nx_st <= D;
end
else if(money == 2'b10)
begin
nx_st <= E;
end
else if(money == 2'b11)
begin
nx_st <= F;
end
C : if(money == 2'b00)
begin
nx_st <= D;
end
else if(money == 2'b01)
begin
nx_st <= E;
end
else if(money == 2'b10)
begin
nx_st <= F;
end
else if(money == 2'b11)
begin
nx_st <= G;
end
D : if(money == 2'b00)
begin
nx_st <= E;
end
else if(money == 2'b01)
begin
nx_st <= F;
end
else if(money == 2'b10)
begin
nx_st <= G;
end
else if(money == 2'b11)
begin
nx_st <= H;
end
E : nx_st <= A;
F : nx_st <= A;
G : nx_st <= A;
H : nx_st <= A;
default : nx_st <= A;
endcase
end
//output logic
always #( posedge clk or pr_st)
begin
case(pr_st)
A: begin
coff <= 1'b0;
bal <= 2'b00;
end
B: begin
coff <= 1'b0;
bal <= 2'b00;
end
C: begin
coff <= 1'b0;
bal <= 2'b00;
end
D: begin
coff <= 1'b0;
bal <= 2'b00;
end
E: begin
coff <= 1'b1;
bal<= 2'b00;
end
F: begin
coff <= 1'b1;
bal <= 2'b01;
end
G: begin
coff <= 1'b1;
bal <= 2'b10;
end
H: begin
coff <= 1'b1;
bal <= 2'b11;
end
default : begin
off <=1'b0;
bal <= 2'b00;
end
endcase
end
assign coffee = coff;
assign balance = bal;
endmodule
//test bench
module tb_main(
);
reg clk;
reg rst;
reg [1:0] money;
wire coffee;
wire [1:0] balance;
main dut( clk, rst, money, coffee, balance);
always
begin
#200 clock = ~clk;
end
initial
begin
rst = 1'b1;
#100 rst = 1'b0;
money = 2'b00; // putting 25ps four times to get coffee
#400 money = 2'b01; //putting 50ps two times to get coffee
#200 money = 2'b10;// putting 75ps two times to get coffee
#200 money = 2'b11;// putting 1 rs single time to g
#100 money = 2'b01; // putting 1st 25ps and 50ps i n second clock cycle
#100 money = 2'b10;
#200
$finish
end
endmodule
You need to initialize your clock signal to a known value in the testbench. You should speed up the clock because your money input changes faster than the clock:
initial clk = 0;
always begin
#10 clk = ~clk;
end
Good day guys, I'm created a Shift - And - Add multiplier. I'm confused on why my output is wrong and always at 85. Is it something with the Test bench ? It's working by the way.
new1.v
`define M ACC[0]
module mult4X4 (Clk, St, Mplier, Mcand, Done, Result);
input Clk,St;
input [3:0] Mplier, Mcand;
output Done;
output [7:0] Result;
reg [3:0] State;
reg [8:0] ACC;
initial
begin
State = 0;
ACC = 0;
end
always #(posedge Clk)
begin
case (State)
0:
begin
if(St == 1'b1)
begin
ACC[8:4] <= 5'b00000 ;
ACC[3:0] <= Mplier ;
State <= 1;
end
end
1,3,5,7 :
begin
if(`M==1'b1)
begin
ACC[8:4] <= {1'b0, ACC[7:4]} + Mcand ;
State <= State +1;
end
else
begin
ACC <= {1'b0, ACC[8:1]};
State <= State + 2;
end
end
2,4,6,8 :
begin
ACC <= {1'b0, ACC[8:1]};
State <= State +1;
end
9:
begin
State <= 0;
end
endcase
end
assign Done = (State == 9) ? 1'b1 : 1'b0 ;
assign Result = (State == 9) ? ACC[7:0] : 8'b01010101;
endmodule
tb_new1.v
module tb_mult4X4;
reg Clk,St,nReset;
reg [3:0] Mplier;
reg [3:0] Mcand;
wire Done;
wire [7:0] Result;
mult4X4 UUT (Clk,St,Mplier,Mcand,Done,Result);
initial begin
$dumpfile ("mult4X4.vpd");
$dumpvars;
end
initial
Clk = 0;
always
#5 Clk =~Clk;
initial begin
nReset = 0;
St = 0;
Mcand = 4'b1101;
Mplier = 4'b1011;
#10
nReset = 1;
St = 1;
Mcand = 4'b1111;
Mplier = 4'b1001;
#10
Mcand = 4'b0101;
Mplier = 4'b1010;
#10
Mcand = 4'b1111;
Mplier = 4'b1111;
#10
Mcand = 4'b1101;
Mplier = 4'b1010;
$finish;
end
endmodule
I ran though the code so many times and everything seems to be following my FSM. Can anyone please point out where went wrong. Really confused on this one
#10 is way to short. Your RTL requires 10 clocks to complete but you change the input every clock (half clk is #5).
Use #100 or better yet #(posedge Done); (which makes the test-bench to wait for done regardless the number of clocks that is required).