2 Bit Counter using JK Flip Flop in Verilog - counter

I'm writing verilog code of 2 Bit Counter using JK Flip Flop that counts 0-3 and back to 0. I'm using Xilinx EDA. However I'm keep getting one error and I don't know what it means? The line numbers doesn't show up here, but error is located at "always #(posedge clk)".
ERROR:HDLCompiler:1401 - "C:\Users\Eduardo\Documents\SFSU\Fall 2014\Engr 378\Lab 3\TwoBitCounter\twobitcounter.v" Line 30: Signal q in unit jkff is connected to following multiple drivers:
`timescale 1ns / 1ps
module twobitcounter( q_out, qbar_out, j,k, clk, reset);
input [1:0] j; input [1:0] k; input clk; input reset;
output [1:0] q_out;
output [1:0] qbar_out;
wire [1:0] q_out;
wire [1:0] qbar_out;
wire clk;
assign qbar_out[0] = ~q_out[0];
assign j[0] = 1;
assign k[0] = 1;
assign j[1] = q_out[0];
assign k[1] = q_out[0];
jkff M1(q_out[0], qbar_out[0], j[0], k[0], clk, reset);
jkff M2(q_out[1], qbar_out[1], j[1], k[1], qbar_out[0]);
endmodule
module jkff(output q_out, output qbar_out,
input j, input k, input clk, input reset);
reg q;
assign q_out = q;
assign qbar_out = ~q;
initial begin
q = 1'b0;
end
always #(posedge clk)
begin
case({j,k})
{1'b0, 1'b0}: begin
q = q;
end
{1'b0, 1'b1}: begin
q = 1'b0;
end
{1'b1, 1'b0}: begin
q = 1'b1;
end
{1'b1, 1'b1}: begin
q = ~q;
end
endcase
end
always #(posedge reset)
begin
q = 1'b0;
end
endmodule

The issue is q is being set in two always blocks, which is not allowed in synthesis. Merge the two always blocks. Also, q is a flop, so it should be assigned using non-blocking assignment (<=), not blocking assignment (=).
always #(posedge clk or posedge reset)
begin
if (reset == 1'b1) begin
q <= 1'b0;
end
else begin
case({j,k})
{1'b0, 1'b0}: begin
q <= q;
end
{1'b0, 1'b1}: begin
q <= 1'b0;
end
{1'b1, 1'b0}: begin
q <= 1'b1;
end
{1'b1, 1'b1}: begin
q <= ~q;
end
endcase
end
end
You should almost never use initial blocks in synthesizable code. Most FPGAs allow it for initialization. ASICs designs however do not support it. For both cases, if there is an asynchronous reset/set then it initial block shouldn't be used.

The error is telling you that you are assigning q in different blocks. This creates an error. You are assigning q in both your initial block and your always block.
You should never use initial blocks in synthesizable code.

Related

How to pass a reference array of variables to task?

I am trying to pass a reference array of variables. It works fine with a reference to variable, but not with an array of variables. The goal with the task is to be able to take an array of variables, and read them on every clock edge.
So this code does not work
module tb;
logic clock = 0;
logic a = 0;
logic b = 0;
task automatic read_vars(ref logic clock, input int clock_edges = 10,
const ref logic signal_array[]);
repeat (clock_edges) begin
#(posedge clock) $display("#TIME: %t Clock edge", $time);
for (int i = 0; i < signal_array.size(); i++) begin
$display("Variable %0d: %0b", i, signal_array[i]);
end
end
endtask
always begin
#1 clock = 1;
#1 clock = 0;
end
always begin
#3 b = 1;
#3 b = 0;
end
always begin
#7 a = 1;
#7 a = 0;
end
initial begin
fork
read_vars(.clock(clock), .signal_array({a, b}));
join_none
#1000;
$finish();
end
endmodule
I get the following error
read_vars(.clock(clock), .signal_array({a, b}));
|
xmvlog: *E,BADRFA (tb.sv,25|45): invalid ref argument usage because actual argument is not a variable. [SystemVerilog].
module worklib.tb:sv
But this code works.
module tb;
logic clock = 0;
logic a = 0;
logic b = 0;
task automatic read_vars(ref logic clock, ref logic a, ref logic b, input int clock_edges = 10);
repeat (clock_edges) begin
#(posedge clock) begin
$display("#TIME: %t Clock edge", $time);
$display("a = %b ", a);
$display("b = %b ", b);
end
end
endtask
always begin
#1 clock = 1;
#1 clock = 0;
end
always begin
#3 b = 1;
#3 b = 0;
end
always begin
#7 a = 1;
#7 a = 0;
end
initial begin
fork
read_vars(.clock(clock), .a(a), .b(b));
join_none
#1000;
$finish();
end
endmodule
What you are trying to do is impossible in verilog.
First of all, having a reference to an array will not help in solving the issue. Arrays contain values of something. So creation of an array with {a,b} will just copy values of the variables into the array and updating variables will not be reflected in any case.
What you are after is an array of references to variables, which is impossible in a verilog.
However, class variables are always reference. So, you can wrap your vars in a class in test bench. Here is a modified example of yours:
class V;
logic val;
endclass:V
module tb;
V a = new;
V b = new;
V arr[] = '{a, b};
logic clock = 0;
//logic a = 0;
//logic b = 0;
task automatic read_vars(ref logic clock, input int clock_edges = 10,
V signal_array[]);
repeat (clock_edges) begin
#(posedge clock) $display("#TIME: %t Clock edge", $time);
for (int i = 0; i < signal_array.size(); i++) begin
$display("Variable %0d: %0b", i, signal_array[i].val);
end
end
endtask
always begin
#1 clock = 1;
#1 clock = 0;
end
always begin
#3 b.val = 1;
#3 b.val = 0;
end
always begin
#7 a.val = 1;
#7 a.val = 0;
end
initial begin
fork
read_vars(.clock(clock), .signal_array(arr));
join_none
#1000;
$finish();
end
endmodule

Implementation of wait statement inside a fork join block

what modification is needed to display i value =5,2,7? I am not getting output. Any suggestion will be helpful.
module tb#(int T=8);
bit [8:0] abc;
initial
begin
for(int i=0; i<T; i++)
begin
fork
begin
wait(abc[i] == 1'b1);
$display(i,$time);
end
join_none
end
end
initial
begin
abc[5] = 1'b1;
#10 abc[2] = 1'b1;
abc[7] = 1'b1;
end
endmodule
https://www.edaplayground.com/x/JUZR
There is only one instance of the variable i and it's value is 8 by the point in time that the process begins. You need to declare a variable k that has a different value for each iteration of the loop.
module tb#(int T=8);
bit [8:0] abc;
initial
begin
for(int i=0; i<T; i++)
begin
automatic int k = i;
fork
begin
wait(abc[k] == 1'b1);
$display(i,k,,,$time);
end
join_none
end
end
initial
begin
abc[5] = 1'b1;
#10 abc[2] = 1'b1;
abc[7] = 1'b1;
end
endmodule
See https://verificationacademy.com/forums/systemverilog/fork-joinnone-inside-loop

Modeling skewed delay for combinational logic

I need help to model a block with different delays for various input-output paths?
input A;
input [3:0] B, C;
output [3:0] Y;
Y = B xor C if A = 1 else Y = 0
with A->Y delay of 10us when posedge A (rise delay) and 5us when negedge A(fall delay)
and B,C - > Y delay is 1us (applicable only if A = 1)
For my case, I might need to use procedural way and assign statements might not suit.
Here is something that worked best for me.
`timescale 1us/1ns
module xor_w_enabled(input A, input B, input C, output Y);
wire A_delayed;
wire B_xor_C_delayed;
assign #1 B_xor_C_delayed = B^C;
assign #(10,5) A_delayed = A;
assign Y = (A_delayed == 1) ? B_xor_C_delayed : 0;
endmodule
Please let me know if I'm missing anything.
For non-synthesizable models you can use #delay constructs combined with `timescale to model delays. something like the following code
`timescale 1us/1us
module delayModule(A,B,C,Y);
input A;
input [3:0] B, C; // this should probably be output
output [3:0] Y;
reg [3:0] tmpb, tmpy;
always #(posedge A)
#10us tmpb <= 1;
always #(negedge A)
#5us tmpb <= 0;
always #* begin
if (A == 1)
#1us tmpy =(B^C);
end
assign B = tmpb;
assign Y = tmpy;
endmodule // delayModule

How to change and manipulate clock in SystemVerilog

I'm trying to manipulate my clock by using my own clock divider module.
module clockDivider(input logic input0,
input logic input1,
input logic clock,
output logic y);
// 00 = stop, 01 = slow, 10 = medium, 11 = fast;
if( ~input1 & ~input0 ) /*stop clock*/ ;
else if( ~input1 & input0 ) /*slow*/ ;
else if( input1 & ~input0 ) /*medium*/ ;
else if( input1 & input0 ) /*fast*/ ;
endmodule
As you can see above, according to my inputs, I will manipulate my clock and then let the step motor which is located in our FPGA board. But I couldn't figure out how to do it.
And also is there any website other than doulos? I think it is not really clear and contains just a small amount of information about System Verilog.
Thanks
You can directly having a modulo N counter to divide frequency by N.
Suppose here is your all 3 types of clock.
00 - No Clock
01 - Clock/4
02 - Clock/2
03 - Clock
Here is the code for it. Please note that its a conceptual code and not verified.
module clockDivider(input logic input0,
input logic input1,
input logic clock,
input logic reset,
output logic y);
// 00 = stop, 01 = slow, 10 = medium, 11 = fast;
parameter mod = 2;
reg [mod-1:0] count, max;
assign y = ( ~input1 & ~input0 ) ? 1'b0 : count[mod-1]; /*stop clock*/
always # (posedge clock)
begin
if( ~input1 & input0 ) /*slow*/
max <= (1 << (mod-2)) - 1'b1;
else if( input1 & ~input0 ) /*medium*/
max <= (1 << (mod-1)) - 1'b1;
else if( input1 & input0 ) /*fast*/
max <= (1 << mod) - 1'b1;
end
always # (posedge clock, negedge reset)
begin
if (!reset)
count <= 0;
else if (count == max)
count <= 0;
else
count <= count + 1'b1;
end
endmodule
By slow, medium and fast, I am going to assume that the fastest you are expecting by this logic is the speed of clock itself i.e you are implementing a clock divider.
I have assumed the following:
slow = 0.25*clock
medium = 0.5*clock
fast = clock
module clockDivider(input logic reset,
input logic input0,
input logic input1,
input logic clock,
output logic y);
// 00 = stop, 01 = slow, 10 = medium, 11 = fast;
logic delayed_y;
logic delayed_delayed_y;
logic [1:0] counter;
always #(posedge clock) begin
if (reset) begin
counter <= 'h0;
end
else begin
counter <= counter+1'b1;
end
end
always #(posedge clock) begin
if (reset) begin
delayed_y <= 1'b0;
end
else begin
delayed_y <= counter[0];
end
end
always #(posedge clock) begin
if (reset) begin
delayed_delayed_y <= 1'b0;
end
else begin
delayed_delayed_y <= counter[1];
end
end
always #(*) begin
if (reset) begin
y = 1'b0;
end
else begin
/*stop clock*/
if( ~input1 & ~input0 ) begin
y = 1'b0;
end
/*slow*/
else if( ~input1 & input0 ) begin
y = delayed_delayed_y;
end
/* medium*/
else if( input1 & ~input0 ) begin
y = delayed_y;
end
/* fast */
else if( input1 & input0 ) begin
y = clock;
end
end
end
endmodule
You can find a working example here: https://www.edaplayground.com/x/5J75
Note: If you are looking to multiply the clock, you need to use the DCM on your target FPGA. There is another method as well with a 2-input XOR gate and a clock buffer but I would stick to the DCM.

DRDY signal in Verilog

in my recent CPLD design I implemented a frequency counter with an SPI slave interface. The SPI master MCU reads out the counter after it is signalled by a DRDY pin. My counter updates the DRDY signal by flipping it (DRDY <=~DRDY) but it requires both edges pin interrupt sensitivity at the MCU side. I'd like to implement it more universally, like the typical ADC chip data ready signal behaviour, which is: a rising edge, held for x clocks then a falling edge. I thought it should be easy however I stucked in conditional loops as a beginner in Verilog.
Here is my code so far:
module ec2(INP, RST, SR, DRDY, DRDY2, DRDY3);
input INP, RST, SR;
output reg DRDY2, DRDY3;//LEDs for verification/testing purposes
output reg DRDY;
reg [23:0] Q;
event data_ready;
always #(posedge INP or negedge RST)
begin
if(!RST)
begin
Q <= 24'd0;
end
else if( (Q == 24'd1000000 && SR) || (Q == 24'd500000 && !SR))
begin
Q <= 24'd0;
->data_ready;
DRDY2 <=~DRDY2;
end
else
begin
Q <= Q + 1;
end
end
always #(data_ready)
begin
DRDY=1'b1;
//wait for 10ms?
DRDY=1'b0;
DRDY3 = DRDY2;
end
endmodule
Events are not synthesizable, you should convert data_ready into a signal (reg). A second counter which triggers DRDY at data_ready assertion would do the trick:
always #(posedge INP or negedge RST)
begin
if (RST)
begin
DRDY <= 1'b0;
drdy_count <= 4'd0;
end
else
begin
if (~DRDY && data_ready)
begin
DRDY <= 1'b1;
drdy_count <= 4'd0;
end
else if (DRDY)
begin
drdy_count <= drdy_count + 1;
if (drdy_count == 15)
DRDY <= 1'b0;
end
end
end