Simple code example where the IOP16B reads the pushbutton and writes to the LED on the FPGA card.
Sources
- Application VHDL code is here.
- IOP16B VHDL code is here.
- Assembly code is here.
- Some other VHDL pieces are in subdirectories from here.
Memory Map
Single peripheral address (0x00), data bit (D0).
Top Level Entity
entity TestIOP16B is
port (
-- Clock and reset
i_clk : in std_logic := '1'; -- Clock (50 MHz)
i_n_reset : in std_logic := '1';
-- The key and LED on the FPGA card
i_key1 : in std_logic := '1'; -- KEY1 on the FPGA card
o_UsrLed : out std_logic := '1' -- USR LED on the FPGA card
);
end TestIOP16B;
CPU Instance
IOP16: ENTITY work.IOP16
-- Need to pass down instruction RAM and stack sizes
generic map (
INST_SRAM_SIZE_PASS => 512, -- Small code size since program is "simple"
STACK_DEPTH_PASS => 4 -- Single level subroutine (not nested)
)
PORT map (
i_clk => i_clk,
i_resetN => w_resetClean_n,
-- Peripheral bus signals
i_periphDataIn => w_periphIn,
o_periphWr => w_periphWr,
o_periphRd => w_periphRd,
o_periphDataOut => w_periphOut,
o_periphAdr => w_periphAdr
);
Code
List file is:
000 SELF 0x6000 IOR 0x00 IO_00 read pushbutton 001 0x7000 IOW 0x00 IO_00 write LED 002 0xE000 JMP SELF
IOP_ROM
The ROM file name has to be IOP_ROM and it gets stored in the current project folder. That allows for the IOP16B to be used in other projects. The Assembler creates a MIF file which gas to be loaded:
IOP_ROM
The IOP_ROM instance has two parameters: INST_SRAM_SIZE_PASS and STACK_DEPTH_PASS.
-- Set stack size in STACK_DEPTH generic
IOP16: ENTITY work.IOP16
-- Need to pass down instruction RAM and stack sizes
generic map {
INST_SRAM_SIZE_PASS => 512, -- Small code size since program is "simple"
STACK_DEPTH_PASS => 1 -- Single level subroutine (not nested)
)
INST_SRAM_SIZE_PASS has to match the size of the IOP_ROM.
STACK_DEPTH_PASS can be 0, 1, or > 1 (typically 4 for 16) deep stack,
Application Example Logic
-- Peripheral bus read mux
w_periphIn <= "0000000"&i_key1 when (w_periphAdr=x"00") else
x"00";
-- Strobes/Selects
w_wrLED <= '1' when ((w_periphAdr=x"00") and (w_periphWr = '1')) else '0';
latchLED: PROCESS (i_clk)
BEGIN
IF rising_edge(i_clk) THEN
if w_wrLED = '1' then
o_UsrLed <= w_periphOut(0);
END IF;
END IF;
END PROCESS;
land-boards.com
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.