package common_pkg is
+
constant WORD_WIDTH : INTEGER := 32;
constant HWORD_WIDTH : INTEGER := 16;
constant BYTE_WIDTH : INTEGER := 8;
constant OPCODE_WIDTH : INTEGER := 5;
constant DISPL_WIDTH : INTEGER := 15;
+
+ subtype byte_t is std_logic_vector(BYTE_WIDTH-1 downto 0);
+ subtype hword_t is std_logic_vector(HWORD_WIDTH-1 downto 0);
+ subtype word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
+
+ subtype gp_register_t is word_t;
+
constant REG_ZERO : gp_register_t := (others => '0');
constant NUM_OP_OPT_WIDTH : INTEGER := 5;
constant COND_WIDTH : INTEGER := 4;
- subtype byte_t is std_logic_vector(BYTE_WIDTH-1 downto 0);
- subtype hword_t is std_logic_vector(HWORD_WIDTH-1 downto 0);
- subtype word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
subtype instruction_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
subtype instruction_addr_t is std_logic_vector(INSTR_ADDR_WIDTH-1 downto 0);
- subtype gp_register_t is word_t;
subtype gp_addr_t is unsigned(REG_ADDR_WIDTH-1 downto 0);
subtype data_ram_word_t is std_logic_vector(WORD_WIDTH-1 downto 0);
subtype data_ram_addr_t is std_logic_vector(DATA_ADDR_WIDTH-1 downto 0);
constant PSW_DISABLE : integer := 4;
-
-
-
type op_info_t is (ADDSUB_OP,AND_OP,OR_OP, XOR_OP,SHIFT_OP);
subtype op_opt_rec is std_logic_vector(NUM_OP_OPT_WIDTH-1 downto 0);
- type dec_op is
+
+ type instruction_rec is record
+
+ predicates : std_logic_vector(3 downto 0);
+
+ opcode : opcode_t;
+
+ reg_dest_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+ reg_src1_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+ reg_src2_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+
+ immediate : std_logic_vector(WORD_WIDTH-1 downto 0);
+ displacement : std_logic_vector(DISPL_WIDTH-1 downto 0);
+
+ jmptype : std_logic_vector(1 downto 0);
+
+ carry, sreg_update, high_low, fill, signext, bp, arith, left_right : std_logic;
+
+ end record;
+
+
+ type read_through_write_rec is record
+
+ rtw_reg : gp_register_t;
+ rtw_reg1 : std_logic;
+ rtw_reg2 : std_logic;
+
+ end record;
+
+ type dec_op is record
condition : condition_t;
op_group : op_info_t;
op_detail : op_opt_rec;
saddr1 : gp_addr_t;
saddr2 : gp_addr_t;
- daddr : gp_addr_t
+ daddr : gp_addr_t;
- end record dec_op;
+ end record;
+
+
+
function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector;
function log2c(constant value : in integer range 0 to integer'high) return integer;
end package common_pkg;
-package body common_pkg;
+package body common_pkg is
function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector is
begin
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
reg_we : in std_logic;
--Data outputs
- reg1_rd_data : gp_register_t;
- reg2_rd_data : gp_register_t;
- branch_prediction_res : instruction_word_t;
- branch_prediction_bit : std_logic
+ reg1_rd_data : out gp_register_t;
+ reg2_rd_data : out gp_register_t;
+ branch_prediction_res : out instruction_word_t;
+ branch_prediction_bit : out std_logic
);
end component decode_stage;
+ component decoder is
+
+ port(
+ instruction : in instruction_word_t;
+ instr_spl : out instruction_rec
+
+ );
+
+ end component decoder;
component execute_stage is
generic (
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
--System inputs
clk : in std_logic;
- reset : in std_logic;
+ reset : in std_logic
);
end component execute_stage;
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
--System inputs
clk : in std_logic;
- reset : in std_logic;
+ reset : in std_logic
);
end component writeback_stage;
- type instruction_rec is record
-
- predicates : std_logic_vector(3 downto 0);
-
- opcode : opcode_t;
-
- reg_dest_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
- reg_src1_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
- reg_src2_addr : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
-
- immediate : std_logic_vector(WORD_WIDTH-1 downto 0);
- displacement : std_logic_vector(DISPL_WIDTH-1 downto 0);
-
- jmptype : std_logic_vector(1 downto 0);
-
- carry, sreg_update, high_low, fill, signext, bp, arith, left_right : std_logic;
-
- end record;
-
-
- type read_through_write_rec is record
-
- rtw_reg : gp_register_t;
- rtw_reg1 : std_logic;
- rtw_reg2 : std_logic;
-
- end record;
end package core_pkg;
use work.core_pkg.all;
use work.common_pkg.all;
+
entity decode_stage is
generic (
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
reg_we : in std_logic;
--Data outputs
- reg1_rd_data : gp_register_t;
- reg2_rd_data : gp_register_t;
- branch_prediction_res : instruction_word_t;
- branch_prediction_bit : std_logic
+ reg1_rd_data : out gp_register_t;
+ reg2_rd_data : out gp_register_t;
+ branch_prediction_res : out instruction_word_t;
+ branch_prediction_bit : out std_logic
);
end decode_stage;
+
+
library IEEE;
+
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use work.core_pkg.all;
use work.common_pkg.all;
+
+
architecture behav of decode_stage is
signal instr_spl : instruction_rec;
)
port map (
- sys_clk,
+ clk,
reg_w_addr,
instr_spl.reg_src1_addr,
instr_spl.reg_src2_addr,
);
+ decoder_inst : decoder
+
+ port map (
+ instruction,
+ instr_spl
+ );
-- sync process for read through write registers
-syn: process(sys_clk, reset)
+syn: process(clk, reset)
begin
rtw_rec.rtw_reg <= (others => '0');
rtw_rec.rtw_reg1 <= '0';
rtw_rec.rtw_reg2 <= '0';
- elsif rising_edge(sys_clk) then
+ elsif rising_edge(clk) then
rtw_rec <= rtw_rec_nxt;
end if;
-- async process: decides between memory and read-through-write buffer on output
-output: process(rtw_rec)
+output: process(rtw_rec, reg1_mem_data, reg2_mem_data)
begin
if (rtw_rec.rtw_reg1 = '1') then
rtw_rec_nxt.rtw_reg1 <= '0';
rtw_rec_nxt.rtw_reg2 <= '0';
- if (reg_w_addr = instr_spl.reg_src_1_addr) then
+ if (reg_w_addr = instr_spl.reg_src1_addr) then
rtw_rec_nxt.rtw_reg1 <= '1';
end if;
- if (reg_w_addr = instr_spl.reg_src_2_addr) then
+ if (reg_w_addr = instr_spl.reg_src2_addr) then
rtw_rec_nxt.rtw_reg2 <= '1';
end if;
end process;
-
--- async process: sign extension
-sign_ext: process(instr_spl)
-
-variable instr_s : instruction_rec;
-
-begin
-
- instr_s := instr_spl;
-
- -- currently no sign extension in jump implemented
-
- if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
- if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
- instr_s.immediate(31 downto 12) <= (others => '1');
- end if;
- if (instr_s.opcode = "11010") then
- instr_s.immediate(31 downto 16) <= (others => '1');
- end if;
- end if;
-
- instr_spl <= instr_s;
-
-end process;
-
-
--- async process: decodes instruction
-split_instr: process(instruction)
-
-variable instr_s : instruction_rec;
-
-begin
-
- instr_s.predicates := instruction(31 downto 28);
- instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
-
- instr_s.reg_dest_addr := (others => '0');
- instr_s.reg_src1_addr := (others => '0');
- instr_s.reg_src2_addr := (others => '0');
-
- instr_s.immediate := (others => '0');
- instr_s.displacement := (others => '0');
- instr_s.jmptype := (others => '0');
- instr_s.carry := '0';
- instr_s.sreg_update := '0';
- instr_s.high_low := '0';
- instr_s.fill := '0';
- instr_s.signext := '0';
- instr_s.bp := '0';
- instr_s.arith := '0';
-
--- special function register operations missing
-
--- case opcode is
---=================================================================
- if (instr_s.opcode = "00000" or instr_s.opcode = "00001" or instr_s.opcode = "00100" or instr_s.opcode = "00110" or instr_s.opcode = "01000") then
--- when "00000" => --add
- instr_s.reg_dest_addr := instruction(22 downto 19);
- instr_s.reg_src1_addr := instruction(18 downto 15);
- instr_s.reg_src2_addr := instruction(14 downto 11);
- instr_s.carry := instruction(1);
- instr_s.sreg_update := instruction(0);
- end if;
--- when "00001" => --sub
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.reg_src2_addr := instruction(14 downto 11);
--- instr_s.carry := instruction(1);
--- instr_s.sreg_update := instruction(0);
-
-
--- when "00100" => --and
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.reg_src2_addr := instruction(14 downto 11);
--- instr_s.carry := instruction(1); --negligible
--- instr_s.sreg_update := instruction(0);
-
--- when "00110" => --or
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.reg_src2_addr := instruction(14 downto 11);
--- instr_s.carry := instruction(1); --negligible
--- instr_s.sreg_update := instruction(0);
-
--- when "01000" => --xor
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.reg_src2_addr := instruction(14 downto 11);
--- instr_s.carry := instruction(1); --negligible
--- instr_s.sreg_update := instruction(0);
-
---=================================================================
- if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
-
--- when "00010" => --addi
- instr_s.reg_dest_addr := instruction(22 downto 19);
- instr_s.reg_src1_addr := instruction(18 downto 15);
- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
- instr_s.signext := instruction(2);
- instr_s.carry := instruction(1);
- instr_s.sreg_update := instruction(0);
- end if;
-
--- when "00011" => --subi
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
--- instr_s.signext := instruction(2);
--- instr_s.carry := instruction(1);
--- instr_s.sreg_update := instruction(0);
-
---=================================================================
- if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
-
--- when "00101" => --andx
- instr_s.reg_dest_addr := instruction(22 downto 19);
- instr_s.reg_src1_addr := instruction(22 downto 19);
- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
- instr_s.high_low := instruction(2);
- instr_s.fill := instruction(1);
- instr_s.sreg_update := instruction(0);
- end if;
-
--- when "00111" => --orx
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
--- instr_s.high_low := instruction(2);
--- instr_s.fill := instruction(1);
--- instr_s.sreg_update := instruction(0);
---
--- when "01001" => --xorx
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
--- instr_s.high_low := instruction(2);
--- instr_s.fill := instruction(1);
--- instr_s.sreg_update := instruction(0);
---
---=================================================================
- if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
-
--- when "01010" => --shift
- instr_s.reg_dest_addr := instruction(22 downto 19);
- instr_s.reg_src1_addr := instruction(18 downto 15);
- instr_s.immediate(4 downto 0) := instruction(14 downto 10);
- instr_s.left_right := instruction(3);
- instr_s.arith := instruction(2);
- instr_s.carry := instruction(1);
- instr_s.sreg_update := instruction(0);
- end if;
-
--- when "01011" => --stackop
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
--- instr_s.left_right := instruction(3);
--- instr_s.arith := instruction(2);
--- instr_s.carry := instruction(1);
--- instr_s.sreg_update := instruction(0);
-
---=================================================================
- if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
-
--- when "01110" => --ldw
- instr_s.reg_dest_addr := instruction(22 downto 19);
- instr_s.reg_src1_addr := instruction(18 downto 15);
- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
- instr_s.signext := instruction(2);
- instr_s.high_low := instruction(1);
- end if;
-
--- when "10000" => --ldh
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
--- instr_s.signext := instruction(2);
--- instr_s.high_low := instruction(1);
-
--- when "10010" => --ldb
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
--- instr_s.signext := instruction(2);
--- instr_s.high_low := instruction(1);
-
--- when "11010" => --ldi
--- instr_s.reg_dest_addr := instruction(22 downto 19);
--- instr_s.reg_src1_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
--- instr_s.signext := instruction(2);
--- instr_s.high_low := instruction(1);
-
---=================================================================
- if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
-
- --when "01111" => --stw
- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
- instr_s.reg_src2_addr := instruction(18 downto 15); -- mem addr
- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
- end if;
-
--- when "10001" => --sth
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.reg_src2_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
-
--- when "10011" => --stb
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.reg_src2_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
-
--- when "10101" => --stx
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.reg_src2_addr := instruction(18 downto 15);
--- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
-
---=================================================================
- if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
-
--- when "10110" => --jumpop
- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
- instr_s.immediate(15 downto 0) := instruction(22 downto 7);
- instr_s.bp := instruction(1);
- instr_s.jmptype := instruction(3 downto 2);
- instr_s.signext := instruction(0);
- end if;
-
--- when "10111" => --brreg
--- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
--- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
--- instr_s.bp := instruction(1); -- negligible
--- instr_s.jmptype := instruction(3 downto 2); -- only lsb
--- instr_s.signext := instruction(0); -- negligible
-
---=================================================================
- if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
-
--- when "11000" => --cmp
- instr_s.reg_src1_addr := instruction(22 downto 19);
- instr_s.reg_src2_addr := instruction(18 downto 15);
- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
- end if;
-
--- when "11001" => --cmpi
--- instr_s.reg_src1_addr := instruction(22 downto 19);
--- instr_s.reg_src2_addr := instruction(18 downto 15);
--- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
-
--- when others => null;
-
--- end case;
-
- instr_spl <= instr_s;
-
-end process;
-
end behav;
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.core_pkg.all;
+use work.common_pkg.all;
+
+entity decoder is
+
+ port (
+ instruction : in instruction_word_t;
+ instr_spl : out instruction_rec
+ );
+
+end decoder;
+
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.mem_pkg.all;
+use work.core_pkg.all;
+use work.common_pkg.all;
+
+
+architecture behav_d of decoder is
+
+begin
+
+split_instr: process(instruction)
+
+variable instr_s : instruction_rec;
+
+begin
+
+ instr_s.predicates := instruction(31 downto 28);
+ instr_s.opcode := instruction(27 downto 27-OPCODE_WIDTH+1);
+
+ instr_s.reg_dest_addr := (others => '0');
+ instr_s.reg_src1_addr := (others => '0');
+ instr_s.reg_src2_addr := (others => '0');
+
+ instr_s.immediate := (others => '0');
+ instr_s.displacement := (others => '0');
+ instr_s.jmptype := (others => '0');
+ instr_s.carry := '0';
+ instr_s.sreg_update := '0';
+ instr_s.high_low := '0';
+ instr_s.fill := '0';
+ instr_s.signext := '0';
+ instr_s.bp := '0';
+ instr_s.arith := '0';
+
+-- special function register operations missing
+
+-- case opcode is
+--=================================================================
+ if (instr_s.opcode = "00000" or instr_s.opcode = "00001" or instr_s.opcode = "00100" or instr_s.opcode = "00110" or instr_s.opcode = "01000") then
+-- when "00000" => --add
+ instr_s.reg_dest_addr := instruction(22 downto 19);
+ instr_s.reg_src1_addr := instruction(18 downto 15);
+ instr_s.reg_src2_addr := instruction(14 downto 11);
+ instr_s.carry := instruction(1);
+ instr_s.sreg_update := instruction(0);
+ end if;
+-- when "00001" => --sub
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.reg_src2_addr := instruction(14 downto 11);
+-- instr_s.carry := instruction(1);
+-- instr_s.sreg_update := instruction(0);
+
+
+-- when "00100" => --and
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.reg_src2_addr := instruction(14 downto 11);
+-- instr_s.carry := instruction(1); --negligible
+-- instr_s.sreg_update := instruction(0);
+
+-- when "00110" => --or
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.reg_src2_addr := instruction(14 downto 11);
+-- instr_s.carry := instruction(1); --negligible
+-- instr_s.sreg_update := instruction(0);
+
+-- when "01000" => --xor
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.reg_src2_addr := instruction(14 downto 11);
+-- instr_s.carry := instruction(1); --negligible
+-- instr_s.sreg_update := instruction(0);
+
+--=================================================================
+ if (instr_s.opcode = "00010" or instr_s.opcode = "00011") then
+
+-- when "00010" => --addi
+ instr_s.reg_dest_addr := instruction(22 downto 19);
+ instr_s.reg_src1_addr := instruction(18 downto 15);
+ instr_s.immediate(11 downto 0) := instruction(14 downto 3);
+ instr_s.signext := instruction(2);
+ instr_s.carry := instruction(1);
+ instr_s.sreg_update := instruction(0);
+
+ if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
+ instr_s.immediate(31 downto 12) := (others => '1');
+ end if;
+ end if;
+
+
+-- when "00011" => --subi
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.immediate(11 downto 0) := instruction(14 downto 3);
+-- instr_s.signext := instruction(2);
+-- instr_s.carry := instruction(1);
+-- instr_s.sreg_update := instruction(0);
+
+
+
+
+--=================================================================
+ if (instr_s.opcode = "00101" or instr_s.opcode = "00111" or instr_s.opcode = "01001") then
+
+-- when "00101" => --andx
+ instr_s.reg_dest_addr := instruction(22 downto 19);
+ instr_s.reg_src1_addr := instruction(22 downto 19);
+ instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+ instr_s.high_low := instruction(2);
+ instr_s.fill := instruction(1);
+ instr_s.sreg_update := instruction(0);
+ end if;
+
+-- when "00111" => --orx
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+-- instr_s.high_low := instruction(2);
+-- instr_s.fill := instruction(1);
+-- instr_s.sreg_update := instruction(0);
+--
+-- when "01001" => --xorx
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+-- instr_s.high_low := instruction(2);
+-- instr_s.fill := instruction(1);
+-- instr_s.sreg_update := instruction(0);
+--
+--=================================================================
+ if (instr_s.opcode = "01010" or instr_s.opcode = "01011") then
+
+-- when "01010" => --shift
+ instr_s.reg_dest_addr := instruction(22 downto 19);
+ instr_s.reg_src1_addr := instruction(18 downto 15);
+ instr_s.immediate(4 downto 0) := instruction(14 downto 10);
+ instr_s.left_right := instruction(3);
+ instr_s.arith := instruction(2);
+ instr_s.carry := instruction(1);
+ instr_s.sreg_update := instruction(0);
+ end if;
+
+-- when "01011" => --stackop
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.immediate(1 downto 0) := instruction(18 downto 17);
+-- instr_s.left_right := instruction(3);
+-- instr_s.arith := instruction(2);
+-- instr_s.carry := instruction(1);
+-- instr_s.sreg_update := instruction(0);
+
+--=================================================================
+ if (instr_s.opcode = "01110" or instr_s.opcode = "10000" or instr_s.opcode = "10010" or instr_s.opcode = "11010") then
+
+-- when "01110" => --ldw
+ instr_s.reg_dest_addr := instruction(22 downto 19);
+ instr_s.reg_src1_addr := instruction(18 downto 15);
+ instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+ instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+ instr_s.signext := instruction(2);
+ instr_s.high_low := instruction(1);
+
+ if (instr_s.signext = '1' and instr_s.immediate(11) = '1') then
+ instr_s.immediate(31 downto 16) := (others => '1');
+ end if;
+ end if;
+
+-- when "10000" => --ldh
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+-- instr_s.signext := instruction(2);
+-- instr_s.high_low := instruction(1);
+
+-- when "10010" => --ldb
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+-- instr_s.signext := instruction(2);
+-- instr_s.high_low := instruction(1);
+
+-- when "11010" => --ldi
+-- instr_s.reg_dest_addr := instruction(22 downto 19);
+-- instr_s.reg_src1_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+-- instr_s.signext := instruction(2);
+-- instr_s.high_low := instruction(1);
+
+--=================================================================
+ if (instr_s.opcode = "01111" or instr_s.opcode = "10001" or instr_s.opcode = "10011" or instr_s.opcode = "10101") then
+
+ --when "01111" => --stw
+ instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
+ instr_s.reg_src2_addr := instruction(18 downto 15); -- mem addr
+ instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+ end if;
+
+-- when "10001" => --sth
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.reg_src2_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+
+-- when "10011" => --stb
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.reg_src2_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+
+-- when "10101" => --stx
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.reg_src2_addr := instruction(18 downto 15);
+-- instr_s.displacement(14 downto 0) := instruction(14 downto 0);
+
+--=================================================================
+ if (instr_s.opcode = "10110" or instr_s.opcode = "10111") then
+
+-- when "10110" => --jumpop
+ instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
+ instr_s.immediate(15 downto 0) := instruction(22 downto 7);
+ instr_s.bp := instruction(1);
+ instr_s.jmptype := instruction(3 downto 2);
+ instr_s.signext := instruction(0);
+ end if;
+
+-- when "10111" => --brreg
+-- instr_s.reg_src1_addr := instruction(22 downto 19); -- register value
+-- instr_s.immediate(15 downto 0) := instruction(22 downto 7); -- negligible
+-- instr_s.bp := instruction(1); -- negligible
+-- instr_s.jmptype := instruction(3 downto 2); -- only lsb
+-- instr_s.signext := instruction(0); -- negligible
+
+--=================================================================
+ if (instr_s.opcode = "11000" or instr_s.opcode = "11001") then
+
+-- when "11000" => --cmp
+ instr_s.reg_src1_addr := instruction(22 downto 19);
+ instr_s.reg_src2_addr := instruction(18 downto 15);
+ instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+ end if;
+
+-- when "11001" => --cmpi
+-- instr_s.reg_src1_addr := instruction(22 downto 19);
+-- instr_s.reg_src2_addr := instruction(18 downto 15);
+-- instr_s.immediate(15 downto 0) := instruction(18 downto 3);
+
+-- when others => null;
+
+-- end case;
+
+
+
+ instr_spl <= instr_s;
+
+end process;
+
+end behav_d;
+
+
+--===========================================================================
+
+
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
-use work.common_pkg;
+use work.common_pkg.all;
+use work.core_pkg.all;
entity fetch_stage is
-- active reset value
RESET_VALUE : std_logic;
-- active logic value
- LOGIC_ACT : std_logic;
+ LOGIC_ACT : std_logic
);
port(
use work.core_pkg.all;
use work.common_pkg.all;
+use work.mem_pkg.all;
architecture behav of fetch_stage is
)
port map (
- sys_clk,
+ clk,
instr_w_addr(PHYS_INSTR_ADDR_WIDTH-1 downto 0),
instr_r_addr_nxt(PHYS_INSTR_ADDR_WIDTH-1 downto 0),
instr_we,
instr_rd_data
);
-syn: process(sys_clk, reset)
+syn: process(clk, reset)
begin
if (reset = RESET_VALUE) then
instr_r_addr <= (others => '0');
- elsif rising_edge(sys_clk) then
+ elsif rising_edge(clk) then
instr_r_addr <= instr_r_addr_nxt;
end if;
end process;
-asyn: process(instr_r_addr, jump_result, prediction_result, branch_prediction_bit, alu_jump_bit)
+asyn: process(instr_r_addr, jump_result, prediction_result, branch_prediction_bit, alu_jump_bit, instr_rd_data)
begin
--- /dev/null
+library IEEE;
+use IEEE.std_logic_1164.all;
+use IEEE.numeric_std.all;
+
+use work.common_pkg.all;
+use work.core_pkg.all;
+
+-------------------------------------------------------------------------------
+-- ENTITY
+-------------------------------------------------------------------------------
+entity pipeline_tb is
+
+end pipeline_tb;
+
+
+-------------------------------------------------------------------------------
+-- ARCHITECTURE
+-------------------------------------------------------------------------------
+architecture behavior of pipeline_tb is
+
+ constant cc : time := 30 ns; -- test clock period
+
+ signal sys_clk_pin : std_logic;
+ signal sys_res_n_pin : std_logic;
+ --Data input
+
+ signal dummy : std_logic;
+
+ signal jump_result_pin : instruction_addr_t;
+ signal prediction_result_pin : instruction_addr_t;
+ signal branch_prediction_bit_pin : std_logic;
+ signal alu_jump_bit_pin : std_logic;
+ signal instruction_pin : instruction_word_t;
+
+ signal reg_w_addr_pin : std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+ signal reg_wr_data_pin : gp_register_t;
+ signal reg_we_pin : std_logic;
+ signal reg1_rd_data_pin : gp_register_t;
+ signal reg2_rd_data_pin : gp_register_t;
+
+
+begin
+
+-- instruction_ram : r_w_ram
+-- generic map (
+-- PHYS_INSTR_ADDR_WIDTH,
+-- WORD_WIDTH
+-- )
+--
+-- port map (
+-- sys_clk,
+-- instr_w_addr(PHYS_INSTR_ADDR_WIDTH-1 downto 0),
+-- instr_r_addr_nxt(PHYS_INSTR_ADDR_WIDTH-1 downto 0),
+-- instr_we,
+-- instr_wr_data,
+-- instr_rd_data
+-- );
+
+ fetch_st : fetch_stage
+ generic map (
+
+ '0',
+ '1'
+ )
+
+ port map (
+ --System inputs
+ clk => sys_clk_pin, --: in std_logic;
+ reset => sys_res_n_pin, --: in std_logic;
+
+ --Data inputs
+ jump_result => jump_result_pin, --: in instruction_addr_t;
+ prediction_result => prediction_result_pin, --: in instruction_addr_t;
+ branch_prediction_bit => branch_prediction_bit_pin, --: in std_logic;
+ alu_jump_bit => alu_jump_bit_pin, --: in std_logic;
+
+ --Data outputs
+ instruction => instruction_pin --: out instruction_word_t
+ );
+
+ decode_st : decode_stage
+ generic map (
+ -- active reset value
+ '0',
+ -- active logic value
+ '1'
+
+ )
+ port map (
+ --System inputs
+ clk => sys_clk_pin, --: in std_logic;
+ reset => sys_res_n_pin, -- : in std_logic;
+
+ --Data inputs
+ instruction => instruction_pin, --: in instruction_word_t;
+ reg_w_addr => reg_w_addr_pin, --: in std_logic_vector(REG_ADDR_WIDTH-1 downto 0);
+ reg_wr_data => reg_wr_data_pin, --: in gp_register_t;
+ reg_we => reg_we_pin, --: in std_logic;
+
+ --Data outputs
+ reg1_rd_data => reg1_rd_data_pin, --: gp_register_t;
+ reg2_rd_data => reg2_rd_data_pin, --: gp_register_t;
+ branch_prediction_res => prediction_result_pin, --: instruction_word_t;
+ branch_prediction_bit => branch_prediction_bit_pin --: std_logic
+
+ );
+
+
+
+-------------------------------------------------------------------------------
+-- generate simulation clock
+-------------------------------------------------------------------------------
+ CLKGEN : process
+ begin
+ sys_clk_pin <= '1';
+ wait for cc/2;
+ sys_clk_pin <= '0';
+ wait for cc/2;
+ end process CLKGEN;
+
+-------------------------------------------------------------------------------
+-- test the design
+-------------------------------------------------------------------------------
+ TEST_IT : process
+
+ -- wait for n clock cycles
+ procedure icwait(cycles : natural) is
+ begin
+ for i in 1 to cycles loop
+ wait until sys_clk_pin = '1' and sys_clk_pin'event;
+ end loop;
+ end;
+
+ begin
+ -----------------------------------------------------------------------------
+ -- initial reset
+ -----------------------------------------------------------------------------
+ sys_res_n_pin <= '0';
+ reg_w_addr_pin <= (others => '0');
+ reg_wr_data_pin <= (others => '0');
+ reg_we_pin <= '0';
+
+ icwait(10);
+ dummy <= '1';
+ sys_res_n_pin <= '1';
+ wait until sys_res_n_pin = '1';
+
+
+ icwait(100000);
+
+ ---------------------------------------------------------------------------
+ -- exit testbench
+ ---------------------------------------------------------------------------
+ assert false
+ report "Test finished"
+ severity error;
+
+ end process test_it;
+
+end behavior;
+
+
+-------------------------------------------------------------------------------
+-- configuration
+-------------------------------------------------------------------------------
+configuration pipeline_conf_beh of pipeline_tb is
+ for behavior
+ for fetch_st : fetch_stage use entity work.fetch_stage(behav);
+ end for;
+ for decode_st : decode_stage use entity work.decode_stage(behav);
+ end for;
+
+ end for;
+end pipeline_conf_beh;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
+use work.mem_pkg.all;
+
entity r2_w_ram is
generic (
ADDR_WIDTH : integer range 1 to integer'high;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
+use work.mem_pkg.all;
+
architecture behaviour of r2_w_ram is
subtype RAM_ENTRY_TYPE is std_logic_vector(DATA_WIDTH -1 downto 0);
type RAM_TYPE is array (0 to (2**ADDR_WIDTH)-1) of RAM_ENTRY_TYPE;
- signal ram : RAM_TYPE; --:= (others=> x"00");
+ signal ram : RAM_TYPE := (others=> x"00000001");
begin
process(clk)
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
+use work.mem_pkg.all;
+
architecture behaviour of r_w_ram is
subtype RAM_ENTRY_TYPE is std_logic_vector(DATA_WIDTH -1 downto 0);
type RAM_TYPE is array (0 to (2**ADDR_WIDTH)-1) of RAM_ENTRY_TYPE;
- signal ram : RAM_TYPE; --:= (others=> x"00");
+ signal ram : RAM_TYPE := ((others => b"11100000000000001001000000000000"));
begin
process(clk)