Why is the following clock multiplication Verilog code not working for me? - verilog

I am trying to generate a clock which is (3/16) of the system clock. So, I have decided to generate a 3x clock from the system clk and then (1/16)x clock from that.
Right now, I am stuck at generating just the 3x clock. I am doing this by calculating the time period of the system clock and then toggling the 3x clock every 1/6th of that period. But my simulation just stalls forever with that. I have not used the forever block anywhere, I have checked. Hence no timing construct.
Following is the code that I am working on.
module eec_clk_gen (
input logic arst,
input logic sys_clk,
output logic eec_clk
);
real t0;
real t1;
real sys_clk_tp;
logic eec_clk_x3;
//Calculating clock period of sys_clk
initial
begin
#(posedge sys_clk) t0 = $realtime;
#(posedge sys_clk) t1 = $realtime;
sys_clk_tp = t1 - t0;
end
//Generating clock at 3 times sys_clk freq
initial
begin
#(posedge sys_clk) eec_clk_x3 = 1'b1;
end
always
begin
#(sys_clk_tp/6) eec_clk_x3 <= ~eec_clk_x3;
end
endmodule: eec_clk_gen
I am not concerned about the arst signal which is missing from my code. It will be implemented once the eec_clk is functional.
Some help please?

There 2, possibly 3 problems with your code.
The initial value of sys_clk_tp is 0.0. So your always block goes into an infinite 0-delay loop. Time cannot advance
You are using non-blocking assignment to t1,t2, so t2 is still 0 when evaluating t1-t2
You are using $time instead of $realtime If your input clock has any fractional delay due to different timescales, $time truncates.
I would do
`
initial
begin
#(posedge sys_clk) t0 = $realtime;
#(posedge sys_clk) t1 = $realtime;
sys_clk_tp = t1 - t0;
forever #(sys_clk_tp/6) eec_clk_x3 = ~eec_clk_x3;
end

What you are trying to do is futile. Even if you manage to get this to work in simulation, it will never synthesize:
The $realtime function is only available in simulation. It is not available in synthesis; if you need a real-time clock, you will need to make your own.
The # operator is only effective in simulation. It is ignored during synthesis.
If you want to multiply a clock signal on an FPGA, most FPGAs have clock management hard macros (typically DLLs or PLLs) which can be used for this purpose. Consult your target part's reference manual for details.
If you are targeting an ASIC, contact your foundry.

Related

I need to generate waveform as shown. in verilog code

I need to generate a waveform, as shown in the image. But with my code, I did not get expected waveform
In the design, part got the last and valid values in a random period from test-bench.
my problem is why the I value incremented at valid not equal to one
Design code:
module design_d(clk,valid,last,data);
input clk,valid,last;
output reg [7:0] data;
reg [7:0] i;
initial
begin
data=0;
i=0;
end
always #(posedge clk,valid)
begin
if (valid)
begin
data<=i;
i=i+1;
$display("i=%d data=%d ",i,data);
end
else
begin
data <=8'bz;
end
end
endmodule
Test bench code:
module test;
reg clk,valid,last;
wire [7:0] data;
parameter clk_period=2;
design_d dut(clk,valid,last,data);
initial
begin
clk=1;
valid=1;
last=0;
end
always #(clk_period/2) clk=~clk;
always #(posedge clk)
begin
last=0;
#4 last=1;
#clk_period last=0;
#8 last=1;
#clk_period last=0;
#10 last=1;
#clk_period last=0;
#16last=1;
#clk_period last=0;
#20 last=1;
#clk_period last=0;
end
always #(posedge clk or last)
begin
valid<=1;
wait(last==1)
#clk_period;
valid<=0;
#clk_period;
valid<=1;
end
initial
begin
$dumpfile("dump.vcd");
$dumpvars(1);
#24 $finish;
end
endmodule
It seems you have difficulties with the English language, which is not your fault but because of that, I may interpret your question wrongly.
You have a waveform of what you need to achieve. This to me suggest that this is a school assignment and therefore I will treat it that way. This means I will **not* give you a complete answer but give you pointers about where you are going wrong. (This should all be in a comment but there is now way it would fit).
...got the last and valid values in a random period from test-bench.
First thing to realize is writing a test-bench is just as difficult, if not more difficult then writing the RTL code itself.
In your test-bench You are using always #(posedge clk) but inside that section you use #... statements. That by itself is not wrong. Dangerous, yes, but not necessary wrong.
But
Your clock has a time period of 2 (parameter clk_period=2;) and inside your posedge clock you use delays which are equal or bigger then the clock period. That often leads to a disaster, as you have found out.
Read up on how Verilog works, especially when the sensitivity list always #... is used: It is not triggered until all statement in the section have been dealt with. In your case it means the that it will takes several clock edges until the always block is started again.
Test Bench
I don't know what the assignment was so I'll use the waveform you have given.
As last and valid are inputs to you module I will give you pointers how to make those.
valid is high for 4 clock cycles, it is then low for one clock cycle, after which it repeats itself. This means you need a pattern which repeats itself every 5 clock cycles and thus you need to make a counter which counts 0,1,2,3,4,0,1,2,3,4,...
You should not make that using #..... statements. You should use the test bench clock and make a counter which counts!
Making a counter which counts as described above is the first thing you need to learn in HDL! You will find that you have to do that over and over and over and over .. In every piece of RTL code and every test bench.
Modulo 5 counter.
I prefer for all my modules and my test benches to have a reset.
If only that it allows me to start a new test from a known state.
reg [2:0] counter;
always #(posedge clk or negedge reset_n)
begin
if (reset_n)
counter <= ...
else // clocked section
begin
if (..)
counter <= ...
else
counter <= ...
end
end
Start fresh and get the above code running first. Observe that the counter is indeed running 0,1 2, 3, 4, 0, .. before you continue.
Derived signals .
Next learn to derive signals from that.
Basic rule: in a clocked section, if you need a signal at counter value X you have to generate that at cycle X-1.
Thus to make last high when the counter is 3 you have to set that up when the counter is 2:
always #(posedge clk...
...
if (counter==3'h2)
last <= 1'b1;
else
last <= 1'b0;
I leave making the valid to you.
Once you got your test bench running start working on your design_d module.
Some tips:
Use always non-blocking assignments <= in your clocked section. **
Do NOT use a clock period of 2, use 100 or 1000. You will find out in due time why that is better.
Do not use always #(posedge clk or [one or more signals] ) unless as per my example. **
Take care of your indenting. I had to do some mayor editing on your code.
**Sorry I can't go into details why that is good practice most of the time as that would triple the size of this answer. For now please follow the tips.
I could have written the actual code in a tenth of the time it took me to write all that so I hope you will not delete the question as others may profit from it.

Verilog race with clock divider using flops

I made a basic example on eda playground of the issue I got.
Let s say I have two clocks 1x and 2x. 2x is divided from 1x using flop divider.
I have two registers a and b. a is clocked on 1x, b is clocked in 2x.
b is sampling value of a.
When we have rising edge of 1x and 2x clocks, b is not taking the expected value of a but it s taking the next cycle value.
This is because of this clock divider scheme, if we make division using icgs and en it works fine.
But is there a way to make it work using this clock divider scheme with flops ?
EDA playground link : https://www.edaplayground.com/x/map#
module race_test;
logic clk1x = 0;
logic clk2x = 0;
always
#5ns clk1x = !clk1x;
int a, b;
always #(posedge clk1x) begin
a <= a+1;
clk2x <= !clk2x;
end
// Problem here is that b will sample postpone value of a
// clk2x is not triggering at the same time than clk1x but a bit later
// This can be workaround by putting blocking assignment for clock divider
always #(posedge clk2x) begin
b <= a;
end
initial begin
$dumpfile("test.vcd");
$dumpvars;
#1us
$stop;
end
endmodule
Digital clock dividers present problems with both simulation and physical timing.
Verilog's non-blocking assignment operator assumes that everyone reading and writing the same variables are synchronized to the same clock event. By using an NBA writing to clk2x, you have shifted the reading of a to another delta time*, and as you discovered, a has already been updated.
In real hardware, there are considerable propagation delays that usually avoid this situation. However, you are using the same D-flop to assign to clk2x, so there will be propagation delays there as well. You last always block now represents a clock domain crossing issue. So depending on the skews between the two clocks, you could still have a race condition.
One way of correcting this is using a clock generator module with an even higher frequency clock
always #2.5ns clk = !clk;
always #(posedge clk) begin
clk1x <= !clk1x;
if (clk1x == 1)
clk2x = !clk2x;
Of course you have solved this problem, but I think there is a better way.
The book says one can use blocking assignment to avoid race. But blocking assignemnt causes errors in synopsys lint check. So, one way to avoid race problem without lint error is to use dummy logic, like this
wire [31:0] a_logic;
wire dummy_sel;
assign dummy_sel = 1'b0;
assign a_logic = dummy_sel ? ~a : a;
always #(posedge clk2x) begin
b <= a_logic;
end

How to give a delay of 1 clock cycle in a combinational block verilog

I have a combinational code that I have, In that code I would like to turn off a signal after 1 clock cycle, i.e. initially it is 1, and after one clock cycle it should be 0. Is there any way I can do it and if possible it should be able to synthesize on an FPGA.
The code is as follows:
always#(ao or bo or co or dod or eo or fo or go or ho)
begin
temp_out = {ho,go,fo,eo,dod,co,bo,ao};
out_flag = 1;
//after one clock cycle it should go to 0 ;
//help is required over here
out_flag = 0;
end
You cannot do it in a pure combinational synthesizable manner. You need a flop (which is synthesizable) and a reset to set the signal to a know value, say to 0. So, you can delay 1 clock cycle after reset as the following:
always #(posedge clk) begin
if (reset)
out_flag <= 0;
else
out_flag <= 1;
end
you need to figure out exact timing and use correct number of flops for you particular situation. You might want to have an asynchronous reset versus synchronous as in the above example.

How to generate delay in verilog for synthesis?

I Want to Design a Verilog code for Interfacing 16*2 LCD. As in LCD's to give "command" or "data" we have to give LCD's Enable pin a "High to low Pulse " pulse that means
**E=1;
Delay();//Must be 450ns wide delay
E=0;**
This the place where I confuse I means in Verilog for synthesis # are not allowed so how can I give delay here I attached my code below. It must be noted that I try give delay in my code but I think delay not work so please help me to get rid of this delay problem......
///////////////////////////////////////////////////////////////////////////////////
////////////////////LCD Interfacing with Xilinx FPGA///////////////////////////////
////////////////////Important code for 16*2/1 LCDs/////////////////////////////////
//////////////////Coder-Shrikant Vaishnav(M.Tech VLSI)/////////////////////////////
///////////////////////////////////////////////////////////////////////////////////
module lcd_fpgashri(output reg [7:0]data,output reg enb,output reg rs,output reg rw ,input CLK);
reg [15:0]hold;
reg [13:0]count=0;
//Code Starts from here like C's Main......
always#(posedge CLK)
begin
count=count+1; //For Delay
//For LCD Initialization
lcd_cmd(8'b00111000);
lcd_cmd(8'b00000001);
lcd_cmd(8'b00000110);
lcd_cmd(8'b00001100);
//This is a String "SHRI" that I want to display
lcd_data(8'b01010011);//S
lcd_data(8'b01001000);//H
lcd_data(8'b01010010);//R
lcd_data(8'b01001001);//I
end
//Task For Command
task lcd_cmd(input reg [7:0]value);
begin
data=value;
rs=1'b0;
rw=1'b0;
enb=1'b1; //sending high to low pulse
hold=count[13]; //This is the place where I try to design delay
enb=1'b0;
end
endtask
//Task for Data
task lcd_data(input reg [7:0]value1);
begin
data=value1;
rs=1'b1;
rw=1'b0;
enb=1'b1; //sending high to low pulse
hold=count[13]; //This is the place where I try to design delay
enb=1'b0;
end
endtask
endmodule
You seem to be stuck in a software programming mindset based on your code, you're going to have to change things around quite a bit if you want to actually describe a controller in HDL.
Unfortunately for you there is no way to just insert an arbitrary delay into a 'routine' like you have written there.
When you write a software program, it is perfectly reasonable to write a program like
doA();
doB();
doC();
Where each line executes one at a time in a sequential fashion. HDL does not work in this way. You need to not think in terms of tasks, and start thinking in terms of clocks and state machines.
Remember that when you have an always block, the entire block executes in parallel on every clock cycle. When you have a statement like this in an always block:
lcd_cmd(8'b00111000);
lcd_cmd(8'b00000001);
lcd_cmd(8'b00000110);
lcd_cmd(8'b00001100);
This does you no good, because all four of these execute simultaneously on positive edge of the clock, and not in a sequential fashion. What you need to do is to create a state machine, such that it advances and performs one action during a clock period.
If I were to try to replicate those four lcd_cmd's in a sequential manner, it might look something like this.
always #(posedge clk)
case(state_f)
`RESET: begin
state_f <= `INIT_STEP_1;
data = 8'b00111000;
end
`INIT_STEP_1: begin
state_f <= `INIT_STEP_2;
data = 8'b00000001;
end
`INIT_STEP_2: begin
state_f <= `INIT_STEP_3;
data = 8'b00000110;
end
`INIT_STEP_3: begin
state_f <= `INIT_STEP_4;
data =8'b00111000;
end
`INIT_STEP_4: begin
state_f <= ???; //go to some new state
data = 8'b00000110;
end
endcase
end
Now with this code you are advancing through four states in four clock cycles, so you can start to see how you might handle writing a sequence of events that advances on each clock cycle.
This answer doesn't get you all of the way, as there is no 'delay' in between these as you wanted. But you could imagine having a state machine where after setting the data you move into a DELAY state, where you could set a counter which counts down enough clock cycles you need to meet your timing requirements before moving into the next state.
The best way to introduce delay is to use a counter as Tim has mentioned.
Find out how many clock cycles you need to wait to obtain the required delay (here 450ns) w.r.t your clock period.
Lets take the number of clock cycles calculated is count. In that case the following piece of code can get you the required delay. You may however need to modify the logic for your purpose.
always # (posedge clk) begin
if (N == count) begin
N <= 0;
E = ~E;
end else begin
N <= N +1;
end
end
Be sure to initialize N and E to zero.
Check the clock frequency of your FPGA board and initialize a counter accordingly. For example, if you want a delay of 1 second on an FPGA board with 50MHz clock frequency, you will have to write a code for a counter that counts from 0 to 49999999. Use the terminalCLK as clk for your design. Delayed clock input will put a delay to your design. The psuedo code for that will be:
module counter(count,terminalCLK,clk)
parameter n = 26, N = 50000000;
input clk;
output reg [n-1:0] count;
output reg terminalCLK;
always#(posedge clk)
begin
count <= count + 1;
if (count <= N/2)
terminalCLK <= ~terminalCLk;
if (count == N)
terminalCLK <= ~terminalCLk;
end

