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;
Related
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
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.
I am trying to use the 8 switches on my basys2 board to control the frequency of a square wave, yet I'm having trouble with the input part of it, as I do not know how to divide the clock using the binary value of the register that I have collected the states of the switches in.
I know that I need to divide 25000000/[input value] in order to get the correct value for the counter. My question is:
how can I divide 25000000 by the register which has the switch states stored inside of it such, as input [7:0] SW?
If you can assume your input is always a power of two, you can use shifting to the right. But if you want the full 255 possible resolutions, you need to implement a divider.
Some synthesis tools just synthesize a divider when you simply write 25000000/inputValue. For some others, you may have to do it yourself.
Alternatively, if you don't want to waste time for dividing, you can pre-calculate the values beforehand and use a counter:
case (inputValue)
8'b0000_00010: counterMax = 25000000/2 ; //Where 25000000/2 can be calculated at compile time or by you
8'b0000_00011: counterMax = 25000000/3 ; //Where 25000000/3 can be calculated at compile time or by you
...
endcase
and then just count to the counterMax:
always #(posedge clock)
begin
counter <= counter + 1;
if(counter == counterMax) begin
out <= ~out;
counter <= 0;
end
end
Instead of dividing by input, can you just increment your counter by SW each clock cycle? Then if SW is for example, '15', then your period is reduced by 15x, but you avoid an expensive division circuit.
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
Below is a simple 3-bit counter.
When reset(rst) is 0, counter value is "000", else it increments by 1 for rising edge of each clock.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.numeric_std.all;
---------------------------------------------
ENTITY counter IS
PORT (clk : IN STD_LOGIC;
rst : in std_logic;
digit : out std_logic_vector (2 downto 0)
);
END counter;
---------------------------------------------
ARCHITECTURE counter OF counter IS
BEGIN
count: PROCESS(clk,rst)
VARIABLE temp : std_logic_vector(2 downto 0);
BEGIN
IF (clk'EVENT AND clk='1') THEN
if (rst = '1') then
temp := temp + "001";
else
temp := "000";
END IF;
END IF;
digit <= temp;
END PROCESS count;
END counter;
Below is the simulation result I got :
In the result, output is correct. But there is an one clock delay between the time rst = 1 and output='001'. ie counter doesn't increment instantaneously when rst = '1'.
As per my understanding, whenever a change in clk or rst happens, process is executed. So when rst changes from low to high, an event occurs. Process checks if rising edge of clk, YES. Then check if rst = 1, YES. So normally counter has to increment in that clk itself. But it doesn't.
Questions:
Why one clock period delay between reset = 1 and output = 001?
And what is wrong in my understanding?
The most likely cause in that "rst" is generated by a clocked process, clocked by the same "clk" signal.
So "rst" occurs one delta cycle after "clk". When "rst" changes it will wake the process up, but "clk'event" was on the previous delta cycle, therefore the "if" statement will not execute.
On the next clock edge, rst = 1 so the counter works as expected.
Three minor points:
it would be worth naming the reset signal rst_n to make it clearer that it is an
active-low reset!
rst really doesn't need to be in the sensitivity list
there is no need for parentheses around the boolean expressions
(Disclaimer: It's been long time since I programmed in VHDL, so this only answers to generic logic design.)
Anyway, one can't expect the result of addition to be ready immediately when a process is triggered. The point is, that calculating even the first bit of 000 + 001 is affected by the propagation delay equivalent to one xor operation. The second bit is calculated from the first bit's carry (if both bits were 1) and xor operation of the second bits. And so on.
If one would probe the 'temp' variable asynchronously, one would see something like this:
^ ________________
result_bit_0 __________|
0123456789
_____________
result_bit_1 ^ |____________
0123456789
____________ _____
result_bit_2 ^ |_| |________
0123456789abcde
________
clock: ________| |______|
The figure tries to illustrate in more detail the waveforms of a generic add operation.
At time 0 the process of adding is started.
After a small delay '2' the first bit stabilizes to 1.
At time '5' the second bit stabilizes to 0 and at time '9' the third bit stabilizes to 0.
But also it's quite common, that as in result_bit_2, the output toggles between various states.
It's the total / maximum delay of each temporary variable to take to stabilize, that determines the minimum clock period. At this case the time instant 'e' is that one, where we have decided that the result of counter increment is available.
Still, from the perspective result (which is a vector), everything happens instantly at the next clock cycle.
the "issue" is in the way you have described your "rst".
The way you did it would result in a "synchronous" reset, i.e. the reset would take effect only after a rising edge of the clock.
In general this is just a matter of coding style/preferences.
I usually prefer asynchronous reset (with maybe a reset synchronizer at top-level to avoid meta-stability when releasing the reset), but there is nothing wrong in adopting a synchronous reset approach.
In case of an asynchronous reset, you would need to change your code to something like this:
PROCESS (clk, rst_n) BEGIN
IF rst_n = '0' THEN
...
ELSIF rising_edge(clk) THEN
...
END IF;
END PROCESS;