thigmotropism
Newbie level 1
Hello all,
I'm hoping someone can give advice on how to properly handle signals between processes.
The gist of the code below is that there are 3 components, P_INIT, P_CONF and P_CMDR, and a FSM that selects how signals are connected between them and the entity's ports. The sequence of the FSM is:
The code may have technical flaws but this is more of a design question. Is using a FSM like this a sensible way to connect processes? Or would I be better off figuring out pure combinational logic? Or maybe something else?
Regards,
thigmotropism
I'm hoping someone can give advice on how to properly handle signals between processes.
The gist of the code below is that there are 3 components, P_INIT, P_CONF and P_CMDR, and a FSM that selects how signals are connected between them and the entity's ports. The sequence of the FSM is:
- Start in IDLE and go to INIT when port start='1'.
- While in INIT, start the process in P_INIT and connect its data out to port's data out.
- When P_INIT finishes its task, P_CONF and P_CMDR are started and the FSM goes to CONF.
- In CONF, P_CMDR ready (output) is connected to P_CONF ready (input) and P_CONF data (output) is connected to P_CMDR (input), so that P_CONF can send data to P_CMDR for processing and be notified when P_CMDR is ready for more.
- When P_CONF does all it needs to do, the FSM goes into READY_STATE.
- In READY_STATE, P_CMDR ready is connected to port ready and the FSM waits for port start='1'.
- When it gets start='1', port dataIn is connected to P_CMDR dataIn and the FSM goes to BUSY.
- In state BUSY, P_CMDR is processing the input and its dataOut is connected to port's dataOUT.
- When finished, FSM returns to READY_STATE to wait for more data.
The code may have technical flaws but this is more of a design question. Is using a FSM like this a sensible way to connect processes? Or would I be better off figuring out pure combinational logic? Or maybe something else?
Regards,
thigmotropism
Code VHDL - [expand] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 entity SampleEntity is port(clk, reset : in std_logic; start, dataIn : in std_logic; ready, dataOut: out std_logic;); end SampleEntity; architecture Arch of SampleEntity is type State is (IDLE, INIT, CONF, READY_STATE, BUSY); signal currentState_reg, currentState_next: State; signal INIT_start, INIT_done, INIT_data: std_logic; signal CONF_start, CONF_ready, CONF_done, CONF_data: std_logic; signal CMDR_start, CMDR_ready, CMDR_dataI, CMDR_dataO: std_logic; begin P_INIT: entity work.Predefined_INIT(Arch) port map (--ins clk => clk, reset => reset, start => INIT_start, --outs done => INIT_done, data => INIT_data); P_CONF: entity work.Predefined_CONF(Arch) port map (--ins clk => clk, reset => reset, start => CONF_start, ready => CONF_ready, --outs done => CONF_done, data => CONF_data); P_CMDR: entity work.Predefined_CMDR(Arch) port map (--ins clk => clk, reset => reset, start => CMDR_start, dataI => CMDR_dataI, --outs ready => CMDR_ready, dataO => CMDR_dataO); -- Sync state transitions with clk Synchro: process(clk, reset) begin if reset='1' then currentState_reg <= IDLE; elsif rising_edge(clk) then currentState_reg <= currentState_next; end if; end process Synchro; -- Next-state logic NextState: process(start, dataIn, currentState_reg, INIT_done, INIT_data, CONF_done, CONF_start, CONF_data, CMDR_ready , CMDR_dataO) begin -- Default values currentState_next <= currentState_reg; -- Interprocess signals INIT_start <= '0'; CONF_start <= '0'; CONF_ready <= '0'; CMDR_start <= '0'; CMDR_dataI <= '0'; -- port outs ready <= '0'; dataOut <= '0'; case currentState_reg is when IDLE => -- Stay IDLE until user sends enable. if start='1' then currentState_next <= INIT; end if; when INIT => -- Send start signal to P_INIT. INIT_start <= '1'; -- Send P_INIT data to port dataOut dataOut <= INIT_data; -- Stay INIT until P_INIT says done. if INIT_done='1' then -- Send start signal to P_CONF and P_CMDR CONF_start <= '1'; CMDR_start <= '1'; currentState_next <= CONF; end if; when CONF => -- Send P_CMDR ready to P_CONF CONF_ready <= CMDR_ready; -- Send P_CONF data to P_CMDR CMDR_start <= CONF_start; CMDR_dataI <= CONF_data; -- Stay CONF until P_CONF says done. if CONF_done='1' then currentState_next <= READY_STATE; end if; when READY_STATE => -- Send P_CMDR ready to port ready ready <= CMDR_ready; -- Stay in READY_STATE until port starts new dataIn. if start='1' then -- Send port start & dataIn to P_CMDR CMDR_start <= start; CMDR_dataI <= dataIN; currentState_next <= BUSY; end if; when BUSY => -- Send P_CMDR dataO to port dataOut dataOut <= CMDR_dataO -- Stay in BUSY_STATE until P_CMDR says ready. if CMDR_ready='1' then currentState_next <= READY_STATE; end if; end case; end process NextState; end architecture Arch;