Forum Discussion
multicycle instruction FSM with nios and the done variable
I have been trying for weeks to figure out how the done variable works and it seems like it has no effect whatsoever on the program. Can anyone explain how it works.
Here's an example i've been working on: if (reset = '1') then state <= s0; ELSIF (clk'EVENT AND clk = '1') THEN CASE state IS WHEN s0 => IF (start = '1' AND n = '0') THEN io_148194546 <= dataa; io_277277265 <= datab; state <= s0; done <= '1'; ELSIF (start = '1' AND n = '1') THEN io_109970892 <= dataa; io_19111827 <= datab; state <= s1; done <= '1'; ELSE state <= s0; done <= '0'; END IF; WHEN s1 => result <= io_1298736395; done <= '1'; state <= s0; WHEN OTHERS => report "Invalid State"; END CASE; END IF; END PROCESS; When I do something like: ALT_CI_CI_HARDWARE_INST(0,2,4); y = ALT_CI_CI_HARDWARE_INST(1,5,8); i can't the result from the past operation in y. So if i want to get the actualy value of y, i need to do something like ALT_CI_CI_HARDWARE_INST(0,2,4); y = ALT_CI_CI_HARDWARE_INST(1,5,8); y = ALT_CI_CI_HARDWARE_INST(1,5,8); Thanks8 Replies
- Altera_Forum
Honored Contributor
Here's the whole code. To summarize last post:
Have to do y = ci(1,x,y) twice to get the result. Otherwise I get the result from the alst operation.-- Generated VHDL code to implement Custom Instructions -- CREATED: Thu Dec 02 10:20:48 EST 2010 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; ENTITY CI_HARDWARE IS PORT ( SIGNAL clk : IN STD_LOGIC; SIGNAL reset : IN STD_LOGIC; SIGNAL clk_en : IN STD_LOGIC; SIGNAL start : IN STD_LOGIC; SIGNAL done : OUT STD_LOGIC; SIGNAL dataa : IN STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL datab : IN STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL n : IN STD_LOGIC ); END CI_HARDWARE; ARCHITECTURE behavior OF CI_HARDWARE IS TYPE state_type is (s0,s1); SIGNAL STATE : state_type; SIGNAL io_148194546 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_277277265 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_109970892 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_19111827 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_1556901833 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_1685984552 : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL io_1298736395 : STD_LOGIC_VECTOR(31 DOWNTO 0); COMPONENT lpm_add_sub GENERIC ( lpm_direction : STRING; lpm_hint : STRING; lpm_representation : STRING; lpm_type : STRING; lpm_width : NATURAL ); PORT ( dataa : IN STD_LOGIC_VECTOR(31 DOWNTO 0); datab : IN STD_LOGIC_VECTOR(31 DOWNTO 0); result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) ); END COMPONENT; COMPONENT lpm_mult GENERIC ( lpm_hint : STRING; lpm_representation : STRING; lpm_type : STRING; lpm_widtha : NATURAL; lpm_widthb : NATURAL; lpm_widthp : NATURAL ); PORT ( dataa : IN STD_LOGIC_VECTOR(31 DOWNTO 0); datab : IN STD_LOGIC_VECTOR (31 DOWNTO 0); result : OUT STD_LOGIC_VECTOR(31 DOWNTO 0) ); END COMPONENT; BEGIN lpm_sub_0 : lpm_add_sub GENERIC MAP ( lpm_direction => "SUB", lpm_hint => "ONE_INPUT_IS_CONSTANT=NO, CIN_USED=NO", lpm_representation => "SIGNED", lpm_type => "LPM_ADD_SUB", lpm_width => 32 ) PORT MAP (io_148194546, io_277277265, io_1556901833); lpm_mul_0 : lpm_mult GENERIC MAP ( lpm_hint => "MAXIMIZE_SPEED=5", lpm_representation => "SIGNED", lpm_type => "LPM_MULT", lpm_widtha => 16, lpm_widthb => 16, lpm_widthp => 32 ) PORT MAP (io_1685984552, io_1556901833, io_1298736395); lpm_add_0 : lpm_add_sub GENERIC MAP ( lpm_direction => "ADD", lpm_hint => "ONE_INPUT_IS_CONSTANT=NO, CIN_USED=NO", lpm_representation => "SIGNED", lpm_type => "LPM_ADD_SUB", lpm_width => 32 ) PORT MAP (io_109970892, io_19111827, io_1685984552); PROCESS (reset, clk) BEGIN if (reset = '1') then state <= s0; ELSIF (clk'EVENT AND clk = '1') THEN CASE state IS WHEN s0 => IF (start = '1' AND n = '0') THEN io_148194546 <= dataa; io_277277265 <= datab; state <= s0; done <= '1'; ELSIF (start = '1' AND n = '1') THEN io_109970892 <= dataa; io_19111827 <= datab; state <= s1; done <= '1'; ELSE state <= s0; done <= '0'; END IF; WHEN s1 => result <= io_1298736395; done <= '1'; state <= s0; WHEN OTHERS => report "Invalid State"; END CASE; END IF; END PROCESS; END behavior; - Altera_Forum
Honored Contributor
The timing of the done bit is probably off. I recommend simulating the instruction by itself so that you'll be able to see the behavior of the done bit. If nothing shows up as wrong then try simulating the system and seeing how it behaves hooked up to the Nios II core.
- Altera_Forum
Honored Contributor
I've been testing it on a DE0 board using a NIOS 2/e core with the custom instruction added. Out of testing it on the board, nothing happens if i remove it completely, have it all 0s, have it all 1s, it's like the done bit doesn't do anything at all...
- Altera_Forum
Honored Contributor
Running it in hardware isn't going to tell you what the problem is. The done bit tells the processor when to complete the instruction and latch the result.
Judging by the statemachine it looks like done bit is stuck high. Again a simulation would catch this easily. - Altera_Forum
Honored Contributor
oops, i posted the wrong version of the FSM code. the only diff is that i have done <= '0' in the n=1 case in state s0. The simulation also works as I expect it to, an image of it is included at the bottom. But if I run the code on a nios II core on the DE0 board, it doesn't work. The results are delayed as described above with the same code.
here's the good version of the code:
http://skiareatrailmaps.com/images/simulation.JPGPROCESS (reset, clk) BEGIN if (reset = '1') then state <= s0; ELSIF (clk'EVENT AND clk = '1') THEN CASE state IS WHEN s0 => IF (start = '1' AND n = '0') THEN io_148194546 <= dataa; io_277277265 <= datab; state <= s0; done <= '1'; ELSIF (start = '1' AND n = '1') THEN io_109970892 <= dataa; io_19111827 <= datab; state <= s1; done <= '0'; ELSE state <= s0; done <= '1'; END IF; WHEN s1 => result <= io_1298736395; done <= '1'; state <= s0; WHEN OTHERS => report "Invalid State"; END CASE; END IF; END PROCESS; END behavior; - Altera_Forum
Honored Contributor
Start shouldn't be asserted for more than one clock cycle. So you should see a start strobe with a valid dataa and datab input, then when your custom instruction is complete you preset the valid data output with the done signal asserted.
- Altera_Forum
Honored Contributor
Hello, thanks for helping
If i put start=1 just for one clock cycle, there is no result given in the simulation. If I put start for both of the 2 sets of inputs (so 2 cycles), i get the results i expect as shown in the image below (Fig 1). Maybe I don't have the SOPC set up correctly. -I have a NIOS2/e core to which i added the custom instruction as a CI slave and didn't change any of the settings there. Maybe there needs to be a variable in "Clock Cycles" when i add the CI as shown in Fig2. -on chip memory -sysid -jtag uart As i said, the CI works from NIOS in the c program, but the result is delayed by a call, so i have to call (1,x,y) twice to get the result. http://skiareatrailmaps.com/images/simulation2.JPG http://skiareatrailmaps.com/images/compoment_editor.JPG Also, tried changing the code to this, but no change. Don't know if I understood what you meant.
Thanks again!if (reset = '1') then state <= s0; ELSIF (clk'EVENT AND clk = '1') THEN CASE state IS WHEN s0 => IF (start = '1' AND n = '0') THEN io_148194546 <= dataa; io_277277265 <= datab; state <= s0; done <= '1'; ELSIF (start = '1' AND n = '1') THEN io_109970892 <= dataa; io_19111827 <= datab; state <= s1; done <= '0'; ELSE state <= s0; done <= '1'; END IF; WHEN s1 => result <= io_1298736395; done <= '1'; state <= s0; WHEN OTHERS => report "Invalid State"; END CASE; END IF; END PROCESS; - Altera_Forum
Honored Contributor
But the Nios II custom instruction master will only assert 'start' for one clock cycle. You pasted an image from component editor that shows this so if you attempt to simulate with the start signal asserted for longer than that you are not even mimicking what the processor will drive into the custom instruction which seems like a waste of time to do.
For more details: http://www.altera.com/literature/ug/ug_nios2_custom_instruction.pdf Page 12-13 describe the timing of a multicycle custom instruction.