I'm trying to make an SR flipflop on Icarus Verilog.
Flipflop module:
module srff(sr,clk,q,qb);
input [1:0]sr;
input clk;
output reg q,qb;
always#(posedge clk) begin
case(sr)
2'b00: q=q;
2'b01: q=0;
2'b10: q=1;
2'b11: q=1'bz;
endcase
end
assign qb=~q;
endmodule
Testbench:
module sr_ff_test;
reg [1:0]sr;
reg clk;
wire q,qbar;
srff sr_ff_test(sr,clk,q,qbar);
initial begin $dumpfile("dump1.vcd");
$dumpvars(0,sr_ff_test);
end
initial begin
$monitor("S=%d, R=%d, CLK=%d, Q=%d, Qbar=%d",sr[0],sr[1],clk,q,qbar);
sr[0]=1'b0;
sr[1]=1'b1;
clk=1;
#100
sr[0]=1'b0;
sr[1]=1'b1;
#100
sr[0]=1'b0;
sr[1]=1'b0;
#100
sr[0]=1'b1;
sr[1]=1'b1;
#100
sr[0]=1'b0;
sr[1]=1'b1;
#100
sr[0]=1'b0;
sr[1]=1'b1;
end
endmodule
The error is as given in the question (line 14 of testbench - the one with monitor...). What went wrong, and how do I fix this?
I'm new to Icarus Verilog, and I don't know if I have accidentally used commands that aren't usable.
The error is in the srff module. You declared qb as a reg, but then you try to drive it with a continuous assignment using the assign keyword.
The solution is to not declare it as a reg. Change:
output reg q,qb;
to:
output reg q;
output qb;
Related
I wrote this Verilog code. The inner module is an 8-bit mux, and the top module is used to test the mux. It should display 11110000, but it displayed xxxxxxxx every time. How do I fix this?
module testbench;
reg CLK;
test mytest(CLK);
initial begin
CLK = 1'b0;
#10
CLK = 1'b1;
end
endmodule
module test(CLK);
input CLK;
reg [7:0] in0,in1;
reg sel;
wire [7:0] out;
mux myux(in0,in1,sel,out);
always #(posedge CLK) begin
sel = 1'b0;
in0 = 8'b11110000;
$display("%b",out);
end
endmodule
This is the mux module:
module mux(in0,in1,sel,out);
input sel;
input [7:0] in1,in0;
output [7:0] out;
reg out;
always #(in0,in1,sel) begin
if(sel == 1'b0) begin
out = in0;
end
else begin
out = in1;
end
end
endmodule
The problem is that you did not run your simulation long enough. You only ran it for one clock cycle. Here is one way to change your testbench module to run many clock cycles:
module testbench;
reg CLK;
test mytest(CLK);
initial begin
CLK = 1'b0;
forever #10 CLK =~CLK;
end
initial #1000 $finish;
endmodule
I now see output like this:
xxxxxxxx
11110000
11110000
11110000
11110000
Also, I got a compile error with your code. In your mux module, you should change:
reg out;
to:
reg [7:0] out;
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.
I want to infer a simple flip flop using verilog. Here is the code.
module tb_simpleRegister();
reg clk;
reg a;
wire b;
simpleRegister dut
(
.clk(clk),
.a(a),
.b(b),
.c(c)
);
initial begin
clk=1;
a=0;
#10
a=1;
#10
a=0;
end
always #5 clk = ~clk;
endmodule
module simpleRegister(
input clk,
input a,
output reg b,
output reg c
);
always #(posedge clk) begin
b <= a;
c <= b;
end
endmodule
And here is the result when I run it. The b output of dut does not behave like a flip flop. However output c does. Any comments on why is this happening?
I would rewrite the test bench as follows:
initial begin
#(posedge clk);
a<=0;
#(posedge clk);
a<=1;
#(posedge clk);
a<=0;
end
//Clock in separate process
initial begin
clk=1;
forever begin
#5 clk = ~clk;
end
end
The non-blocking assignment will ensure the value of a is changed just after the clock edge giving the testbench a full cycle setup.
My understanding of Verilog tasks is that they act like subroutines and are able to accept both input and output parameters. Using $display, I can peek at the values of my register variables along the way. For some reason my output register does not seem to overwrite the argument. Here is an example:
`timescale 1 ps / 1 ps
`default_nettype none
module testbench;
reg clk;
reg data_reg = 8'h00;
always begin // 100MHz clock
clk = 1'b1;
#(5000);
clk = 1'b0;
#(5000);
end
task copy(input reg [7:0] din, output reg [7:0] dout);
begin
$display("copy: before: din=%h, dout=%h",din,dout);
#(negedge clk);
dout = din;
#(negedge clk);
$display("copy: after: din=%h, dout=%h",din,dout);
end
endtask
initial
begin
$display("data_reg=%h",data_reg);
copy(8'hBC, data_reg);
$display("data_reg=%h",data_reg);
copy(8'h00, data_reg);
$display("data_reg=%h",data_reg);
$display("done");
$finish;
end
endmodule
And here is the output of the icarus-verilog simulator:
data_reg=0
copy: before: din=bc, dout=xx
copy: after: din=bc, dout=bc
data_reg=0
copy: before: din=00, dout=bc
copy: after: din=00, dout=00
data_reg=0
done
Why doesn't the register data_reg get overwritten when the copy task is called?
You forgot to set the width for reg data_reg so it is 1 bit wide and you happen to be assigning an even value to it so it is zero.
My code for the design block and the testbench compiles; however, when I simulate, I'm not getting the correct output. Can anyone tell me where I'm going wrong in my code?
Here is the code for testbench:
module testbench;
reg [511:0]FROM_LS;
reg CLK;
reg [63:0]TO_IF_ID;
initial
begin
CLK= 0;
TO_IF_ID[63:0]=63'b0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule
and here is the code for the design block:
module inst_line_buffer(input wire [511:0]from_LS,
input wire clk,
output reg [63:0]to_if_id);
parameter mem_size=16;
integer k;
reg [31:0] ilb[0:mem_size-1];
initial
begin
for (k = 0; k < mem_size ; k = k + 1)
begin
ilb[k] = 32'b00;
//$display ("ilb= %b",ilb[k]);
end
end
always #(posedge clk)
begin
ilb[0]= from_LS[511:480];
ilb[1]= from_LS[479:448];
ilb[2]= from_LS[447:416];
ilb[3]= from_LS[415:384];
ilb[4]= from_LS[383:352];
ilb[5]= from_LS[351:320];
ilb[6]= from_LS[319:288];
ilb[7]= from_LS[287:256];
ilb[8]= from_LS[255:224];
ilb[9]= from_LS[223:192];
ilb[10]= from_LS[191:160];
ilb[11]= from_LS[159:128];
ilb[12]= from_LS[127:96];
ilb[13]= from_LS[95:64];
ilb[14]= from_LS[63:32];
ilb[15]= from_LS[31:00];
to_if_id [63:32]= ilb[0];
to_if_id [31:0]= ilb[1];
$display("ilb= %b", ilb[1]);
end
endmodule
I'm expecting that the value of TO_IF_ID should be 0001100000001000110011100101110100110000010001111111110001110000, but I'm getting all zeros.
When you run a simulation on your testbench module, TO_IF_ID is always 0 because you only assigned a value to it once at time 0 in your initial block. If you want the value to change, it needs to be driven somehow.
As Andy pointed out in a comment, you probably meant to instantiate the inst_line_buffer module in your testbench. Verilog will not do this magically for you. But then, you should declare TO_IF_ID as a wire instead of a reg and remove it from the initial block.
module testbench;
reg [511:0]FROM_LS;
reg CLK;
wire [63:0]TO_IF_ID;
inst_line_buffer inst_line_buffer (
.from_LS (FROM_LS),
.clk (CLK),
.to_if_id (TO_IF_ID)
);
initial begin
CLK= 0;
FROM_LS[511:480]= 32'b00011_00000_00100_01100_11100_10111_01;
FROM_LS[479:448]=32'b00_11000_00100_01111_11111_00011_10000;
#500 $finish;
end
always
begin
#10 CLK= ~ CLK;
//FROM_LS[511:448]= ~ FROM_LS[511:448];
$display("FROM_LS= %b", FROM_LS);
$display("TO_IF_ID= %b", TO_IF_ID);
end
endmodule