LIBRARY ieee; use IEEE.STD_LOGIC_1164.ALL; USE ieee.numeric_std.ALL; entity j1 is Generic ( R_STACK_SIZE : natural := 32; D_STACK_SIZE : natural := 32 ); Port ( sys_clk_i : in std_logic; sys_rst_i : in std_logic; io_din : in unsigned(15 downto 0); io_rd : out std_logic; io_wr : out std_logic; io_addr : out unsigned(15 downto 0); io_dout : out unsigned(15 downto 0); inst_din : in unsigned(15 downto 0); inst_addr : out unsigned(12 downto 0); data_addr : out unsigned(12 downto 0); data_we : out std_logic; data_en : out std_logic; data_din : in unsigned(15 downto 0); data_dout : out unsigned(15 downto 0) ); end j1; architecture behave of j1 is signal insn : unsigned(15 downto 0); signal immediate : unsigned(15 downto 0); signal ramrd : unsigned(15 downto 0); signal dsp : unsigned(4 downto 0); -- Data stack pointer (register) signal dsp2 : unsigned(4 downto 0); -- register signal st0 : unsigned(15 downto 0); -- Return stack pointer (register) signal st02 : unsigned(15 downto 0); -- register signal dstkW2 : std_logic; -- D stack write signal pc : unsigned(12 downto 0); -- register signal pc2 : unsigned(12 downto 0); -- register signal rsp : unsigned(4 downto 0); -- register signal rsp2 : unsigned(4 downto 0); -- register signal rstkW2 : std_logic; -- register signal rstkD2 : unsigned(15 downto 0); -- register signal ramWE2 : std_logic; -- RAM write enable signal pc_plus_1 : unsigned(15 downto 0); type stack_t is array (integer range <>) of unsigned(15 downto 0); signal dstack : stack_t(0 to D_STACK_SIZE-1); -- register signal rstack : stack_t(0 to R_STACK_SIZE-1); -- register signal st1 : unsigned(15 downto 0); signal rst0 : unsigned(15 downto 0); signal st0sel : unsigned(3 downto 0); signal is_alu : BOOLEAN; signal is_lit : BOOLEAN; signal dd : unsigned(1 downto 0); -- D stack delta signal rd : unsigned(1 downto 0); -- R stack delta signal stack_ram_en : std_logic; -- helper for RAM R/W signal stack_ram_we : std_logic; -- helper for RAM R/W begin -- LINE 25: pc_plus_1 <= ("000" & pc) + 1; -- LINE 37: st1 <= dstack(to_integer(dsp)); rst0 <= rstack(to_integer(rsp)); immediate <= '1' & insn(14 downto 0); -- LINE 112: is_alu <= (insn(15 downto 13) = "011"); is_lit <= (insn(15) = '1'); -- LINE 115: io_rd <= '1' when (is_alu and (insn(11 downto 8) = X"C")) else '0'; io_wr <= ramWE2; io_addr <= st0; io_dout <= st1; ramWE2 <= '1' when (is_alu and (insn(5) = '1')) else '0'; dstkW2 <= '1' when (is_lit or (is_alu and insn(7) = '1')) else '0'; dd <= insn(1 downto 0); rd <= insn(3 downto 2); -- LINE 27: -- The D and R stacks proc_d_and_r_stack: process(sys_clk_i) begin if rising_edge(sys_clk_i) then if dstkW2 = '1' then dstack(to_integer(dsp2)) <= st0; end if; if rstkW2 = '1' then rstack(to_integer(rsp2)) <= rstkD2; end if; end if; end process; -- LINE 40: -- st0sel is the ALU operation. For branch and call the operation -- is T, for 0branch it is N. For ALU ops it is loaded from the instruction -- field. proc_aluop_sel: process(insn) begin case insn(14 downto 13) is when "00" => st0sel <= "0000"; when "10" => st0sel <= "0000"; when "01" => st0sel <= "0001"; when "11" => st0sel <= insn(11 downto 8); when others => st0sel <= "XXXX"; end case; end process; -- LINE 55: -- define RAMS outside this module insn <= inst_din; inst_addr <= pc2(12 downto 0); data_en <= not (st02(15) or st02(14)); data_we <= ramWE2 and not (st02(15) or st02(14)); ramrd <= data_din; data_dout <= st1; data_addr <= st02(13 downto 1); -- LINE 85: -- Compute the new value of T. proc_alu: process(insn, immediate, st0sel, st0, st1, rst0, rsp, dsp) begin if insn(15) = '1' then st02 <= immediate; else case st0sel is when "0000" => st02 <= st0; when "0001" => st02 <= st1; when "0010" => st02 <= st0 + st1; when "0011" => st02 <= st0 and st1; when "0100" => st02 <= st0 or st1; when "0101" => st02 <= st0 xor st1; when "0110" => st02 <= not st0; when "0111" => if st1 = st0 then st02 <= X"FFFF"; else st02 <= X"0000"; end if; when "1000" => if signed(st1) < signed(st0) then st02 <= X"FFFF"; else st02 <= X"0000"; end if; when "1001" => st02 <= st1 srl to_integer(st0(3 downto 0)); when "1010" => st02 <= st0 - 1; when "1011" => st02 <= rst0; when "1100" => if st0(15) = '1' or st0(14) = '1' then -- LINE 104: ???? st02 <= io_din; else st02 <= ramrd; end if; when "1101" => st02 <= st1 sll to_integer(st0(3 downto 0)); when "1110" => st02 <= "000" & rsp & "000" & dsp; -- LINE 106: ???? when "1111" => if st1 < st0 then st02 <= X"FFFF"; else st02 <= X"0000"; end if; when others => st02 <= "XXXXXXXXXXXXXXXX"; end case; end if; end process; -- LINE 126: proc_stack_ctrl: process(is_lit, is_alu, pc2, dd, rd, insn, st0, pc_plus_1, rsp, dsp) begin if is_lit then -- literal dsp2 <= dsp + 1; rsp2 <= rsp; rstkW2 <= '0'; rstkD2 <= "000" & pc2; elsif is_alu then dsp2 <= dsp + (dd(1) & dd(1) & dd(1) & dd); rsp2 <= rsp + (rd(1) & rd(1) & rd(1) & rd); rstkW2 <= insn(6); rstkD2 <= st0; else -- jump/call -- predicated jump is like DROP if insn(15 downto 13) = "001" then dsp2 <= dsp - 1; else dsp2 <= dsp; -- *default end if; if insn(15 downto 13) = "010" then -- call rsp2 <= rsp + 1; rstkW2 <= '1'; rstkD2 <= pc_plus_1(14 downto 0) & '0'; else rsp2 <= rsp; -- *default rstkW2 <= '0'; -- *default rstkD2 <= "000" & pc2; -- *default end if; end if; end process; -- LINE 157: proc_pc: process(sys_rst_i, is_alu, insn, pc, st0, rst0, pc_plus_1) begin if sys_rst_i = '1' then pc2 <= pc; else if ((insn(15 downto 13) = "000") or ((insn(15 downto 13) = "001") and (st0 = X"0000")) or (insn(15 downto 13) = "010")) then pc2 <= insn(12 downto 0); elsif is_alu and (insn(12) = '1') then -- return pc2 <= rst0(13 downto 1); -- LINE 167: ???? else pc2 <= pc_plus_1(12 downto 0); -- LINE 169: truncation ???? end if; end if; end process; -- LINE 172: proc_next: process(sys_clk_i) begin if rising_edge(sys_clk_i) then if sys_rst_i = '1' then pc <= (others => '0'); dsp <= (others => '0'); st0 <= (others => '0'); rsp <= (others => '0'); else dsp <= dsp2; pc <= pc2; st0 <= st02; rsp <= rsp2; end if; end if; end process; end behave;