Place and route timing strategy - vhdl

This sounds very naive, but i would like your expert comments on the below pseudo-code. Which of the 2 methods below can achieve minimal place & route timing when implemented in hardware.
Method:1
control_proc: process(clk)
begin
if(clk'event and clk=='1') then
if sig_delay == 1 then
sig_ctrl <= '1';
else
sig_ctrl <= '0';
end if;
end if;
end process
delay_proc: process(clk)
begin
if(clk'event and clk=='1') then
if <some-condition> then
sig_delay <= '1';
else
sig_delay <= '0';
end if;
end if;
end process
Method:2
control_single_proc: process(clk)
begin
if(clk'event and clk=='1') then
if <some-condition> then
sig_delay <= '1';
else
sig_delay <= '0';
end if;
if sig_delay == 1 then
sig_ctrl <= '1';
else
sig_ctrl <= '0';
end if;
end if;
end process
Note:
sig_ctrl is used as a CE (chip enable) for another component in the hierarchy, which is kind of bit serialiser.

Your two methods are equivalent. Any good synthesis tool will be able to perform the same optimisations on both cases.
The sorts of things that might prevent a synthesis tool from optimising logically equivalent hardware are entity hierarchy / design partition boundaries, however most tools flatten the netlist before optimisation anyway.
Method 2 may perform marginally better in simulation since there are fewer processes to schedule.

Related

D-latch with both asynchro and synchro resetting in VHDL

I have to implement a D-latch that follows asynchronnous resetting when aclrn=0 and synchronnous when sclrn=0. The implementation should be able to follow both methods of resetting.
Here's what I came up with in VHDL (I only include the process) based on basic D-latches.
process(aclrn,clock)
begin
if (aclrn='0') then
q <= '0';
elsif (rising_edge(clock)) then
if (sclrn='0') then
q <= '0';
else
q <= d;
end if;
end if;
end process;
where
clock, d, aclrn, sclrn : in std_logic; q : out std_logic
Am I correct that the process doesn't need to take in sclrn as an argument, but only aclrn and clock? Are there any other inconsistencies?
Thank you in advance.
You say D-latch but coded flipflop. Do you really need a D-latch or you are just using latch instead of register carelessly?
if you really need a flipflop, you have done it right.
You have put aclrn and clock in sensitivity list which is right. You don't need to put sclrn in list because it is synchronous.
Xilinx XST tutorial example for Flip-Flop With Positive-Edge Clock and Synchronous Set
architecture archi of registers_3 is
begin
process (C)
begin
if (C'event and C='1') then
if (S='1') then
Q <= '1';
else
Q <= D;
end if;
end if;
end process;
end archi;
and XST coding example for Flip-Flop With Positive-Edge Clock and Asynchronous Reset
architecture archi of registers_2 is
begin
process (C, CLR)
begin
if (CLR = '1')then
Q <= '0';
elsif (C'event and C='1')then
Q <= D;
end if;
end process;
end archi;
By mixing these two you get your answer. I see nothing wrong with your code. best way to know if you've code what you are asked is to simulate it.
If you need latch, notice that latches are sensitive to levels instead of edges. this is an example of LATCH with positive gate and async reset
architecture archi of latches_2 is
begin
process (CLR, D, G)
begin
if (CLR='1') then
Q <= '0';
elsif (G='1') then
Q <= D;
end if;
end process;
end archi;

VHDL Synthesis Error and Code Suggestions [duplicate]

I've a module that have a 8bit input and a serial output, I want to serialize input data and synchronize it with a clock.
I want to set my data when falling edge then wait when clock rise, when clock fall again I set another data. I don't want to connect the directly reference clock to the output because when I don't use this module I want a 1 state on clock output.
I've tried this code:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
elsif rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
The synthesizer gives me this error:
"Asynchronous load of non-constant data for SCK is not supported"
When I separate the code in two blocks like this:
process(Clock, ModuleReset)
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end process;
process(Clock)
if rising_edge(Clock) then
OutCK <= '1';
end if;
end process;
I have these two errors:
"Multiple non tristate drivers for net SCK"
"Unresolved tristate drivers for net SCK"
Another code I've tried is:
process(Clock, ModuleReset)
if ModuleEN = '1' then
OutCK <= Clock;
end if;
begin
if ModuleReset = '0' then
OutData <= '0';
OutCK <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutCK <= '0';
OutData <= Data(counter);
end if;
end process;
But the output clock looks strange with a different frequency.
Your last idea, which I understand ended up working for you, is sub-optimal. If your clock is slow, it should be fine, but I suggest you fix it nevertheless.
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
Yields combinational logic with the clock signals for the output. Having the clock used as a logic signal is never recommended, since clocks use clock paths which doesn't route well to general routing resources. The output signal will have potential glitches (very bad for an output interface!) and large delay/skew.
Your first approach, to use a DDR register to forward the clock, is indeed the correct and best approach. With this scheme, your clock only use clock paths, and if both the registers outputing the clock and data are situated in IO blocks, they will have the same output delay with very little skew.
You didn't specify the technology you're using, but I suggest you lookup how to write code that maps to DDR register for your synthesizer. Alternatively, you can manually instantiate the DDR output register primitive, likely ODDR for Xilinx or ALTDDIO_OUT for altera.
The problem with your attempts is indeed that you have multiple drivers for the same signal, or that you assign a signal on both rising and falling edge of a clock. This is not synthesizable.
Try this:
process(Clock, ModuleReset, ModuleEN)
begin
if ModuleEN = '1' then
OutCK <= Clock;
else
OutCK <= '1';
end if;
if ModuleReset = '0' then
OutData <= '0';
counter <= 7;
elsif falling_edge(Clock) then
OutData <= Data(counter);
end if;
end process;

During synthesis, should I care about the "found latch" warnings if I actually want the latches?

say I have the following state machine:
....
if state_a then
output_a <= '0';
next_state <= state_b;
elsif state_b then
output_a < '0';
if cond then
output_b <= '1';
next_state <= state_a;
else
next_state <= state_b;
end if;
end if;
......
I don't want output_b to change except when being assigned again in state_b. However, when I try to synthesise this code, most synthesis tools will say something along this line:
warning: found 1-bit latch for signal "output_b". latches aren't
recommended for FPGA design because it might result in timing
problems.
Should I worry about this at all? If so, why and what are the alternatives?
Following Xilinx:
If latch inference is intended, you can safely ignore this message. However, some inefficient coding styles can lead to accidental latch inference. You should analyse your code to see if this result is intended.
Some techniques to avoid latch inference:
Make sure any "if / else if" statements have a concluding "else" clause,
Assign to all the same outputs in each case,
Include all possible cases in the case statement (but be aware that WHEN OTHERS clause always works, but can create extraneous logic).
if you have incomplete if/elsif or case statement in a clocked process, it's absolutely harmless.
if rising_edge(clk)
if a then
out <= b;
end if;
end if;
It means that you have flip-flop with some sort of feedback, or, like in this case, you have flip-flop with clock enable pin used, which is even better.
If you have incomplete if/elsif or case statement in not clocked process - it's a latch and it's in most cases:
something you don't really want;
something that point out on a poor design and can be avoided with redesign.
If you complete your little example, someone can help you redesign it. Now it is not enough information.
The problem you have stems from the FSM coding style you're (presumably) using. As other pointed it is not possible to guess what you want the code to do, since you did not provide enough code to figure that out, so I present one possible interpretation, assuming you really wanted to change output_a somehow and that one time (after reset) latching of output_b should happen at the same time FSM state transitions.
Using 2 processes per FSM style, we have code that is not giving latch warnings:
----
signal CLK, RESET, cond : std_logic;
type state_t is (a,b);
signal state, state_next : state_t;
signal ouput_a, output_b, output_b_next : std_logic;
----
FSM_clock: process(all)
begin
if rising_edge(CLK) then
if RESET then
state <= a;
output_b <= '0';
else
state <= state_next;
output_b <= output_b_next;
end if;
end if;
end process;
FSM_next: process(all)
begin
state_next <= state;
output_b_next <= output_b;
output_a <= '0';
case state is
when a =>
state_next <= b;
when b =>
output_a <= '1';
if cond then
output_b_next <= '1';
state_next <= a;
else
state_next <= b;
end if;
end case;
end process;

Communication between processes in VHDL

I have problems on communicating between the processes. I used to use flag and clearFlag to tackle this, but it's kind of annoying and not looking good. What is the best practice to handle this? Here is a sample code on how I did it before:
Proc_A : process (clk, reset, clrFlag)
begin
if clrFlag = '1' then
flag <='0';
elsif reset = '0' then
A <= (others => '0');
elsif rising_edge (clk) then
A <= in;
flag <= '1';
end if;
end process;
Proc_B : process (clk, reset)
begin
if reset = '0' then
B <= (others => '0');
elsif rising_edge (clk) then
if flag = '1' then
B <= data;
clrFlag <= '1';
else
clrFlag <= '0';
end if;
end if;
end process;
This way works but I don't think it is nice method. I have to write a flag and clrFlag couple to do this task. All I want to do is when something happened (e.g. A <= in;), it triggers another proc, Proc_B for example, to run once or a number of times. What is the best practice to this problem? Thanks!
For simulation, you can make a process wait on a signal:
Proc_B : process
begin
wait until flag'event;
B <= data;
end process;
and just write the flag with its inverse every time you need something to happen.
In synthesisable logic, you either have to exchange flag signals, as you do, or use some other higher-level communication (like a FIFO, messagebox, or similar).
However, if all your proc_b logic takes place in a single cycle - so you can guarantee not to miss a flag, and to be able to keep up even if flag is asserted all the time (as it looks like you do) - you can do this (and combine the two processes):
Proc : process (clk, reset, clrFlag)
begin
flag <='0';
if reset = '0' then
A <= (others => '0');
B <= (others => '0');
elsif rising_edge (clk) then
if some_trigger_event = '1' then
A <= in;
flag <= '1';
end if;
-- recall that due to VHDL's scheduling rules, this "if" will take place
-- one clock cycle after the flag is written to, just as if it were in a
-- separate process
if flag = '1' then
B <= data;
end if;
end if;
end process;
Side note - your code is not ideal for synthesis... you really only want the reset part outside the clocked part:
Proc_A : process (clk, reset)
begin
if reset = '0' then
A <= (others => '0');
elsif rising_edge (clk) then
if clrFlag = '1' then
flag <='0';
else
A <= in;
flag <= '1';
end if;
end process;

VHDL synthesis of registers - separate process for each register vs. one merged process

Let's say I have two registers named reg_operand1 and reg_operand2. For both of them I have an appropriate write-enable signal. Somewhere I read I should have separate process for each register assignment, something like this:
process(CLK, RESET)
begin
if (RESET = '1') then
reg_operand1 <= (others => '0');
elsif (CLK'event and CLK = '1') then
if reg_operand1_we='1' then
reg_operand1 <= DI;
end if;
end if;
end process;
process(CLK, RESET)
begin
if (RESET = '1') then
reg_operand2 <= (others => '0');
elsif (CLK'event and CLK = '1') then
if reg_operand2_we='1' then
reg_operand2 <= DI;
end if;
end if;
end process;
But what happen if I merge the processes into this? Will the synthesized circuit be different? Also, what if I put "elsif" between the if-statements in merged process? Will the synthesizer insert a multiplexor into the circuit? Thanks!
process(CLK, RESET)
begin
if (RESET = '1') then
reg_operand1 <= (others => '0');
reg_operand2 <= (others => '0');
elsif (CLK'event and CLK = '1') then
if reg_operand1_we='1' then
reg_operand1 <= DI;
end if;
if reg_operand2_we='1' then
reg_operand2 <= DI;
end if;
end if;
end process;
The second one will produce exactly the same hardware as the first, and as already been said, contains less boilerplate.
If I understand your question about elsif correctly, you're proposing:
process(CLK, RESET)
begin
if (RESET = '1') then
reg_operand1 <= (others => '0');
reg_operand2 <= (others => '0');
elsif (CLK'event and CLK = '1') then
if reg_operand1_we='1' then
reg_operand1 <= DI;
elsif reg_operand2_we='1' then
reg_operand2 <= DI;
end if;
end if;
end process;
This generates different hardware, and also gives different behaviour.
In the example without the elsif, reg_operand2 is assigned DI when reg_operand2_we is high, irrespective of the state of reg_operand1_we.
When elsif is used, the assignment to of reg_operand2 only occurs when reg_operand2_we is high and reg_operand1_we is low
In general, if the two assignments do not depend on each other, use a seperate if construct.
The second one is shorter and simpler, and will generate the same hardware. (from a brief inspection : i.e. assuming there are no accidental typos in one or the other)
An elsif in the second version, combining the two register writes, will just prioritise the registers; i.e. if you attempt to write to both registers by asserting both we signals in the same cycle, only reg_operand1 will actually be written. It will have no other effect on the design.
So...
Unless you have specific corporate style guides that prohibit it, use the second style as a general rule.
There may be a FEW cases where you want to COMPLETELY separate some functionality to make it clear that it IS separate; in that case it's better not to be dogmatic about this style; but USUALLY fewer lines of code means less to go wrong, especially where (as here) it's easier to read and understand.
"I read somewhere" ... it would be worth knowing where you read this. There are a LOT of excruciatingly bad books, teaching materials and example projects out there, waiting to ruin potential VHDL programmers, and it's worth publicising which ones to avoid...

Resources