I'm trying to build an JK FF with Async low active clear and preset. However verilog is giving me " design.sv:24: syntax error I give up." It looks like I have an error somewhere but I can't find it.
I would appreciate every help
This is my design code
module JKFF(clk,J,K,Q,Qbar,Clear,Preset);
input J,K,clk,Clear;
output Q, Qbar;
reg Q;
assign Qbar= ~Q;
always#(negedge clk or negedge Clear or negedge Preset )
begin
if(!Clear)
Q<=1'b0;
else if(!Preset)
Q<=1'b1;
else if(Clear==1&&Preset==1)
if (K==0 && J==0)
Q <= Q;
if (K==1 && J==0)
Q <= 0;
if (K==0 && J==1)
Q <= 1;
else
Q <= ~Q;
end
endmodule;
This is my TB code
module JKFF_tb;
// Inputs
reg J;
reg K;
reg clk;
reg Clear;
// Outputs
wire Q;
wire Qbar;
// Instantiate the Unit Under Test (UUT)
JKFF uut (
.Q(Q),
.Qbar(Qbar),
.J(J),
.K(K),
.clk(clk),
.Clear(Clear)
);
initial begin
clk=0;
Clear=1;
Preset=1;
forever #10 clk = ~clk;
end
initial begin
J= 1; K= 0;
#100; J= 0; K= 1;
#100; J= 0; K= 0;
#100; J= 1; K=1;
end
// Add stimulus here
endmodule
You don't declare Preset in module JKFF input list.
You typo semicolon ; after endmodule keyword.
You don't have code inside begin and end after else if(Clear==1&&Preset==1)
You don't have else if in J and K conditions.
In module JKFF_tb you don't declare Preset reg and you assign value to it.
You don't pass Preset to JKFF module instance named uut.
module JKFF(clk,J,K,Q,Qbar,Clear,Preset);
input J,K,clk,Clear, Preset;
output Q, Qbar;
reg Q;
assign Qbar= ~Q;
always#(negedge clk or negedge Clear or negedge Preset )
begin
if(!Clear)
Q<=1'b0;
else if(!Preset)
Q<=1'b1;
else if(Clear==1&&Preset==1) begin
if (K==0 && J==0)
Q <= Q;
else if (K==1 && J==0)
Q <= 0;
else if (K==0 && J==1)
Q <= 1;
else
Q <= ~Q;
end
end
endmodule
module JKFF_tb;
// Inputs
reg J;
reg K;
reg Preset;
reg clk;
reg Clear;
// Outputs
wire Q;
wire Qbar;
// Instantiate the Unit Under Test (UUT)
JKFF uut (
.Q(Q),
.Qbar(Qbar),
.J(J),
.K(K),
.clk(clk),
.Clear(Clear),
.Preset(Preset)
);
initial begin
clk=0;
Clear=1;
Preset=1;
forever #10 clk = ~clk;
end
initial begin
J= 1; K= 0;
#100; J= 0; K= 1;
#100; J= 0; K= 0;
#100; J= 1; K=1;
end
// Add stimulus here
endmodule
Related
This is the verilog code for mod 64 counter, incrementing every clock cycle
module modulus64counter
#(parameter N=64,
parameter WIDTH=5)
(input clk,
input rstn,
output reg[WIDTH-1:0] out);
integer i;
always #(posedge clk) begin
if(!rstn) begin
out<=0;
end
else begin
if(out==N-1)
out<=0;
else
out<= out+1;
end
end
endmodule
and the test bench is
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [4:0] out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=0X%h", $time,rstn,out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(50) #(posedge clk);
$finish;
end
endmodule
Now if i want to increment the value of out every "n" clock cycle instead of consecutive clock cycle , how can i modify the program
Kindly help
Updated 20220131
Updated the code to produce output after every 2 clock cycles. Similarly, if you wish to delay for even more clock cycle, the simplest way is to continuously flopping it.
For a better implementation, you can try out a shift register.
module modulus64counter #(
parameter N=64,
parameter WIDTH=8,
parameter DELAY_CYCLE=2
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
reg [WIDTH-1:0] dly1clk;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
dly1clk <= 0;
end else if(out == DELAY_CYCLE-1) begin
out <= 0;
dly1clk <= dly1clk + 1;
end else begin
out <= out + 1;
end
end
always #(posedge clk) begin
if(!rstn) begin
actual_out <= 0;
end else begin
actual_out <= dly1clk;
end
end
endmodule
The code below should work for you. You can always swap the out and actual_out if you insist on using out as the final counting variable.
Also, removing the out on the monitor line in the testbench will only print the value when it reaches mod n. I kept both out and actual_out on testbench's monitor to ease debugging purpose.
Verilog code
module modulus64counter #(
parameter N=64,
parameter WIDTH=8
)(
input clk,
input rstn,
output reg[WIDTH-1:0] out,
output reg[WIDTH-1:0] actual_out
);
integer i;
reg [WIDTH-1:0] cntr;
always #(posedge clk) begin
if(!rstn) begin
out <= 0;
actual_out <= 0;
end else if(out == N-1) begin
out <= 0;
actual_out <= actual_out + 1;
end else begin
out <= out + 1;
end
end
endmodule
Testbench
module modulus64countertb;
// Inputs
reg clk;
reg rstn;
// Outputs
wire [7:0] out;
wire [7:0] actual_out;
// Instantiate the Unit Under Test (UUT)
modulus64counter uut (
.clk(clk),
.rstn(rstn),
.out(out),
.actual_out(actual_out)
);
always #10 clk = ~clk;
initial begin
// Initialize Inputs
clk = 1;
rstn = 0;
$monitor ("T=%0t rstn=%0b out=%d actual_out=%d", $time,rstn,out,actual_out);
repeat(2) #(posedge clk);
rstn <=1;
repeat(200) #(posedge clk);
$finish;
end
endmodule
Output result simulated using edaplayground:
I have a d flip flop tutorial, and when I try to compile, some errors occur. I've taken this tutorial from technobyte.org, and anything changed, but it doesn't work. D Flip Flop and Test Bench Code is below.
Can you find the problem?
D Flip Flop
module D_Flip_Flop(d,clk,clear,q,qbar);
input d, clk, clear;
output reg q, qbar;
always#(posedge clk)
begin
if(clear== 1)
q <= 0;
qbar <= 1;
else
q <= d;
qbar = !d;
end
endmodule
Test Bench for D Flip Flop
//test bench for d flip flop
//1. Declare module and ports
module dff_test;
reg D, CLK,reset;
wire Q, QBAR;
//2. Instantiate the module we want to test. We have instantiated the dff_behavior
D_Flip_Flop dut(.q(Q), .qbar(QBAR), .clear(reset), .d(D), .clk(CLK)); // instantiation by port name.
//3. Monitor TB ports
$monitor("simtime = %g, CLK = %b, D = %b,reset = %b, Q = %b, QBAR = %b", $time, CLK, D, reset, Q, QBAR);
//4. apply test vectors
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
reset=1; D <= 0;
#100; reset=0; D <= 1;
#100; D <= 0;
#100; D <= 1;
end
endmodule
Errors
There are 3 types of syntax errors in your code:
You need begin/end around multiple statements in your if/else.
The $monitor statement should be inside an initial block.
Verilog is case-sensitive. clk was not declared. Change all CLK to clk.
You should report these errors to the person who created that tutorial.
Here is code that compiles cleanly for me. I also added proper indentation to your DFF:
module D_Flip_Flop(d,clk,clear,q,qbar);
input d, clk, clear;
output reg q, qbar;
always#(posedge clk) begin
if(clear== 1) begin
q <= 0;
qbar <= 1;
end else begin
q <= d;
qbar = !d;
end
end
endmodule
module dff_test;
reg D, clk,reset;
wire Q, QBAR;
//2. Instantiate the module we want to test. We have instantiated the dff_behavior
D_Flip_Flop dut(.q(Q), .qbar(QBAR), .clear(reset), .d(D), .clk(clk)); // instantiation by port name.
//3. Monitor TB ports
initial $monitor("simtime = %g, clk = %b, D = %b,reset = %b, Q = %b, QBAR = %b", $time, clk, D, reset, Q, QBAR);
//4. apply test vectors
initial begin
clk=0;
forever #10 clk = ~clk;
end
initial begin
reset=1; D <= 0;
#100; reset=0; D <= 1;
#100; D <= 0;
#100; D <= 1;
end
endmodule
Good coding practice recommends using nonblocking assignments for sequential logic. Change:
qbar = !d;
to
qbar <= !d;
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
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,
Our assignment is to build a rudimentary single-cycle CPU in Verilog, but I'm not getting even more fundamental modules of it correct. For instance, to test the Instruction Memory module, we've been given a text file "hw3Test.txt" with instructions in hex, and I'm trying to slurp that into the IM.
00221820
AC010000
8C240000
10210001
00001820
00411822
When I run a testbench, I see that the only instructions that get into memory are the second, third, and fourth lines. Here's the IM module:
module IM(addr, clk, inst);
input [31:0] addr;
input clk;
output reg [31:0] inst;
reg [31:0] mem [255:0];
initial begin
$readmemh("hw3Test.txt", mem);
end
always #( posedge clk) begin
inst=mem[addr[31:2]];
end
endmodule
And the testbench:
module imtest;
// Inputs
reg [31:0] addr;
reg clk;
// Outputs
wire [31:0] inst;
// Instantiate the Unit Under Test (UUT)
IM uut (
.addr(addr),
.clk(clk),
.inst(inst)
);
initial begin
// Initialize Inputs
addr = 0;
clk = 0;
// Wait 100 ns for global reset to finish
#100;
// Add stimulus here
clk = 0;
addr = 0;
#100;
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
end
endmodule
I'm also not sure I'm even getting the PC-to-IM module correct, because aside from the initialized values, everything but the rst and clk signals show no valid values. Can anyone point out where I'm going wrong?
module pc_im(
// Inputs
rst, clk, PCin,
// Outputs
inst, PCout
);
input clk, rst;
input [31:0] PCin;
output reg [31:0] inst;
output reg [31:0] PCout;
PC mypc (
.clk(clk),
.rst(rst),
.PCin(PCin),
.PCout(PCout)
);
IM myim(
.clk(clk),
.addr(PCout),
.inst(inst)
);
endmodule
Here's the PC.v module:
module PC(rst, clk, PCin, PCout);
input clk, rst;
input [31:0] PCin;
output reg [31:0] PCout;
always #(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
endmodule
And finally, the testbench:
module pcimtest;
// Inputs
reg rst;
reg clk;
reg [31:0] PCin;
// Outputs
wire [31:0] inst;
wire [31:0] PCout;
// Instantiate the Unit Under Test (UUT)
pc_im uut (
.rst(rst),
.clk(clk),
.PCin(PCin),
// Outputs
.inst(inst),
.PCout(PCout)
);
initial begin
// Initialize Inputs
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
rst = 0;
forever begin
#100;
clk <= ~clk;
PCin <= PCout;
end
// Add stimulus here
end
endmodule
Here are a few things that look suspect.
Problem 1
It is normally good to use non-blocking assignments in blocks intended to infer registers.
i.e. change
always #( posedge clk) begin
inst=mem[addr[31:2]];
end
to
always #( posedge clk) begin
inst<=mem[addr[31:2]];
end
Problem 2
You are changing signals twice per clock cycle, once on negative edge and once on positive edge.
Change:
forever begin
#20;
clk = ~clk;
addr = addr + 4;
end
to
forever begin
#20;
clk = 1;
#20;
clk = 0;
addr = addr + 4;
end
Problem 3
You are using synchronous resets but not supplying a clock during reset.
Consider the code
always #(posedge clk) begin
if (rst) PCout <= 0;
else PCout <= PCin + 4;
end
This block will only activate on positive clock edges. However, you make reset high while the clock is paused so no reset will happen.
Change
rst = 1;
clk = 0;
PCin = 0;
// Wait 100 ns for global reset to finish
#100;
to
rst = 1;
clk = 0;
PCin = 0;
#20
clk = 1;
#20
clk = 0;
// Wait 100 ns for global reset to finish
#100;