Verilog sync counter - counter

module syncounter(qa,qabar,qb,qbbar,overflow,ja,ka,jb,kb,clk,rst);
output qa,qabar,qb,qbbar,overflow;
input ja,ka,jb,kb,clk,rst;
reg qa,qb,qabar,qbbar,overflow;
//var1 = qa;
jkflip jk1(qa,qabar,ja,ka,clk,rst);
assign var1 = qa;
jkflip jk2(qb,qbbar,var1,var1,clk,rst);
always # (ja,ka,jb,kb)
begin
if(qa & qb)
begin
overflow = 1;
end
end
endmodule
The code for flip flop is
module jkflip(q,qbar,j,k,clk,rst);
input j,k,clk,rst;
output q,qbar;
wire j,k,clk,rst;
reg q,qbar;
always #(posedge clk)
begin
if(rst) q<=~q;
else
begin
case ({j,k})
2'b00 : q<=q;
2'b01 : q<=1'b0;
2'b10 : q<=1'b1;
2'b11 : q<=~q;
endcase
end
end
endmodule
Testbench for counter
module syncountw();
reg j0,k0,j1,k1,clk,rst;
wire q0,q0bar,q1,q1bar,overflow;
syncounter syn1(q0,q0bar,q1,q1bar,overflow,j0,k0,j1,k1,clk,rst);
always #1 clk = !clk;
//always #1 j0 =1 ;
//always #1 k0 = 1;
initial begin
clk = 1;
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
#2
j0 = 1;
k0 = 1;
end
endmodule
I am getting a error called:
Error (suppressible): (vsim-3053) C:/Modeltech_pe_edu_10.4/examples/syncounter.v(7): Illegal output or inout port connection for port 'q'.
# Time: 0 ns Iteration: 0 Instance: /syncountw/syn1/jk1 File: C:/Modeltech_pe_edu_10.4/examples/jkflip.v
# ** Error (suppressible): (vsim-3053) C:/Modeltech_pe_edu_10.4/examples/syncounter.v(7): Illegal output or inout port connection for port 'qbar'.
# Time: 0 ns Iteration: 0 Instance: /syncountw/syn1/jk1 File: C:/Modeltech_pe_edu_10.4/examples/jkflip.v
# ** Error (suppressible): (vsim-3053) C:/Modeltech_pe_edu_10.4/examples/syncounter.v(9): Illegal output or inout port connection for port 'q'.
# Time: 0 ns Iteration: 0 Instance: /syncountw/syn1/jk2 File: C:/Modeltech_pe_edu_10.4/examples/jkflip.v
# ** Error (suppressible): (vsim-3053) C:/Modeltech_pe_edu_10.4/examples/syncounter.v(9): Illegal output or inout port connection for port 'qbar'.
# Time: 0 ns Iteration: 0 Instance: /syncountw/syn1/jk2 File: C:/Modeltech_pe_edu_10.4/examples/jkflip.v

qa, qb, qabar, & qbbar are declared as reg, they should be wire. The reg type is for signals assigned by procedural blocks (i.e.: initial & always) in the scope of the current module.
var1 is assigned, but never declared.
Change:
reg qa,qb,qabar,qbbar,overflow;
//var1 = qa;
To:
reg overflow;
wire var1;
FYI: you forgot to assign qbar a value

Related

SystemVerilog X propagation issue

