fetch und decode kompilierbar, generelle tb, änderung in pkgs, eigene decoder entity
authorStefan <stefan@ubuntu.ubuntu-domain>
Sun, 14 Nov 2010 14:10:43 +0000 (15:10 +0100)
committerStefan <stefan@ubuntu.ubuntu-domain>
Sun, 14 Nov 2010 14:10:43 +0000 (15:10 +0100)
12 files changed:
cpu/src/common_pkg.vhd
cpu/src/core_pkg.vhd
cpu/src/decode_stage.vhd
cpu/src/decode_stage_b.vhd
cpu/src/decoder.vhd [new file with mode: 0644]
cpu/src/decoder_b.vhd [new file with mode: 0644]
cpu/src/fetch_stage.vhd
cpu/src/fetch_stage_b.vhd
cpu/src/pipeline_tb.vhd [new file with mode: 0644]
cpu/src/r2_w_ram.vhd
cpu/src/r2_w_ram_b.vhd
cpu/src/r_w_ram_b.vhd

index 46434bcf991648fa24da65974733342c8507c1b1..c54829bc81b60da2c7b2016ce8549af3c1daa33a 100644 (file)
@@ -5,12 +5,20 @@ use IEEE.numeric_std.all;
 
 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');
 
@@ -23,14 +31,10 @@ package common_pkg is
        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);
@@ -53,13 +57,39 @@ package common_pkg is
        
        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;
@@ -71,15 +101,18 @@ package common_pkg is
                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
index 57abe47e3e4a45e77af38148166aca61a565e37c..335ffb6876eec9f85eb5eb2d1515d1522052c8b5 100644 (file)
@@ -12,7 +12,7 @@ package core_pkg is
                        -- active reset value
                        RESET_VALUE : std_logic;
                        -- active logic value
-                       LOGIC_ACT : std_logic;
+                       LOGIC_ACT : std_logic
                        
                        );
        port(
@@ -39,7 +39,7 @@ package core_pkg is
                        -- active reset value
                        RESET_VALUE : std_logic;
                        -- active logic value
-                       LOGIC_ACT : std_logic;
+                       LOGIC_ACT : std_logic
                        
                        );
        port(
@@ -54,27 +54,36 @@ package core_pkg is
                        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;
 
@@ -85,43 +94,16 @@ package core_pkg is
                        -- 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;
index 63caa7efc405be286734742406b9d8d0aa473ecc..2b0cf49a62513e8c4060c39d4afca6ba2011977f 100644 (file)
@@ -5,13 +5,14 @@ use IEEE.numeric_std.all;
 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(
@@ -26,11 +27,13 @@ entity decode_stage is
                        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;
+
+
index 287f8e050cd7aeb28d18db5cae2d055979c23def..28c04c35aaf5aa0353af073505d90f28ffba4476 100644 (file)
@@ -1,4 +1,5 @@
 library IEEE;
+
 use IEEE.std_logic_1164.all;
 use IEEE.numeric_std.all;
 
@@ -6,6 +7,8 @@ use work.mem_pkg.all;
 use work.core_pkg.all;
 use work.common_pkg.all;
 
+
+
 architecture behav of decode_stage is
 
 signal instr_spl : instruction_rec;
@@ -23,7 +26,7 @@ begin
                )
                
                port map (
-                       sys_clk,
+                       clk,
                        reg_w_addr,
                        instr_spl.reg_src1_addr,
                        instr_spl.reg_src2_addr,
@@ -34,9 +37,15 @@ begin
                );
 
 
+       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
 
@@ -44,7 +53,7 @@ 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;
        
@@ -52,7 +61,7 @@ end process;
 
 
 -- 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
@@ -78,11 +87,11 @@ begin
        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;
 
@@ -104,267 +113,5 @@ begin
 
 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;
 
diff --git a/cpu/src/decoder.vhd b/cpu/src/decoder.vhd
new file mode 100644 (file)
index 0000000..41c5438
--- /dev/null
@@ -0,0 +1,16 @@
+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;
+
diff --git a/cpu/src/decoder_b.vhd b/cpu/src/decoder_b.vhd
new file mode 100644 (file)
index 0000000..1804811
--- /dev/null
@@ -0,0 +1,268 @@
+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;
+
+
+--===========================================================================
+
+
index c81e2ac14affda3e8addf55cbd590b220cf3a1d4..5713c02b0478b9f69a2607a7115e440631ecbad2 100644 (file)
@@ -2,7 +2,8 @@ library IEEE;
 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
 
@@ -10,7 +11,7 @@ entity fetch_stage is
                        -- active reset value
                        RESET_VALUE : std_logic;
                        -- active logic value
-                       LOGIC_ACT : std_logic;
+                       LOGIC_ACT : std_logic
                        
                        );
        port(
index 2dd8e92446af2123e53a0596a918882bf47bb731..e774901a01dc6b93b514d15d9d6e707886ccc8fb 100644 (file)
@@ -4,6 +4,7 @@ use IEEE.numeric_std.all;
 
 use work.core_pkg.all;
 use work.common_pkg.all;
+use work.mem_pkg.all;
 
 architecture behav of fetch_stage is
 
@@ -23,7 +24,7 @@ begin
                )
                
                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,
@@ -31,20 +32,20 @@ begin
                        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
 
diff --git a/cpu/src/pipeline_tb.vhd b/cpu/src/pipeline_tb.vhd
new file mode 100644 (file)
index 0000000..43c0c98
--- /dev/null
@@ -0,0 +1,174 @@
+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;
index ec15c61b1478977fa812ea9d1d35564559db41b9..23f1ddab12bd22e020429e4256913f4e754c0794 100644 (file)
@@ -2,6 +2,8 @@ library IEEE;
 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;
index 4350511f196797983222d64f533ec221602a2c08..84a3a94b150f6747a4319645f7c37f86e01810c3 100644 (file)
@@ -3,12 +3,14 @@ library ieee;
 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)
index 50c76606ce3e9e94a59edf1effef2b244779a337..9e530fad63d42eddf6d7b0d6c5204642e408bdd1 100644 (file)
@@ -3,12 +3,14 @@ library ieee;
 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)