Thanks for all the tips. It's an enormous help. They just don't teach
best practices at university (at least not at mine).
I circumvent it by only using signals in port maps.
Is your design synchronized to one clock?
There is only one clock. I'm not experienced enough to work with
multiple clocks.
I am trying to avoid signals when I can. I use them in port maps, and
use a two processes approach for other logic. The thing is that this
translate-block requires to select certain port maps and output them
differently at the outputs. For example, input a can become output b,
c or d. The solution I know for this requires an intermediate signal
for the actual selection. Is there another way?
If one signal is delayed by a delta cycle (by a signal assignment in your
translate block) and another signal is not delayed, and this skew is not
allowed, then simply insert an extra signal and signal assignment in the
other signal. That way the signals will be aligned again.
The answer from the sram is delayed. My current fix is to delay the
clock of my core with one delta cycle. This seems to work when just
assigning signals, but not in my switch process.
So right now I have (Sorry for all the code):
entity image_translator is
port
(
clk : in std_logic; --real clock, not the delta-delayed one
zero_select : in natural range 0 to 2;
mems_image : inout memories_inout_type --connected to core
);
end;
lbl_sram_image0: sram
generic map
(
ram_width => bits_per_pixel,
ram_addr_bits => bit_img_size
)
port map
(
clk => clk,
address => image0.address,
enable => image0.enable,
write_enable => image0.write_enable,
input => image0.input,
output => image0.output
);
image0.address <= mems_image.image0.address;
image0.enable <= mems_image.image0.enable;
image0.write_enable <= mems_image.image0.write_enable;
image0.input <= mems_image.image0.inoutput;
mems_image.image0.inoutput <= image0.output;
the above works, but this fails:
comb : process(r)
variable v : reg_type;
begin
-- default assignment
v := r;
v.zero_select := zero_select;
case v.zero_select is
when 0 =>
--image 0->0, 1->1, 2->2 (only 0 shown)
image0.address <= mems_image.image0.address;
image0.enable <= mems_image.image0.enable;
image0.write_enable <= mems_image.image0.write_enable;
image0.input <= mems_image.image0.inoutput;
mems_image.image0.inoutput <= image0.output;
when 1 =>
--image 0->2, 1->0, 2->1
when 2 =>
--image 0->1, 1->2, 2->0
when others =>
report "Wrong loop entry in image translator encountered" severity
failure;
end case;
-- drive register inputs
rin <= v;
-- Keep bus free
resetMemoryAccess(mems_image.image0);
resetMemoryAccess(mems_image.image1);
resetMemoryAccess(mems_image.image2);
resetMemoryAccess(mems_image.it);
resetMemoryAccess(mems_image.ix);
resetMemoryAccess(mems_image.iy);
end process;
-- sequential process
regs : process(clk)
begin
if rising_edge(clk) then r <= rin; end if;
end process;
Somewhere there are more delays and I can't figure out where. Can you
tell me what the delay is? And where I'm going wrong with this.
Another trick is to put a real delay (say 1 ns) in the last signal
assignment that is the last in a chain of signal assignments. A real delay
will eat up all delta delays. Of course that must be done with all signals
that are related (that should be aligned).
How can I add a real delay for synthesis? Or is the trick only
relevant for simulation (and synthesis won't experience the problem)?