I'm having an issue with my SV code. I'm attempting to simulate a carry look ahead adder. However, when I look at my timing results
they show result has having an x propagated, as well as SUM.
Here is my SystemVerilog code
module fulladder (input logic i_bit1, i_bit2, i_carry,
output logic o_sum, o_carry);
assign o_sum = i_bit1 ^ i_bit2 ^ i_carry;
assign o_carry = (i_bit1 & i_bit2) | (i_carry & (i_bit1 ^ i_bit2));
endmodule
module carry_lookahead_adder
#(parameter WIDTH)
(input logic [WIDTH-1:0] i_add1,
input logic [WIDTH-1:0] i_add2,
output logic [WIDTH:0] o_result
);
logic [WIDTH:0] w_C;
logic [WIDTH-1:0] w_G, w_P, w_SUM;
//Generate full adders
genvar i;
generate for (i= 1; i<WIDTH; i++)
begin : f_loop
fulladder fi (
.i_bit1(i_add1[i]),
.i_bit2(i_add2[i]),
.i_carry(w_C[i]),
.o_sum(w_SUM[i]),
.o_carry()
);
end
endgenerate
genvar jj;
generate
for (jj=0; jj<WIDTH; jj++)
begin
assign w_G[jj] = i_add1[jj] & i_add2[jj];
assign w_P[jj] = i_add1[jj] | i_add2[jj];
assign w_C[jj+1] = w_G[jj] | (w_P[jj] & w_C[jj]);
end
endgenerate
assign w_C[0] = 1'b0; //No carry input
assign o_result = {w_C[WIDTH], w_SUM};
endmodule
and the testbench
module carry_lookahead_adder_tb (w_RESULT);
parameter WIDTH = 32;
logic [WIDTH-1:0] r_ADD_1 = 0;
logic [WIDTH-1:0] r_ADD_2 = 0;
output logic [WIDTH:0] w_RESULT;
carry_lookahead_adder #(.WIDTH(WIDTH)) carry_lookahead_inst
(
.i_add1(r_ADD_1),
.i_add2(r_ADD_2),
.o_result(w_RESULT)
);
initial
begin
$dumpfile("dump.vcd");
$dumpvars;
#10;
r_ADD_1 = 32'b00000000000000000000000000000000;
r_ADD_2 = 32'b00000000000000000000000000000001;
#10;
r_ADD_1 = 32'b00000000000000000000000000000010;
r_ADD_2 = 32'b00000000000000000000000000000010;
#10;
r_ADD_1 = 32'b00000000000000000000000000000101;
r_ADD_2 = 32'b00000000000000000000000000000110;
#10;
r_ADD_1 = 32'b00000000100000000000000000000101;
r_ADD_2 = 32'b00000000100000000000000000000110;
#10;
r_ADD_1 = 32'b11111111111111111111111111111111;
r_ADD_2 = 32'b11111111111111111111111111111111;
#10;
r_ADD_1 = 32'b00000000000000000000000000000000;
r_ADD_2 = 32'b00000000000000000000000000000001;
#10;
end
endmodule // carry_lookahead_adder_tb
Can anyone clue me into what may be causing this x? Sorry to post my full code; I'm just lost as to where the problem may be coming from.
Bit [0] of w_SUM is unknown because you are not driving it. Change the generate for loop so that the count starts from 0, not 1. Change:
generate for (i= 1; i<WIDTH; i++)
to:
generate for (i= 0; i<WIDTH; i++)
After this change, the x goes away.
The problem was that the for loop was not generating the right number of fulladder instances: you need 32, but you only got 31. There was no fulladder instance for you to connect w_SUM[0], i_add1[0], etc., to.

Simulation in verilog using $monitor

I've been trying to implement full adder in Verilog. I have implemented it and it is also showing results on Isim. Only problem is that when I try to see the simulation using $monitor command, it is showing me only 1 result, not all simulation results. Here is testbench code:
module Full_adder_s2_testbench;
// Inputs
reg a;
reg b;
reg cin;
// Outputs
wire sum;
wire cout;
// Instantiate the Unit Under Test (UUT)
Full_adder_s2 uut (
.a(a),
.b(b),
.cin(cin),
.sum(sum),
.cout(cout)
);
integer i;
initial begin
// Initialize Inputs
a = 0;
b = 0;
cin = 0;
// Wait 100 ns for global reset to finish
#100;
end
always # ( a, b, cin )
begin
// generate truth table
for ( i = 0; i < 8; i = i + 1 )
// every 10 ns set a, b, and cin to the binary rep. of i
#10 {a, b, cin} = i;
$monitor( "%d ns: a + b + cin = %b + %b + %b = cout sum = %b %b",
$time, a, b, cin, cout, sum );
// stop 10ns after last change of inputs
#10 $stop;
end
endmodule
And here is result in ISIM:
# run 1000 ns
Simulator is doing circuit initialization process.
Finished circuit initialization process.
400 ns: a + b + cin = 1 + 1 + 1 = cout sum = 1 1
Stopped at time : 410 ns : in File "E:/Namal/FYP/My work/XILINX/Full_adder_s2/Full_adder_s2_testbench.v" Line 66
$monitor is only meant to be setup once and will trigger every time a signal changes, try using $display since you already have the statement inside of your always #*.
While learning Verilog I would encourage you to use begin end liberally. The issue is that only 1 line was in the for loop, the $display/$monitor was outside and so only executed once at the start.
always #* begin
// generate truth table
for ( i = 0; i < 8; i = i + 1 ) begin //<-- Added begin
// every 10 ns set a, b, and cin to the binary rep. of i
#10 {a, b, cin} = i;
$display( "%d ns: a + b + cin = %b + %b + %b = cout sum = %b %b", $time, a, b, cin, cout, sum );
end //<--Added end
// stop 10ns after last input
#10 $stop;
end
Full example on EDA Playground.
NB: it is best not to use manual sensitivity lists any more replace always # ( a, b, cin ) with always #*. This will result in quicker refactoring and lowering the chance of RTL to gates simulation mismatch.

