library IEEE; use IEEE.STD_LOGIC_1164.ALL; library STD; use IEEE.NUMERIC_STD.ALL; entity DSPn is port( CLK : in std_logic; CE : in std_logic; RST_N : in std_logic; ENABLE : in std_logic; A0 : in std_logic; DI : in std_logic_vector(7 downto 0); DO : out std_logic_vector(7 downto 0); CS_N : in std_logic; RD_N : in std_logic; WR_N : in std_logic; DP_ADDR : in std_logic_vector(11 downto 0); DP_SEL : in std_logic; VER : in std_logic_vector(2 downto 0);--00-DSP1B, 01-DSP2, 10-DSP3, 11-DSP4 BRK_OUT : out std_logic; DBG_REG : in std_logic_vector(7 downto 0); DBG_DAT_IN : in std_logic_vector(7 downto 0); DBG_DAT_OUT : out std_logic_vector(7 downto 0); DBG_DAT_WR : in std_logic ); end DSPn; architecture rtl of DSPn is constant ACC_A : integer range 0 to 1 := 0; constant ACC_B : integer range 0 to 1 := 1; constant FLAG_OV0 : integer range 0 to 5 := 0; constant FLAG_OV1 : integer range 0 to 5 := 1; constant FLAG_Z : integer range 0 to 5 := 2; constant FLAG_C : integer range 0 to 5 := 3; constant FLAG_S0 : integer range 0 to 5 := 4; constant FLAG_S1 : integer range 0 to 5 := 5; constant INSTR_OP: std_logic_vector(1 downto 0) := "00"; constant INSTR_RT: std_logic_vector(1 downto 0) := "01"; constant INSTR_JP: std_logic_vector(1 downto 0) := "10"; constant INSTR_LD: std_logic_vector(1 downto 0) := "11"; -- IO Registers signal DR : std_logic_vector(15 downto 0); signal SR : std_logic_vector(15 downto 0); signal DP : std_logic_vector(10 downto 0); signal RP : std_logic_vector(10 downto 0); signal PC : std_logic_vector(10 downto 0); type StackRam_t is array (0 to 7) of std_logic_vector(10 downto 0); signal STACK_RAM : StackRam_t; signal SP : unsigned(2 downto 0); signal K, L, M, N : std_logic_vector(15 downto 0); signal P, Q : std_logic_vector(15 downto 0); type Acc_t is array (0 to 1) of std_logic_vector(15 downto 0); signal ACC : Acc_t; type Flags_t is array (0 to 1) of std_logic_vector(5 downto 0); signal FLAGS : Flags_t; signal TR, TRB : std_logic_vector(15 downto 0); signal SI, SO : std_logic_vector(15 downto 0); signal SGN : std_logic_vector(15 downto 0); signal RQM : std_logic; signal DRS, DRC : std_logic; signal USF0, USF1 : std_logic; signal P0, P1 : std_logic; signal EI, DMA : std_logic; signal OP_DST : std_logic_vector(3 downto 0); signal OP_SRC : std_logic_vector(3 downto 0); signal OP_RP : std_logic; signal OP_DPH : std_logic_vector(3 downto 0); signal OP_DPL : std_logic_vector(1 downto 0); signal OP_A : unsigned(0 downto 0); signal OP_ALU : std_logic_vector(3 downto 0); signal OP_P : std_logic_vector(1 downto 0); signal OP_ID : std_logic_vector(15 downto 0); signal OP_NA : std_logic_vector(10 downto 0); signal OP_BRCH : std_logic_vector(8 downto 0); signal OP_INSTR : std_logic_vector(1 downto 0); signal IDB : std_logic_vector(15 downto 0); signal ALU_R : std_logic_vector(15 downto 0); signal PROG_ROM_ADDR : std_logic_vector(12 downto 0); signal PROG_ROM_Q : std_logic_vector(23 downto 0); signal DATA_ROM_ADDR : std_logic_vector(12 downto 0); signal DATA_ROM_Q : std_logic_vector(15 downto 0); signal DATA_RAM_ADDR_A, DATA_RAM_ADDR_B : std_logic_vector(10 downto 0); signal DATA_RAM_Q_A, DATA_RAM_Q_B : std_logic_vector(15 downto 0); signal DATA_RAM_WE : std_logic; signal EN : std_logic; signal RD_Nr, WR_Nr : std_logic_vector(2 downto 0); signal PORT_ACTIVE : std_logic; --debug signal DBG_RUN_LAST : std_logic; signal DBG_DAT_WRr : std_logic; signal DBG_BRK_ADDR : std_logic_vector(10 downto 0) := (others => '1'); signal DBG_CTRL : std_logic_vector(7 downto 0) := (others => '0'); component dp16k_wrapper_8bit generic ( addr_width : natural := 11 ); port ( clock : in STD_LOGIC;
use work.pkg.all;

entity riassoc01 is
  port (v : nat_rec;
        res : out natural);
end riassoc01;

architecture behav of riassoc01 is
begin
  res <= v.a + v.b;
end behav;

entity iassoc01 is
  port (a, b : natural;
        res : out natural);
end iassoc01;

architecture behav of iassoc01 is
begin
  inst : entity work.riassoc01
    port map (v.a => a, v.b => b, res => res);
end behav;
x"D" => L <= OP_ID; when x"E" => TRB <= OP_ID; when others => null; end case; end if; end if; end if; end process; process(CLK, RST_N) variable NEXT_SP : unsigned(2 downto 0); variable NEXT_PC : std_logic_vector(10 downto 0); variable COND : std_logic; begin if RST_N = '0' then STACK_RAM <= (others => (others => '0')); SP <= (others => '0'); PC <= (others => '0'); elsif rising_edge(CLK) then if EN = '1' then NEXT_PC := std_logic_vector(unsigned(PC) + 1); if OP_INSTR = INSTR_RT then NEXT_SP := SP - 1; PC <= STACK_RAM(to_integer((NEXT_SP(2) and VER(2))&NEXT_SP(1 downto 0))); SP <= NEXT_SP; elsif OP_INSTR = INSTR_JP then case OP_BRCH(5 downto 2) is when "0000" => COND := FLAGS(ACC_A)(FLAG_C) xor (not OP_BRCH(1)); when "0001" => COND := FLAGS(ACC_B)(FLAG_C) xor (not OP_BRCH(1)); when "0010" => COND := FLAGS(ACC_A)(FLAG_Z) xor (not OP_BRCH(1)); when "0011" => COND := FLAGS(ACC_B)(FLAG_Z) xor (not OP_BRCH(1)); when "0100" => COND := FLAGS(ACC_A)(FLAG_OV0) xor (not OP_BRCH(1)); when "0101" => COND := FLAGS(ACC_B)(FLAG_OV0) xor (not OP_BRCH(1)); when "0110" => COND := FLAGS(ACC_A)(FLAG_OV1) xor (not OP_BRCH(1)); when "0111" => COND := FLAGS(ACC_B)(FLAG_OV1) xor (not OP_BRCH(1)); when "1000" => COND := FLAGS(ACC_A)(FLAG_S0) xor (not OP_BRCH(1)); when "1001" => COND := FLAGS(ACC_B)(FLAG_S0) xor (not OP_BRCH(1)); when "1010" => COND := FLAGS(ACC_A)(FLAG_S1) xor (not OP_BRCH(1)); when "1011" => COND := FLAGS(ACC_B)(FLAG_S1) xor (not OP_BRCH(1)); when "1100" => if (DP(3 downto 0) = (0 to 3 => OP_BRCH(1)) and OP_BRCH(0) = '0') or (DP(3 downto 0) /= (0 to 3 => OP_BRCH(1)) and OP_BRCH(0) = '1') then COND := '1'; else COND := '0'; end if; when "1111" => COND := RQM xor (not OP_BRCH(1)); when others => COND := '0'; end case; if OP_BRCH = "000000000" then PC <= SO(10 downto 0); elsif OP_BRCH(8 downto 6) = "010" and COND = '1' then PC <= OP_NA; elsif OP_BRCH(8 downto 7) = "10" and OP_BRCH(5 downto 0) = "000000" then PC <= OP_NA; if OP_BRCH(6) = '1' then STACK_RAM(to_integer((SP(2) and VER(2))&SP(1 downto 0))) <= NEXT_PC; SP <= SP + 1; end if; else PC <= NEXT_PC; end if; else PC <= NEXT_PC; end if; end if; end if; end process; PROG_ROM_ADDR <= std_logic_vector(unsigned(PC) + ("0"&x"000")) when VER="000" else std_logic_vector(unsigned(PC) + ("0"&x"500")) when VER="001" else std_logic_vector(unsigned(PC) + ("0"&x"C00")) when VER="010" else std_logic_vector(unsigned(PC) + ("1"&x"254")) when VER="011" else std_logic_vector(unsigned(PC) + ("1"&x"954")); PROG_ROM : sprom_verilog generic map(13, 24, 7018, "../src/chip/DSP/dsp1b23410_p.hex") port map( clock => CLK, address => PROG_ROM_ADDR, q => PROG_ROM_Q ); DATA_ROM_ADDR <= VER(2 downto 1) & (VER(0) or (RP(10) and VER(2))) & RP(9 downto 0); DATA_ROM : sprom_verilog generic map(13, 16, 6144, "../src/chip/DSP/dsp1b23410_d.hex") port map( clock => CLK, address => DATA_ROM_ADDR, q => DATA_ROM_Q ); DATA_RAM_ADDR_A <= "000" & DP(7 downto 0) when VER(2)='0' else DP; DATA_RAM_ADDR_B <= DP_ADDR(11 downto 1) when DP_SEL = '1' and (WR_N = '0' or RD_N = '0') else DATA_RAM_ADDR_A or x"40"; DATA_RAM_WE <= '1' when OP_INSTR /= INSTR_JP and OP_DST = x"F" and EN = '1' else '0'; DATA_RAML : dp16k_wrapper_8bit generic map(11) port map( clock => CLK, address_a => DATA_RAM_ADDR_A, data_a => OP_ID(7 downto 0), wren_a => DATA_RAM_WE, q_a => DATA_RAM_Q_A(7 downto 0), address_b => DATA_RAM_ADDR_B, data_b => DI, wren_b => not WR_N and DP_SEL and not DP_ADDR(0), q_b => DATA_RAM_Q_B(7 downto 0) ); DATA_RAMH : dp16k_wrapper_8bit generic map(11) port map( clock => CLK, address_a => DATA_RAM_ADDR_A, data_a => OP_ID(15 downto 8), wren_a => DATA_RAM_WE, q_a => DATA_RAM_Q_A(15 downto 8), address_b => DATA_RAM_ADDR_B, data_b => DI, wren_b => not WR_N and DP_SEL and DP_ADDR(0), q_b => DATA_RAM_Q_B(15 downto 8) ); --I/O Ports process(CLK, RST_N) begin if RST_N = '0' then DRS <= '0'; RQM <= '0'; DR <= (others => '0'); WR_Nr <= (others => '1'); RD_Nr <= (others => '1'); PORT_ACTIVE <= '0'; elsif rising_edge(CLK) then if ENABLE = '1' then WR_Nr <= WR_Nr(1 downto 0) & WR_N; RD_Nr <= RD_Nr(1 downto 0) & RD_N; if WR_Nr = "110" and CS_N = '0' and A0 = '0' then if DRC = '0' then if DRS = '0' then DR(7 downto 0) <= DI; else DR(15 downto 8) <= DI; end if; else DR(7 downto 0) <= DI; end if; PORT_ACTIVE <= '1'; elsif RD_Nr = "110" and CS_N = '0' and A0 = '0' then PORT_ACTIVE <= '1'; end if; if (WR_Nr = "001" or RD_Nr = "001") and PORT_ACTIVE = '1' then if DRC = '0' then if DRS = '0' then DRS <= '1'; else RQM <= '0'; DRS <= '0'; end if; else RQM <= '0'; end if; PORT_ACTIVE <= '0'; elsif EN = '1' then if OP_INSTR /= INSTR_JP and OP_DST = x"6" then DR <= OP_ID; RQM <= '1'; elsif (OP_INSTR = INSTR_OP or OP_INSTR = INSTR_RT) and OP_SRC = x"8" then RQM <= '1'; end if; end if; end if; end if; end process; process( A0, SR, DR, DRC, DRS, DP_SEL, DP_ADDR, DATA_RAM_Q_B ) begin if DP_SEL = '1' then if DP_ADDR(0) = '0' then DO <= DATA_RAM_Q_B(7 downto 0); else DO <= DATA_RAM_Q_B(15 downto 8); end if; elsif A0 = '1' then DO <= SR(15 downto 8); else if DRC = '0' then if DRS = '0' then DO <= DR(7 downto 0); else DO <= DR(15 downto 8); end if; else DO <= DR(7 downto 0); end if; end if; end process; --Debug process(CLK, RST_N) begin if RST_N = '0' then BRK_OUT <= '0'; DBG_RUN_LAST <= '0'; elsif rising_edge(CLK) then if EN = '1' then BRK_OUT <= '0'; if DBG_CTRL(0) = '1' then --step BRK_OUT <= '1'; elsif DBG_CTRL(2) = '1' and DBG_BRK_ADDR = PC then --opcode address break BRK_OUT <= '1'; end if; end if; DBG_RUN_LAST <= DBG_CTRL(7); if DBG_CTRL(7) = '1' and DBG_RUN_LAST = '0' then BRK_OUT <= '0'; end if; end if; end process; process( RST_N, CLK, DBG_REG, ACC, FLAGS, PC, RP, DP, TR, TRB, K, L, M, N, DR, SR, SP, IDB ) begin case DBG_REG is when x"00" => DBG_DAT_OUT <= ACC(ACC_A)(7 downto 0); when x"01" => DBG_DAT_OUT <= ACC(ACC_A)(15 downto 8); when x"02" => DBG_DAT_OUT <= ACC(ACC_B)(7 downto 0); when x"03" => DBG_DAT_OUT <= ACC(ACC_B)(15 downto 8); when x"04" => DBG_DAT_OUT <= "00"&FLAGS(ACC_A); when x"05" => DBG_DAT_OUT <= "00"&FLAGS(ACC_B); when x"06" => DBG_DAT_OUT <= PC(7 downto 0); when x"07" => DBG_DAT_OUT <= "00000"&PC(10 downto 8); when x"08" => DBG_DAT_OUT <= RP(7 downto 0); when x"09" => DBG_DAT_OUT <= "000000"&RP(9 downto 8); when x"0A" => DBG_DAT_OUT <= DP(7 downto 0); when x"0B" => DBG_DAT_OUT <= TR(7 downto 0); when x"0C" => DBG_DAT_OUT <= TR(15 downto 8); when x"0D" => DBG_DAT_OUT <= TRB(7 downto 0); when x"0E" => DBG_DAT_OUT <= TRB(15 downto 8); when x"0F" => DBG_DAT_OUT <= K(7 downto 0); when x"10" => DBG_DAT_OUT <= K(15 downto 8); when x"11" => DBG_DAT_OUT <= L(7 downto 0); when x"12" => DBG_DAT_OUT <= L(15 downto 8); when x"13" => DBG_DAT_OUT <= M(7 downto 0); when x"14" => DBG_DAT_OUT <= M(15 downto 8); when x"15" => DBG_DAT_OUT <= N(7 downto 0); when x"16" => DBG_DAT_OUT <= N(15 downto 8); when x"17" => DBG_DAT_OUT <= DR(7 downto 0); when x"18" => DBG_DAT_OUT <= DR(15 downto 8); when x"19" => DBG_DAT_OUT <= SR(7 downto 0); when x"1A" => DBG_DAT_OUT <= SR(15 downto 8); when x"1B" => DBG_DAT_OUT <= "00000" & std_logic_vector(SP); when x"1C" => DBG_DAT_OUT <= IDB(7 downto 0); when x"1D" => DBG_DAT_OUT <= IDB(15 downto 8); when others => DBG_DAT_OUT <= x"00"; end case; if RST_N = '0' then DBG_DAT_WRr <= '0'; elsif rising_edge(CLK) then DBG_DAT_WRr <= DBG_DAT_WR; if DBG_DAT_WR = '1' and DBG_DAT_WRr = '0' then case DBG_REG is when x"80" => DBG_BRK_ADDR(7 downto 0) <= DBG_DAT_IN; when x"81" => DBG_BRK_ADDR(10 downto 8) <= DBG_DAT_IN(2 downto 0); when x"82" => null; when x"83" => DBG_CTRL <= DBG_DAT_IN; when others => null; end case; end if; end if; end process; end rtl;