- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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); ThanksLink Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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;
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
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 <= '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;
http://skiareatrailmaps.com/images/simulation.JPG
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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. 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;
Thanks again!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page