[myhdl-list] Handling combinational code
Brought to you by:
jandecaluwe
From: Angel E. <ang...@gm...> - 2012-12-03 11:35:31
|
Hi, when writing VHDL code it is common to write combinational statements outside of processes. For example, I've got the following VHDL code that I wanted to rewrite using MyHDL: ~~~ ---------------------------------------------------------------------------------- -- -- Module Name: capture_synchronizer - Behavioral -- Description: -- -- Module that can be used to cross clock boundaries by detecting a signal change -- regardless of the input/output clock relationship. -- -- This module follows the description on: -- -- http://chipdesignmag.com/display.php?articleId=32&issueId=5 -- -- Figure 3. -- -- [WARNING] This module introduces a 1 output cycle delay. -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.all; entity capture_synchronizer is port ( clk : in std_logic; rst : in std_logic; input : in std_logic; output : out std_logic ); end capture_synchronizer; architecture Behavioral of capture_synchronizer is signal captured : std_logic := '0'; signal demet : std_logic := '0'; signal sync1 : std_logic := '0'; signal sync2 : std_logic := '0'; begin -- Capture any changes to the input signal -- This is done by implementing a process whose -- output toggles whenever the input signal changes, -- (which in turn is done by using the input signal) -- as a "clock" capturer : process(input, rst) begin if rst = '1' then captured <= '0'; elsif rising_edge(input) then captured <= not captured; end if; end process; -- 1. Register the captured signal using the output clock -- we do so using a synchronizing double register -- 2. When the captured signal changes it means thatDetect changes at the input by comparing the synchronized input -- with its previous value. When there is a change, activate the -- output for a single cycle demet_and_sync : process(clk, input) begin if rising_edge(clk) then -- Double register the "captured" signal to "demetastabilize" it demet <= captured; sync1 <= demet; -- Store the "demetastabilized" signal so that we can detect -- when it changes sync2 <= sync1; if rst = '1' then demet <= '0'; sync1 <= '0'; sync2 <= '0'; end if; end if; end process; -- When the "demetastabilized" captured signal changes, toggle output output <= sync1 xor sync2; end Behavioral; ~~~ The code in question is not very important. The important part is the last line: output <= sync1 xor sync2; My question is, what is the most "idiomatic" way to handle this sort of statement in MyHDL? So far what I've done is creating an "always_proc" process called "combinational" in which I dump all statements that I would usually place outside all processes in the equivalent VHDL code. That is, in the example: @always_comb def combinational(): output.next = sync1 ^ sync2 The MyHDL toVHDL converter seems to handle this fine and in fact it places these statements outside all processes as well. Is this the right/recommended way to handle this? The only drawback that I see is that it makes it harder to place these sort of statements close to the processes that are related to them, which may make the code a little harder to understand. I guess that I could solve that by creating multiple "combinational" always_proc generators, each located near the processes where the combinational inputs or outputs are used. Would that be a good solution? Thanks, Angel |