How to correct this error "Illegal reference to net q"? [duplicate] - verilog

This question already has answers here:
Error: "(vlog-2110) Illegal reference to net"
(2 answers)
Closed 22 days ago.
I am getting this error when I am compiling my file which Using Behaviour Modelling is designing a positive edge triggered T-Flip-Flop with asynchronous clear in Verilog code.
module t_flip_flop (input clk, input pr, input clr, input d, output q);
reg q_next;
always # (posedge clk or negedge clr) begin
if (clr == 0) q_next <= 1'b0;
else if (pr == 1) q_next <= d;
else if (clk == 1'b1) q <= q_next;
end
endmodule
module t_flip_flop_testbench;
reg clk, pr, clr, d;
wire q;
t_flip_flop tff (clk, pr, clr, d, q);
initial begin
clk = 0;
pr = 0;
clr = 0;
d = 0;
#10
clk = 1;
#10
clk = 0;
pr = 1;
d = 1;
#10
clk = 1;
#10
clk = 0;
pr = 0;
d = 0;
#10
clk = 1;
#10
clr = 1;
#10
clr = 0;
#10
$finish;
end
endmodule

In the t_flip_flop module, q is implicitly a "net" type. You need to explicitly declare q as a reg type since you are making a procedural assignment to it inside the always block.
Change:
module t_flip_flop (input clk, input pr, input clr, input d, output q);
to:
module t_flip_flop (input clk, input pr, input clr, input d, output reg q);
That change fixes the error.
Unrelated to your reported error, the following line is a little unusual:
else if (clk == 1'b1) q <= q_next;
You likely want to get rid of the clk condition. While it may simulate as you wish, it might be a problem if you want to synthesize it.

Related

Verilog Adder/Subtractor [duplicate]

This question already has answers here:
How do I use flip flop output as input for reset signal
(1 answer)
Why is my counter out value producing StX?
(2 answers)
Closed 2 months ago.
Trying to make a Binary adder and Subtractor in Verilog Output keeps coming out as X I don't think it is the testbench I believe is something wrong with the wires for the output F. The Flip Flops and the Multiplexer should be correct but I have no way of knowing for sure I do not get any error messages when I run this
module Subtractor(A, B, Bin, Bout , Sub); //Variables for subtractor
// 1-bit full binary subtractor.
input A;//Input variable
input B;//Input variable
input Bin;//Input variable
output Bout;
output Sub;
assign Bout=((~A)&(B))|((~A)&(Bin))|((B)&(Bin));
assign Sub=(A^B^Bin);
endmodule
module Adder(A, B, Cin, Cout, Sum);
// 1- bit full binary adder
input A, B, Cin;
output Cout, Sum;
assign Cout = ((A)&(Cin))|((B)&(Cin))|((A)&(B));
assign Sum = (A^B^Cin);
endmodule
module CarryFLIPFLOP(CLK,RESET,D,Q);
//Flip flop for carry value
input CLK,RESET,D;
output reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module BorrowFLIPFLOP(CLK,RESET,D,Q);
// 1- bit full binary adder
input CLK,RESET,D;
output reg Q;
//reg Q;
always #(posedge CLK)
begin
if(RESET)
Q<=0;
else
Q<=D;
end
endmodule
module Fplexer(Sum, Sub, S, F, clk);
input Sum, Sub, S, clk;
output reg F;
always#(posedge clk) begin
if(S==1) begin
F <= Sum;
end else begin
F <= Sub;
end
end
endmodule
module z_flag(clk,F,R,Z);
input clk,F,R;
output reg Z=1;
always#(posedge clk)begin
Z=R|(Z&~F);
end
endmodule
module top(A,B,S,R,clk,F,Z,N,V);
input A, B, S, R, clk;
output F, Z, N, V;
wire w0,w1,w2,w3,w4,w5,w6,w7,w8;
assign w7 = A;
assign w8 = B;
Subtractor S0(.A(w7), .B(w8), .Bin(w3), .Bout(w4), .Sub(w5));
BorrowFLIPFLOP Borrow(.CLK(clk), .RESET(R), .D(w2), .Q(w3));
Adder A0(.A(w7), .B(w8), .Cin(w0), .Cout(w1), .Sum(w2));
CarryFLIPFLOP Carry(.CLK(clk), .RESET(R), .D(w2), .Q(w0));
Fplexer multi(.Sum(w2), .Sub(w5), .S(S), .F(w6), .clk(clk));
assign V=(w0 & w1);
assign F = w6;
assign N = w6;
z_flag Zflag(.clk(clk), .F(w6), .R(R), .Z(Z));
endmodule
module testbench;
reg clk;
reg R;
reg A;
reg B;
reg S = 0;
wire F;
//intitialize clock/top
top UUT(A,B,S,R,clk,F,Z,N,V);
always
#5 clk = ~clk;
initial begin
$display("Testing +- Machine");
$monitor("%d - %d Is %d",A, B, F);
A = 0; B = 1; S = 0; R=0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 1; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
A = 1; B = 0; #10;
clk = 1; #1;
clk = 0; #1;
clk = 1; #1;
end
endmodule
Your design has a reset signal and you never used it.
Your FLIPFLOP code does not have RESET in the sensitivity list.
You are making assignments to clk in an always block and in the initial block. Pick one place.
Learn how to save waveforms to see internal signals, not just the top level output.

Verilog codes work nicely in simulation but not generating ouput on basys3 board

I am a student and learning verilog. I needed to created a D-latch simulations. My code and testbench works perfectly for simulation. However, when I implemented it to my basys3 board, I am not generating any outputs.
this is my design source:
module D_latch_dataflow(
input D,
input Enable,
output wire Q,
output wire Qbar
);
wire D_i;
assign #2 D_i = ~D;
assign #2 Q = ~(Enable & D_i |Qbar);
assign #2 Qbar = ~(Enable & D |Q);
endmodule
I tried changing
output wire Q,
output wire Qbar
to
output Q,
output Qbar
But it still doesn't work. What's the problem???
This is my testbench:
module D_latch_dataflow_tb();
reg D;
reg Enable;
wire Q;
wire Qbar;
D_latch_dataflow DUT (.D(D), .Enable(Enable), .Q(Q), .Qbar(Qbar));
initial begin
#120 $finish;
end
initial begin
D = 0; Enable = 0;
#10 D = 1;
#10 Enable = 1;
#10 D = 0;
#10 D = 1;
#10 Enable = 0;
#10 D = 0;
#10 D = 1;
#10 D = 0;
#10 Enable = 1;
#10 D = 1;
#10 D = 0;
#20;
end
endmodule
This is my simulation.
enter image description here
assign #2 D_i = ~D;
Delays aren't synthesizable -- there is no hardware in the FPGA that can be used to build a predictable unclocked delay. They should not be used outside of testbenches.
If you really want a D latch (and cannot use FPGA primitives), you will need to describe its behavior using an always block, e.g.
reg Q;
always #(D or Enable)
if (Enable)
Q <= D;
Note that this will generate warnings in many synthesis tools -- latches are considered undesirable, as they often cause timing problems.

Output of multiplication in Verilog not showing in simulate behavior

I've written two different Verilog snippets for combinational and sequential multiplication, which I post below. When I simulate either of the multiplications the multiplier, denoted mult_A and multiplicand, denoted mult_B show their bit-string values, but the resulting product, denoted R shows all Xs. Help in showing the codes multiplication result R would be greatly appreciated.
Combinational
module com_multiplication(mult_A, mult_B, R);
input [15:0] mult_A, mult_B;
output R;
reg [31:0] R;
integer k;
always#(mult_A, mult_B)
begin
R = 0;
for(k = 0; k < 16; k = k + 1)
if(mult_A[k] == 1'b1) R = R + (mult_B << 1);
end
endmodule
Serial
module ser_multiplication(mult_A, mult_B, clk, start, R, finish);
input [15:0] mult_A, mult_B;
input clk, start;
output R, finish;
reg [31:0] R;
reg [15:0] mult_A_duplicate;
reg [31:0] mult_B_duplicate;
reg [4:0] p;
wire finish = !p;
initial p = 0;
always#(posedge clk)
if (finish && start) begin
p = 16;
R = 0;
mult_B_duplicate = {16'd0, mult_B};
mult_A_duplicate = mult_A;
end else if (p) begin
if (mult_A_duplicate[0] == 1'b1) R = R + mult_B_duplicate;
mult_A_duplicate = mult_A_duplicate >> 1;
mult_B_duplicate = mult_B_duplicate << 1;
p = p - 1;
end
endmodule
Testbench
For now the serial part is commented out.
module multiplication_tb;
reg clk, start, finish;
reg [15:0] mult_A, mult_B;
reg [31:0] R;
com_multiplication U0 (
.mult_A (mult_A),
.mult_B (mult_B),
.R (R)
);
/*ser_multiplication U1 (
.clk (clk),
.start (start),
.finish (finish),
.mult_A (mult_A),
.mult_B (mult_B),
.R (R)
); */
initial
begin
$display("time\t clk start finish");
$monitor ("%g\t %b %b %b %b %b %b", $time, clk, start, finish, mult_A,
mult_B, R);
#100 clk = 0;
mult_A =0;
mult_B = 0;
#10 mult_A = 2;
mult_B = 3;
#20 mult_B=2;
#10 mult_B=5;
#100 $finish;
end
always
#5 clk = !clk;
endmodule
I just glanced at your code but it looks like your clock is not toggling. Simple way to make a forever toggling clock is:
initial
begin
clk = 1'b0;
forever
#50 clk = ~clk;
end

Verilog: one clock cycle delay using register

I'm trying to delay two signals. I wrote a register to do that and instantiated it but a strange thing happens. Delaying "state" signal seems to work, but delaying "nb_bits" signal doesn't.
Here's my code for the register:
`timescale 1ns / 1ps
module register(
input CLK,
input clr,
input en,
input [7:0] in,
output [7:0] out
);
reg [7:0] temp;
always # (posedge CLK or posedge clr) begin
if (clr) begin
temp <= 8'b00010000;
end
else if (en) begin
temp <= in;
end
else begin
temp <= temp;
end
end
assign out = temp;
endmodule
And that's ma instantiation:
wire [3:0] nbb;
nb_bits_register nb_bits_reg(
.CLK(CLK),
.clr(clr),
.en(en),
.in(nb_bits),
.out(nbb)
);
wire [7:0] stt;
register state_reg(
.CLK(CLK),
.clr(clr),
.en(en),
.in(state),
.out(stt)
);
nb_bits_register module is analogical; I didn't want to parametrize before solving this problem.
`timescale 1ns / 1ps
module nb_bits_register(
input CLK,
input clr,
input en,
input [3:0] in,
output [3:0] out
);
reg [3:0] temp;
always # (posedge CLK or posedge clr) begin
if (clr) begin
temp <= 4'b0000;
end
else if (en) begin
temp <= in;
end
else begin
temp <= temp;
end
end
assign out = temp;
endmodule
And here's a simulation:
enter image description here
And testbench:
`timescale 1ns / 1ps
module state_machine_tb();
reg CLK, clr, en;
reg [7:0] symbol;
reg [3:0] nb_bits;
wire [7:0] state;
initial begin
CLK <= 1;
clr <= 0;
en <= 0;
symbol <= 8'b00110010;
nb_bits <= 1;
#10
clr <= 1;
en <= 1;
#10
clr <= 0;
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110010;
nb_bits <= 2;
#10
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110001;
nb_bits <= 1;
#10
symbol <= 8'b00110000;
nb_bits <= 3;
#10
$finish;
end
always begin
#5 CLK <= ~CLK;
end
state_machine state_machine_inst(
.CLK(CLK),
.clr(clr),
.en(en),
.symbol(symbol),
.nb_bits(nb_bits),
.state(state)
);
endmodule
It does seem like a rase condition in the scheduler. By definition from the Verilog LRM, the order of evaluating procedural blocks (always blocks and initial blocks) is indeterminate. You might notice a pattern with a particular simulator and version, but that patter can change when changing the simulator or changing the version of the same simulator.
Use blocking assignment with your clock (ex: always #5 CLK = ~CLK;). With will guarantee the CLK will be updated before other stimulus.
In the test bench, change all the #10 to #(posedge CLK). The timing will be the same, however it guarantees CLK was updated before evaluating the new values symbol and other stimulus.
FYI: If you change output [7:0] out to output reg [7:0] out you can assign out directly in your always block, removing the need for temp. This doesn't change anything functionally; just fewer variables and lines of code.
It seems like a race condition: your changes of nb_bits coincide with positive edges of CLK, so there's an ambiguity resolved by the simulator in this way:
change nb_bits (from 1 to 2, etc.)
change CLK from 0 to 1
execute in nb_bits_register: if (en) temp <= in; ... assign out = temp;
As the result, out = in in nb_bits_register.
A solution is to avoid this coincidence, e.g. by changing the first #10 in the testbench to #11.

Nonblocking simultaneous assignments to wires and registers in Verilog

I am interested to write Verilog module which simultaneously will update several outputs
Something like following code, makes 3 operations at the same time (clk 10):
module mymodule (a,b,c,d,e);
input a;
input b;
output c;
output d;
output e;
wire b;
wire a;
wire c;
wire d;
reg e;
initial begin
c <= #10 (a+b);
d <= #10 a;
e <= #10 b;
end
endmodule
Is that code legal?
How todo a one off assign of variables after 10 timeunits or clocks:
As a testbench level construct:
reg c,d,e;
initial begin
#10;
c = a+b;
d = a;
e = b;
end
For RTL (synthesis) first you need a testbench with a clock.
I would generate a clock like this in my testharness :
reg clk ; //Rising edge every 10 timesteps
initial begin
clk = 0;
#5;
forever begin
#5 ;
clk = ~clk;
end
end
Build a counter which counts to 10 and once it reaches 10 Enables the flip-flop to load new values.
wire enable = (counter == 4'b10);
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
c <= 1'b0;
d <= 1'b0;
e <= 1'b0;
end
else if (enable) begin
c <= (a+b);
d <= a;
e <= b;
end
end
endmodule
Extra Verilog Tips
Outputs are implicitly wires no need to redefine them.
Non-Blocking assignments <= are for use in an always #(posedge clk) when inferring flip-flops.
regs or logic types can be assigned inside always or initial blocks. wires are used with assign or for connectivity between ports.

Resources