How to generate serial signal from string? - string

How do I send data represented by a binary string (e.g. "01011101000100111", length is variable) to an std_logic signal given either fixed delay or clock signal? I want this for a testbench so I'd want to be able to arbitrarily change the binary string with as little hassle as possible, so I'm thinking of using generate.

I humbly present a fixed-delay version (it is testbench code after all...). I've checked this and it works, but I'm more comfortable in verilog so this code may no be the nicest VHDL ever...
--
-- Clocking out bitstream
--
library ieee;
use ieee.std_logic_1164.all;
entity stackoverflow_strings is
end stackoverflow_strings;
-- this is testbench code, so we can use "wait"s inside a "for" loop.
architecture rtl of stackoverflow_strings is
signal my_output : std_ulogic;
begin
shift_data : process is
constant my_bits : std_logic_vector := B"100101010000100010101";
begin
my_output <= '0';
wait for 10 ns;
for i in my_bits'range loop
my_output <= my_bits(i);
wait for 10 ns;
end loop;
wait;
end process shift_data;
end rtl;

To add to Marty's fine answer:
To make it clocked, change the wait for 10 ns;s to wait until rising_edge(clk);

Related

Filling register vector from FIFO with generated shifts

I'm a bit of a neophyte with Verilog, and I have just started working on a project, and I'm trying to verify that the code I have started with is workable. The code snippet below is unloading a FIFO into a vector of 8 bit registers. At each clock cycle it unloads a byte from the FIFO and puts it in the end of the register chain, shifting all the other bytes down the chain.
reg [ 7:0] mac_rx_regs [0 : 1361];
generate for (ii=0; ii<1361; ii=ii+1)
begin: mac_rx_regs_inst
always #(posedge rx_clk_int, posedge tx_reset)
if (tx_reset) begin
mac_rx_regs[ii] <= 8'b0;
mac_rx_regs[1361] <= 8'b0;
end else begin
if (rx_data_valid_r) begin
mac_rx_regs[ii] <= mac_rx_regs[ii+1];
mac_rx_regs[1361] <= rx_data_r;
end
end
end
endgenerate
I'd like to know if this is a good way to do this. I would have expected to just address the register vector with the byte count from reading the FIFO. I'm concerned that this isn't deterministic in that the order that the generated always blocks run is not specified, plus it seems that it'll cause a lot of unnecessary logic to be created for moving data from one register to another.
To start with, you don't really need to worry about the number of always statements in general. If they are all using the same clock and reset, you will get expected behavior relative to interaction between the processes.
The one thing I do, that is more about style than anything else, is to add a #FD to my flop assignments like shown below to make simulation look a little better, IMHO.
Also, this is simple enough that you could code this as a single process.
parameter FD = 1;
reg [1361*8-1:0] mac_rx_regs; // Arrays are good if you are trying to
// infer memory, but if you are okay
// with registers, just declare a vector.
always # (posedge clk or posedge reset)
begin
if (reset)
mac_rx_regs <= #FD 1361*8'h0;
else
// This next statement shifts in a new 8 bits when rx_data_valid_r is asserted.
// It will assign max_rx_regs to max_rx_regs (nop) when deasserted.
mac_rx_regs <= #FD rx_data_valid_r ? {mac_rx_regs[1361*8-9:0],rx_data_r} :
mac_rx_regs;
end

delayed attribute in VHDL

I'm trying to create a delayed version ('s_dlyd') of a signal ('s') using the 'delayed attribute in VHDL.
My code (below) compiles and simulates (using Xilinx webpack, ISIM) and 's' undergoes the expected '0/1' transitions.
s_dlyd simply sits at '1' however (i.e. it isn't a 5ns-delayed copy of 's' I'd (naively?!) expected.
I'm guessing I'm missing something fundamental about the way VHDL schedules transitions. I've tried numerous of variations of the code (splitting the line "s<=..." into 3; trying things like "s_dlyd <= s'delayed(5 ns) after 11 ns" etc.) but none give me a delayed copy of s.
Any help appreciated. Thankyou
architecture Behavioral of five_three is
signal s : STD_LOGIC := '1';
signal s_dlyd: STD_LOGIC;
begin
my_process : process is
begin
s <= '1', '0' after 10 ns, '1' after 20 ns;
s_dlyd <= s'delayed(5 ns);
wait for 50 ns;
s <= '0' ;
wait;
end process;
end architecture;
I expect s_dlyd to be '1' after 5 ns, previously 'U'.
A signal equivalent to signal S delayed T units of time. The value of
S'DELAYED(t) at time Tn is always equal to the value of S at time
Tn-t.
The current effective value of s will be assigned to s_dyld after 5 ns in this case. The current value of s (Now = 0 ns) is the default value ('1').
Your process is only going to get invoked once because of the wait statements (the last one wait ;).
The equivalent sequential signal assignment statement is
s_dyld <= transport s after 5 ns;
You can assign s_dyld in a separate process sensitive to s or as a concurrent signal assignment statement or restructure your current wait statement with more waits and more s_dyld assignments.

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

Why a delay of 1 clock period in simple counter

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;

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