I am preforming a feedback mux calculation using verilog. But however the system does not response (giving X) to one of input which is B (the input controlled by the mux). Can helping me pointing out where is the error and how to fix it.
Here are the codes:
module test(input sel,input [3:0]a,b,output [3:0]o);
localparam in_0 = 4'd0;
wire [3:0]w1;
assign w1 = a + b;
assign o = w1 | 4'd0;
assign b = (sel)?w1:in_0;
endmodule
Here are the testbench:
module test_tb();
reg sel;
reg [3:0] a,b;
wire [3:0]o;
test U1(.sel(sel),.a(a),.b(b),.o(o));
initial begin
sel <= 1'b0;
a <= 4'd2;
#2;
sel <= 1'b1;
#2;
a <= 4'd1;
#2;
sel <= 1'b0;
a <= 4'd4;
#2;
end
endmodule
According to the testbench (the initialization) it seems that b is not an input (it's just the output of multiplexer)
I think you want to implement the following circuit :
But to avoid creating loops (when sel=1), you should add a clk port to your design in order to control the operation :
module test(
input clk,
input sel,
input [3:0] a,
output [3:0] o
);
wire [3:0] b;
reg [3:0] w1;
assign o = w1;
assign b = (sel)?w1:4'd0;
always #(posedge clk)
w1 <= a + b;
endmodule
Looking at your example :
module test(
input sel,
input [3:0] a,
input [3:0] b,
output [3:0]o
);
localparam in_0 = 4'd0;
wire [3:0]w1;
assign w1 = a + b;
assign o = w1 | 4'd0;
assign b = (sel)? w1 : in_0;
Note that with sel==1 you have w1 = a+b, and b =w1which is w1= a+w1; as a combinatorial loop. this will not work. If there was a flip-flop inside to break the loop then it would behave like an accumulator.
Aa noted by Emman that b is an input and therefore the value can not be overriden.
This line assign b = (sel)? w1 : in_0; is not valid. Note that it never actually uses the input value as this completely overrides it in all situations.
Related
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.
I am using EDA Playground with Aldec Riviera simulator, and I have this module here:
module alu(input logic [31:0] a, b,
input logic [2:0] alucontrol,
output logic [31:0] result,
output logic zero);
logic [31:0] condinvb, sum;
assign condinvb = alucontrol[2] ? ~b : b;
assign sum = a + condinvb + alucontrol[2];
always_comb
case (alucontrol[1:0])
2'b00: result = a & b;
2'b01: result = a | b;
2'b10: result = sum;
2'b11: result = sum[31];
endcase
assign zero = (result == 32'b0);
endmodule
and my testbench is here:
module alu_testbench();
logic [31:0] a,b;
logic [2:0] alucontrol;
logic [31:0] result;
logic zero, clk;
alu test_alu(a,b,alucontrol);
initial begin
$dumpfile("dump.vcd"); $dumpvars(1);
clk = 0;
a = 'hdead0000; b = 'h0000beef; alucontrol = 'b010; #1;
a = 'hc0debabe; b = 'h0000ffff; alucontrol = 'b000; #1;
a = 'hc0de0000; b = 'h0000babe; alucontrol = 'b001; #1;
a = 'hc0debabe; b = 'h0000babe; alucontrol = 'b100; #1;
end
always begin
#1; clk = ~clk;
end
endmodule
When I run the testbench and look at the generated waveform, I do not see result being updated. Instead, it stays as XXXX_XXXX. What am I doing wrong in the testbench?
In the testbench, you declared the result signal, but it is not connected to anything. You probably intended it to be driven by the alu output of the same name. In that case, you should connect it to the instance:
Change:
alu test_alu(a,b,alucontrol);
to:
alu test_alu(a,b,alucontrol,result,zero);
Try your code on other simulators on edaplayground; you should get warnings about unconnected ports.
With your code, if you looked inside the alu instance, the result signal would not be X.
Another equivalent way to code the instance is to use connections by name:
alu test_alu (
.a (a),
.b (b),
.alucontrol (alucontrol),
.result (result),
.zero (zero)
);
This makes it easier to avoid common connection errors.
I'm writing an ALU for a processor I'm designing (first RTL project) and I'm getting a high impedance output on ALU_out when I run my testbench, even though the flags do get set and are output correctly.
module alu(
input clk,
input reset,
input [7:0] A, B,
input [3:0] Op_Sel,
output [7:0] ALU_out,
output C, V, N, Z
);
reg [8:0] Result = 0;
reg [8:0] cn_temp = 0;
reg [7:0] v_temp = 0;
reg carry = 0;
reg overflow = 0;
reg negative = 0;
reg zero = 0;
assign ALU_Out = Result[7:0];
assign C = carry;
assign V = overflow;
assign N = negative;
assign Z = zero;
always #*
begin
if (reset)
begin
Result = 0;
cn_temp = 0;
v_temp = 0;
carry = 0;
overflow = 0;
negative = 0;
zero = 0;
end
end
always #(posedge clk)
begin
case(Op_Sel)
4'b0000: // Addition
begin
Result = A + B;
negative = Result[7];
zero = (Result[7:0] == 8'b00000000);
carry = Result[8];
v_temp = A[6:0] + B[6:0];
overflow = v_temp[7] ^ carry;
end
.
.
//The rest of the instructions
.
.
.
endcase
end
endmodule
//My testbench
module alu_testbench();
reg clk;
reg reset;
reg [7:0] A;
reg [7:0] B;
reg [3:0] Op_Sel;
wire [7:0] ALU_out;
wire C, V, N, Z;
always begin
#1
clk = ~clk;
end
initial begin
clk = 0;
reset = 0;
#1
reset = 1;
#1
reset = 0;
end
initial begin
#10
A=2;
B=3;
Op_Sel = 4'b0000;
#10
A=1;
end
alu alu (
.clk(clk),
.A(A),
.B(B),
.Op_Sel(Op_Sel),
.ALU_out(ALU_out),
.C(C),
.V(V),
.N(N),
.Z(Z));
endmodule
I believe I connected up the module to the testbench (through a wire), so why am I getting high impedance on ALU_out?
This was a tricky typo. You mistakenly used an upper-case "O" in the ALU_Out signal name. Since Verilog is case-sensitive, this is a different signal from ALU_out. It is not mandatory to declare all signals in Verilog. However, you can use the following compiler directive in your code to help catch this type of common problem:
`default_nettype none
Your simulator should generate an error.
To fix it, change:
assign ALU_Out = Result[7:0];
to:
assign ALU_out = Result[7:0];
My simulators also generated a warning message because you didn't drive the reset input of alu. Here is the fix:
alu alu (
.clk(clk),
.reset(reset), /// <------ add this
.A(A),
.B(B),
.Op_Sel(Op_Sel),
.ALU_out(ALU_out),
.C(C),
.V(V),
.N(N),
.Z(Z));
I'm trying to build an 8-bit multiplier in Verilog, but I keep running in to this weird error when I go to simulate my module's test bench. It says:
Too many port connections. Expected 8, found 9
This doesn't really make any sense seeing as how both the module AND the test bench have 9 variables listed. Any help will be much appreciated!
Multiplier Module
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
reg Done;
reg [1:0] state;
reg [7:0] A_reg, B_reg;
reg [15:0] A_temp, B_temp, O_temp, O_reg;
my16bitadder Adding(O_temp, Cout,A_temp,B_temp, Cin);
always#(posedge Clk)
begin
if(Reset) assign state = {2'b00};
case(state)
0:
if(Load)
begin
A_reg = A;
B_reg = B;
O_reg = A_reg;
state = 1;
end
1:
begin
A_temp = A_reg;
B_temp = O_reg;
B_reg = B_reg - 1;
state = 2;
end
2:
begin
O_reg = O_temp;
if(B_temp)
begin
state = 1;
end
else
begin
state = 3;
Done = 1'b1;
end
end
3:
begin
Done = 1'b0;
state = 0;
end
endcase
end
endmodule
Testbench
module my8bitmultiplier_tb;
reg Load, Clk, Reset, Cin;
reg [7:0] A, B;
wire [15:0] O;
wire Done, Cout;
my8bitmultiplier dut(O, Done, Cout, A, B, Load, Clk, Reset, Cin);
always #5 Clk = ~Clk;
initial
begin
A = 8'b10;
B = 8'b10;
Load = 1;
Cin = 0;
#10 Load = 0;
#3000 A = 8'd100;
#3000 B = 8'd100;
#3000 Load = 1;
#3010 Load = 0;
#6000 A = 8'd150;
#6000 B = 8'd150;
#6000 Load = 1;
#6000 Load = 0;
begin
$display ($time,"A= %d B= %d O=%d ", A, B, O);
end
#10000 $finish;
end
endmodule
When I run you code on another simulator, I get a more helpful warning message:
reg Done;
|
xmvlog: *W,ILLPDX : Multiple declarations for a port not allowed in module with ANSI list of port declarations (port 'Done') [12.3.4(IEEE-2001)].
The warning goes away when I delete this line:
reg Done;
and change:
module my8bitmultiplier (output [15:0] O, output Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
to:
module my8bitmultiplier (output [15:0] O, output reg Done, Cout, input [7:0] A, B, input Load, Clk, Reset, Cin);
Perhaps that solves your problem on modelsim. You can also try your code on different simulators on edaplayground. You will sometimes get more helpful messages.
I'm attempting to visualize some code from here. However, the wire values I'm trying to view (all the reqs and acks in SIMSYS) are displaying as 'x'.
I don't know enough about any HDLs to know what is going wrong, so I'd appreciate an explanation of what's going on. If it makes any difference, I'm running it with iverilog 10.2 on Ubuntu 19.04.
Here's the code in question:
// A Muller C-element
module MCEL (q, a, b);
input a, b;
output q;
wire reset;
wire p1 = !(a & q);
wire q1 = !(b & q);
wire r1 = !(a & b);
assign #13 q = !(p1 & q1 & r1);
endmodule
//Micropipeline stage (David Sutherland style).
module MPHSL(req_l, ack_l, req_r, ack_r, din,dout);
input req_l; output ack_l;
output req_r; input ack_r;
MCEL left(ack_l, req_l, !req_r);
MCEL right(req_r, ack_l, !ack_r);
// Data handling stage
input [7:0] din;
output [7:0] dout;
reg [7:0] dout1;
always #(posedge req_l) dout1 <= din;
assign dout = dout1;
endmodule
// Simulation wrapper
module SIMSYS();
wire req_1, ack_1;
wire req_2, ack_2;
wire req_3, ack_3;
wire req_4, ack_4;
reg tn;
initial begin tn = 0; #350 tn = 1; # 20 tn = 0; end
wire [7:0] d1,d2,d3,d4;
MPHSL s1(tn | req_4, ack_4, req_1, ack_1, (tn)? 8'hx5A: d4+1, d1);
MPHSL s2(req_1, ack_1, req_2, ack_2, d1, d2);
MPHSL s3(req_2, ack_2, req_3, ack_3, d2, d3);
MPHSL s4(req_3, ack_3, req_4, ack_4, d3, d4);
endmodule
The issue is that there are no initial values and no logic that resets any variables to a valid state, so the code is forever propagating X values. The first thing you need to do is change the MCEL module's q output to be a reg so you can assign it an initial value, then give it and MPHSL's dout1 reg their values. For example:
// A Muller C-element
module MCEL (q, a, b);
input a, b;
output reg q = 0;
wire reset;
wire p1 = !(a & q);
wire q1 = !(b & q);
wire r1 = !(a & b);
always #* #13 q = !(p1 & q1 & r1);
endmodule
//Micropipeline stage (David Sutherland style).
module MPHSL(req_l, ack_l, req_r, ack_r, din,dout);
input req_l; output ack_l;
output req_r; input ack_r;
MCEL left(ack_l, req_l, !req_r);
MCEL right(req_r, ack_l, !ack_r);
// Data handling stage
input [7:0] din;
output [7:0] dout;
reg [7:0] dout1 = 0;
always #(posedge req_l) dout1 <= din;
assign dout = dout1;
endmodule
// Simulation wrapper
module SIMSYS();
wire req_1, ack_1;
wire req_2, ack_2;
wire req_3, ack_3;
wire req_4, ack_4;
reg tn;
initial begin tn = 0; #350 tn = 1; # 20 tn = 0; end
wire [7:0] d1,d2,d3,d4;
MPHSL s1(tn | req_4, ack_4, req_1, ack_1, (tn)? 8'hx5A: d4+1, d1);
MPHSL s2(req_1, ack_1, req_2, ack_2, d1, d2);
MPHSL s3(req_2, ack_2, req_3, ack_3, d2, d3);
MPHSL s4(req_3, ack_3, req_4, ack_4, d3, d4);
endmodule
And the result: