-- ----------------------------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; package misc_asm_pack is -- Build a 2-D array type for the RAM --subtype word_t is std_logic_vector((DATA_WIDTH-1) downto 0); --type memory_t is array(2**ADDR_WIDTH-1 downto 0) of word_t; subtype word_t is std_logic_vector(31 downto 0); type memory_t is array(2**9 downto 0) of word_t; shared variable rom_counter : integer range 0 to 2047 := 0; shared variable tmp : memory_t := (others => (others => '0')); subtype uint32_t is std_logic_vector(31 downto 0); ------------------------------------------------------------------------------------------ -- pseudo opcodes procedure org (constant value : unsigned(31 downto 0)); procedure prog_label(variable address : out std_logic_vector(23 downto 0)); procedure dw (variable address : out word_t; constant value : uint32_t); ------------------------------------------------------------------------------------------ -- vhdl-assembler opcodes procedure nop; procedure rts; procedure load_l(constant regnum : unsigned(3 downto 0); constant value : std_logic_vector(15 downto 0)); procedure load_h(constant regnum : unsigned(3 downto 0); constant value : std_logic_vector(15 downto 0)); procedure add (constant regnumd : unsigned(3 downto 0); constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)); procedure and_r (constant regnumd : unsigned(3 downto 0); constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)); procedure outm (constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)); procedure svr (constant regnumd : unsigned(3 downto 0); constant regnums : unsigned(3 downto 0)); procedure jump (constant value : std_logic_vector(23 downto 0)); procedure call (constant value : std_logic_vector(23 downto 0)); end misc_asm_pack; -- ----------------------------------------------------------------------------------------- package body misc_asm_pack is ------------------------------------------------------------------------------------------ -- vhdl-assembler pseudo opcodes -- set the next opcode to specified address procedure org (constant value : unsigned(31 downto 0)) is begin rom_counter := to_integer(value); end org; ----------------------------------------------------------------------------------------- procedure dw (variable address : out word_t; constant value : uint32_t) is begin tmp(rom_counter) := value; address := std_logic_vector(to_signed(rom_counter,32)); rom_counter := rom_counter + 1; end dw; ----------------------------------------------------------------------------------------- procedure prog_label (variable address : out std_logic_vector(23 downto 0)) is begin address := std_logic_vector(to_unsigned(rom_counter,24)); end prog_label; ------------------------------------------------------------------------------------------ -- vhdl-assembler opcodes procedure nop is begin tmp(rom_counter) := X"00000000"; rom_counter := rom_counter + 1; end nop; ----------------------------------------------------------------------------------------- procedure rts is begin tmp(rom_counter) := X"00000001"; rom_counter := rom_counter + 1; end rts; ----------------------------------------------------------------------------------------- procedure load_l (constant regnum : unsigned(3 downto 0); constant value : std_logic_vector(15 downto 0)) is begin tmp(rom_counter) := "0101" & std_logic_vector(regnum) & "00000000" & value; rom_counter := rom_counter + 1; end load_l; ----------------------------------------------------------------------------------------- procedure load_h (constant regnum : unsigned(3 downto 0); constant value : std_logic_vector(15 downto 0)) is begin tmp(rom_counter) := "0101" & std_logic_vector(regnum) & "10000000" & value; rom_counter := rom_counter + 1; end load_h; ----------------------------------------------------------------------------------------- procedure add (constant regnumd : unsigned(3 downto 0); constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)) is begin tmp(rom_counter) := "0001" & std_logic_vector(regnumd) & std_logic_vector(regnums1) & std_logic_vector(regnums2) &"0000111000000000"; rom_counter := rom_counter + 1; end add; ----------------------------------------------------------------------------------------- procedure and_r -- and is reserved for VHDL (constant regnumd : unsigned(3 downto 0); constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)) is begin tmp(rom_counter) := "0001" & std_logic_vector(regnumd) & std_logic_vector(regnums1) & std_logic_vector(regnums2) &"0100110000000000"; rom_counter := rom_counter + 1; end and_r; ----------------------------------------------------------------------------------------- procedure outm (constant regnums1 : unsigned(3 downto 0); constant regnums2 : unsigned(3 downto 0)) is begin tmp(rom_counter) := "00100000" & std_logic_vector(regnums1) & std_logic_vector(regnums2) & "0000000000000000"; rom_counter := rom_counter + 1; end outm; ----------------------------------------------------------------------------------------- procedure svr (constant regnumd : unsigned(3 downto 0); constant regnums : unsigned(3 downto 0)) is begin tmp(rom_counter) := "0001" & std_logic_vector(regnumd) & std_logic_vector(regnums) & "00000010" & "111000000000"; rom_counter := rom_counter + 1; end svr; ----------------------------------------------------------------------------------------- procedure jump (constant value : std_logic_vector(23 downto 0)) is begin tmp(rom_counter) := "11101111" & value; rom_counter := rom_counter + 1; end jump; ----------------------------------------------------------------------------------------- procedure call (constant value : std_logic_vector(23 downto 0)) is begin tmp(rom_counter) := "11100000" & value; rom_counter := rom_counter + 1; end call; end package body; -- -----------------------------------------------------------------------------------------