Systemverilog assertion to check bad signal transition

I am trying to write an assertion that will fire only if a signal transitions on the rising edge of 'clk'. I wrote below code to test out my ideas
module test();
bit clk, clkb;
int d;
assign clkb = ~clk;
initial begin
clk = 0;
forever #100 clk = ~clk;
end
initial begin
d = 10;
#150 d = 20;
end
sva_d_chgd: assert property (#(posedge clk) $stable(d,#(clkb)))
else $error($psprintf("err: time = %0d, clk = %b, d = %0d", $time, clk, d));
always # (d or clk) begin
$display("time = %0d, clk = %b, d = %0d", $time, clk, d);
if ($time > 200) $finish;
end
endmodule
Above code returns the following output in VCS:
time = 0, clk = 0, d = 10
time = 100, clk = 1, d = 10
"test.vs", 18: test.sva_d_chgd: started at 100s failed at 100s
Offending '$stable(d, #(clkb))'
Error: "test.vs", 18: test.sva_d_chgd: at time 100
err: time = 100, clk = 1, d = 10
time = 150, clk = 1, d = 20
time = 200, clk = 0, d = 20
time = 300, clk = 1, d = 20
$finish called from file "test.vs", line 23.
$finish at simulation time 300
Why did the assertion fire at time 100 when 'd' remained stable until time 150?
In your code, stable checks at every posedge of clk to see if the value of "d" has changed or not between the previous two edges of clkb. Since at the very first posedge of clk there was no previous clkb edge value of "d", stable returns "unknown" instead of "true" or "false" which causes your assertion to fail.
I've added a reset signal to your code and disabled the assertion until after the first posedge of clk. I also moved when "d" changes.
module test();
bit clk, clkb, rst;
int d;
assign clkb = ~clk;
initial begin
clk = 0;
forever #100 clk = ~clk;
end
initial begin
rst = 1;
#150 rst = 0;
end
initial begin
d = 10;
#250 d = 20;
end
sva_d_chgd: assert property (#(posedge clk)
disable iff (rst)
$stable(d,#(clkb)))
else $error($psprintf("err: time = %0d, clk = %b, d = %0d", $time, clk, d));
always # (d or clk) begin
$display("time = %0d, clk = %b, d = %0d", $time, clk, d);
if ($time > 400) $finish;
end
endmodule
Here's the output:
# time = 0, clk = 0, d = 10
# time = 100, clk = 1, d = 10
# time = 200, clk = 0, d = 10
# time = 250, clk = 0, d = 20
# time = 300, clk = 1, d = 20
# ** Error: err: time = 300, clk = 1, d = 20
# Time: 300 ns Started: 300 ns Scope: test.sva_d_chgd File: assert_test.sv Line: 26
# time = 400, clk = 0, d = 20
# time = 500, clk = 1, d = 20
# ** Note: $finish : assert_test.sv(30)
# Time: 500 ns Iteration: 1 Instance: /test
This gets around the first unwanted failure of your assertion but I think the way you coded your assertion it is still not actually trapping the condition you're looking for.

Verilog 'for'-loop returned values

I have written the code below.
My problem:
At index 1
It enters in the for loop with some values. It goes in a 'if' statement and as you can see there the last instruction from every 'if' it is something like 'P=....' .
At index 2 (next step )
It enters in a 'if' statement but the value of P is not from step 1, it is the initial value .
How can I use the last value of 'P' at next step ? (index+1 )
module multiplier(prod, a, b, wireP, wireA, wireS);
output [15:0] prod;
output [16:0] wireA;
output [16:0] wireS;
output [16:0] wireP;
reg [15:0] prod;
input [7:0] a;
input [7:0] b;
reg [16:0] P;
reg [16:0] S;
reg [16:0] A;
wire [16:0] tempshift;
reg [16:0] tempoutshift;
arithmeticShift shiftP(tempshift,P);
wire [16:0] tempPS;
reg [16:0] tempoutPS;
carryForPbooth sumPS(coutPS,tempPS,P,S,0);
wire [16:0]tempPA;
reg [16:0]tempoutPA;
carryForPbooth sumPA(coutPA,tempPA,P,A,0);
reg [16:0] regP;
reg [16:0] regA;
reg [16:0] regS;
integer index;
always #(*) begin
A[16:9] = a[7:0];
A[8:0] = 9'b000000000;
S[16:9] = ~a[7:0]+1'b1;
S[8:0] = 9'b000000000;
P[16:9] = 8'b00000000;
P[8:1] = b[7:0];
P[0] = 1'b0;
#1 tempoutPS = tempPS;
#1 tempoutPA = tempPA;
#1 tempoutshift = tempshift;
for(index = 1; index < 9; index = index + 1) begin
if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
if(P[1:0] == 2'b01) begin
#1 tempoutPA = tempPA;
#1 P = tempoutPA;
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
if(P[1:0] == 2'b10) begin
#1 tempoutPS = tempPS;
#1 P = tempoutPS;
#1 tempoutshift = tempshift;
#1 P = tempoutshift;
end
end
#1 prod=P[16:1];
end
assign wireP = P;
assign wireS = S;
assign wireA = A;
endmodule
It looks like you are trying to create a synthesizable Shift and Add multiplier architecture where the multiply value is calculated over 9 clock cycles.
Looking through the code and removing some temp variables I have reduced it down to:
module multiplier(
input [7:0] a,
input [7:0] b,
output [15:0] prod,
output reg [16:0] A,
output reg [16:0] S,
output reg [16:0] P
);
wire [16:0] tempshift;
arithmeticShift shiftP(tempshift,P);
wire [16:0] tempPS;
carryForPbooth sumPS(coutPS,tempPS,P,S,0);
wire [16:0] tempPA;
carryForPbooth sumPA(coutPA,tempPA,P,A,0);
reg [3:0] index;
always #(*) begin
A = { a, 9'b000000000};
S = { -a, 9'b000000000} ;// -x => ~x+1
P = {8'b00000000, b, 1'b0};
for(index = 1; index < 9; index = index + 1) begin
if((P[1:0] == 2'b00) | (P[1:0] == 2'b11)) begin
#1 P = tempshift;
end
if(P[1:0] == 2'b01) begin
#1 P = tempPA;
#1 P = tempshift;
end
if(P[1:0] == 2'b10) begin
#1 P = tempPS;
#1 P = tempshift;
end
end
end
assign prod = P[16:1];
endmodule
I think you are faking clock cycles using #1, This will only work in the simulator will either not synthesise or only the last assignment will take effect.
If this is meant to be split over 9 clock cycles the it need to have a counter tied to the shift value, not a for loop. In Verilog for loops are unrolled at compilation time and should be executable in zero time, unless used as part of a testbench.
The sections of code similar to the following appear several times.
#1 P = tempPA;
#1 P = tempshift;
I think you are trying to apply a value to a module then capture its output, using the same variable, this is hard to know as I do not have the interfaces for the blocks you have instantiated. You can not do this in Verilog if you want to synthesize your code. You should be using another intermediate variable to connect things up.
Remember that always #* begin ... end is combinatorial logic, and has no timing except the ripple involved in calculating the answer. For implying a D-Type flip-flop we use:
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
// Reset conditions
end
else begin
// Next clock conditions
end
end

Design for assingning output with the counted value of clock on some condition in VHDL

I'm new to VHDL and confused with this design
when Acknwledgement= '1' and clk='1' then
count should be count+1;
and when Acknwledgement= '0' my total counted value of clocks should be assigned to the 'output' and after that resetting count='0' and output='0'.
can anyone help with this.
Thanks in advance.
EDIT:
Code from comment pasted in:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity acknw is
port (acknw : in std_logic;
clk : in std_logic;
output : out integer range 0 to 15);
end acknw;
architecture Behavioral of acknw is
begin
process(clk, acknw) variable c : integer range 0 to 15;
begin
if(clk'event and clk = '1') then
if(acknw = '1') then
c := c+1;
output <= c;
else
c := 0;
output <= c;
end if;
end if;
end process;
end Behavioral;
from your comment it sounds like you want an asynchronous acknw, try something like this:
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity acknw is
port (acknw : in std_logic;
clk : in std_logic;
output : out integer range 0 to 15);
end acknw;
architecture Behavioral of acknw is
begin
process(clk, acknw)
begin
if (acknw = '0') then
output <= 0;
elsif rising_edge(clk) then
-- rollover
if (output /= 15) then
output <= output + 1;
else
output <= 0;
end if;
end if;
end process;
end Behavioral;