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;
Discussions
Become a Hackaday.io Member
Create an account to leave a comment. Already have an account? Log In.