VHDL Clock Divider With Decimals

I'm trying to slow a 50MHz clock down to 25.175MHz for use in a VGA controller. I have a clock divider already, but am having trouble slowing the clock down whenever the resulting division of the current clock speed and the desired clock speed is not a whole number. I.E. 50000000/25175000 ~ 1.98. The clock divider compiles and runs, but outputs nothing if the division is a decimal number. Here's my code:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY Clockdiv IS PORT (
Clkin: IN STD_LOGIC;
Clk: OUT STD_LOGIC);
END Clockdiv;
ARCHITECTURE Behavior OF Clockdiv IS
CONSTANT max: INTEGER := 50000000/25175000;
CONSTANT half: INTEGER := max/2;
SIGNAL count: INTEGER RANGE 0 TO max;
BEGIN
PROCESS
BEGIN
WAIT UNTIL Clkin'EVENT and Clkin = '1';
IF count < max THEN
count <= count + 1;
ELSE
count <= 0;
END IF;
IF count < half THEN
Clk <= '0';
ELSE
Clk <= '1';
END IF;
END PROCESS;
END Behavior;
I searched on google, and found using the REAL data type will allow you to use decimals, but when I changed the variables I'm using to REALs, Quartus gives me the error: Error (10414): VHDL Unsupported Feature error at Clockdiv.vhd(12): cannot synthesize non-constant real objects or values.
Then, if I change "count" to a CONSTANT type, I get the error: Error (10477): VHDL error at Clockdiv.vhd(18): name "count" must represent signal.
Does anybody know how I can slow a clock down to 25.175MHz? Also, does anybody know how to slow a clock down so that the compiler is happy with the resulting division being a decimal value?
Thanks
Reals are, in general, not synthesisable, so you'll need to come up with an integer based solution.
That ratio is quite a tricky one because it's almost 2:1, but not quite. Most edge based clock divider circuits work only on one edge of the original clock, so the lowest ratio you can divide by is 2. In this case you'll have to work on both edges of the clock.
Once you've got that you need to have a counter that increments by the denominator of your ratio and is it's over the numerator then output a clock edge.
PROCESS
BEGIN
WAIT UNTIL Clkin'EVENT;
IF count < max THEN
count <= count + DENOMINATOR;
ELSE
count <= 0;
END IF;
IF count > NOMINATOR THEN
Clk <= ~Clk;
END IF;
END PROCESS;
For this ratio I think the smallest way you can represent it is 2000/1007.
The trouble with this is that you'll get a clock that's basically 25MHz, but occasionally (each 2000 / 7 iterations) you'll get an extra edge. It won't be a 25.175MHz clock. Getting 25.175MHz from 50MHz is impossible without a PLL.
I've written plenty of VGA controllers, and just using a 25 MHz clock has never been much of a problem. If you absolutely want to get closer though, your FPGA probably has a clock manager of some sort (I'm only familiar with Xilinx devices), that will allow you to synthesize an output clock by multiplying and dividing an input clock.
Also, while using derived/gated clocks (clocks where you directly set the value in a process) will probably work for you in this case, it can lead to a lot of problems that can be hard to debug. A better solution is to generate clock enables, and then run everything on the same (fast) clock.
And a last thing, although it is probably as much a question of preferred style, but I usually use clocked process statements instead of WAIT statements (shown below with rising edge trigger, synchronous reset and a clock enable). I find it clearer to read and understand, and less prone to writing unsynthesizable constructs such as wait for 10ns;, or statements with multiple WAITs.
process(clk)
begin
if(rising_edge(clk)) then
if(sync_reset = '1') then
--Reset logic
elsif(clk_enable = '1') then
--Actual functionality
end if;
end if;
end process;

Resources