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.
Related
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 want it to show the output of the flip flop but instead it lists the output as 'Z'. How can I get it to do this?
Code:
module d_flip_flop_edge_triggered(Q, Qn, C, D);
output Q;
output Qn;
input C;
input D;
wire Q;
wire Qn;
wire Cn;
wire Cnn;
wire DQ;
wire DQn;
not(Cn, C);
not(Cnn, Cn);
endmodule
This is the test bench - I think the problem lies here.
TestBench:
module ffTB;
// Inputs
reg C;
reg D;
// Outputs
wire Q;
wire Qn;
// Instantiate the Unit Under Test (UUT)
d_flip_flop_edge_triggered uut (
.Q(Q),
.Qn(Qn),
.C(C),
.D(D)
);
initial begin
// Initialize Inputs
C = 0;
D = 0;
// Wait 100 ns for global reset to finish
#100;
C = 1;
D = 1;
#100;
C = 0;
#100;
C = 1;
#100;
C = 0;
#100;
C = 1;
#100;
C = 0;
end
endmodule
Thank you my grade depends on it!
Your model for the flip-flop is completely wrong. (Sorry, but it's true.) With the exception of the input C, none of the inputs or outputs are connected to anything! As a result, the testbench shows that the outputs are floating, which is denoted by the value Z.
Your D flip-flop RTL,
module d_flip_flop_edge_triggered( output reg Q,
output wire Qn,
input wire clk,
input wire rst_n,
input wire D
);
always # (posedge clk or negedge rst_n)
begin
if (~rst_n)
begin
Q <= 1'b0;
end
else
begin
Q <= D;
end
end
assign Qn = ~Q;
endmodul
And Testbench,
module ffTB;
reg clk;
reg rst_n;
reg D;
wire Q, Qn;
d_flip_flop_edge_triggered d_flip_flop_edge_triggered_inst (Q, Qn, clk, rst_n, D);
initial
begin
clk = 1'b0;
rst_n = 1'b0;
D = 1'b0;
#10 rst_n = 1'b1;
#600 $finish;
end
always clk = #5 ~clk;
initial
begin
repeat (100)
begin
D = $random;
#5;
end
end
endmodule
with simulation,
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.
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
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.