Close

Simple Application Example

A project log for Small CPU in VHDL

Small CPU in VHDL

land-boardscomland-boards.com 06/22/2021 at 21:420 Comments

Simple code example where the IOP16B reads the pushbutton and writes to the LED on the FPGA card. 

Sources

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