From 0b342c308aedd8031eb9ad4b2712a3023a247462 Mon Sep 17 00:00:00 2001 From: Stefan Rebernig Date: Mon, 15 Nov 2010 16:24:23 +0100 Subject: [PATCH] writeback stage --- cpu/src/common_pkg.vhd | 15 +++++- cpu/src/core_pkg.vhd | 18 +++++++ cpu/src/writeback_stage.vhd | 18 +++++++ cpu/src/writeback_stage_b.vhd | 92 ++++++++++++++++++++++++++++++++++- 4 files changed, 139 insertions(+), 4 deletions(-) diff --git a/cpu/src/common_pkg.vhd b/cpu/src/common_pkg.vhd index 3d93390..06e3769 100755 --- a/cpu/src/common_pkg.vhd +++ b/cpu/src/common_pkg.vhd @@ -25,7 +25,7 @@ package common_pkg is constant INSTR_ADDR_WIDTH : INTEGER := 32; constant PHYS_INSTR_ADDR_WIDTH : INTEGER := 11; constant REG_ADDR_WIDTH : INTEGER := 4; - constant DATA_ADDR_WIDTH : INTEGER := 32; + constant DATA_ADDR_WIDTH : INTEGER := 11; constant PHYS_DATA_ADDR_WIDTH : INTEGER := 32; constant NUM_OP_OPT_WIDTH : INTEGER := 6; @@ -110,7 +110,18 @@ package common_pkg is end record; - + type writeback_rec is record +-- result : in gp_register_t; --reg (alu result or jumpaddr) +-- result_addr : in gp_addr_t; --reg + address : word_t; --ureg +-- alu_jmp : in std_logic; --reg +-- br_pred : in std_logic; --reg +-- write_en : in std_logic; --reg (register file) + dmem_en : std_logic; --ureg (jump addr in mem or in address) + dmem_write_en : std_logic; --ureg + hword : std_logic; --ureg + byte_s : std_logic; + end record; function inc(value : in std_logic_vector; constant by : in integer := 1) return std_logic_vector; diff --git a/cpu/src/core_pkg.vhd b/cpu/src/core_pkg.vhd index 3f916fb..24d06a2 100644 --- a/cpu/src/core_pkg.vhd +++ b/cpu/src/core_pkg.vhd @@ -102,6 +102,24 @@ package core_pkg is --System inputs clk : in std_logic; reset : in std_logic + + result : in gp_register_t; --reg (alu result or jumpaddr) + result_addr : in gp_addr_t; --reg + address : in word_t; --ureg + ram_data : in word_t; --ureg + alu_jmp : in std_logic; --reg + br_pred : in std_logic; --reg + write_en : in std_logic; --reg (register file) + dmem_en : in std_logic; --ureg (jump addr in mem or in address) + dmem_write_en : in std_logic; --ureg + hword : in std_logic; --ureg + byte_s : in std_logic; --ureg + + regfile_val : out gp_register_t; + reg_we : out std_logic; + reg_addr : out gp_addr_t; + jump_addr : out instruction_addr_t; + jump : out std_logic ); end component writeback_stage; diff --git a/cpu/src/writeback_stage.vhd b/cpu/src/writeback_stage.vhd index 965f996..7d6e3c2 100644 --- a/cpu/src/writeback_stage.vhd +++ b/cpu/src/writeback_stage.vhd @@ -15,6 +15,24 @@ entity writeback_stage is --System inputs clk : in std_logic; reset : in std_logic; + + result : in gp_register_t; --reg (alu result or jumpaddr) + result_addr : in gp_addr_t; --reg + address : in word_t; --ureg + ram_data : in word_t; --ureg + alu_jmp : in std_logic; --reg + br_pred : in std_logic; --reg + write_en : in std_logic; --reg (register file) + dmem_en : in std_logic; --ureg (jump addr in mem or in address) + dmem_write_en : in std_logic; --ureg + hword : in std_logic; --ureg + byte_s : in std_logic; --ureg + + regfile_val : out gp_register_t; + reg_we : out std_logic; + reg_addr : out gp_addr_t; + jump_addr : out instruction_addr_t; + jump : out std_logic ); end writeback_stage; diff --git a/cpu/src/writeback_stage_b.vhd b/cpu/src/writeback_stage_b.vhd index 4e5fba3..86015cd 100644 --- a/cpu/src/writeback_stage_b.vhd +++ b/cpu/src/writeback_stage_b.vhd @@ -9,17 +9,105 @@ architecture behav of writeback_stage is begin +signal data_ram_read : word_t; + +signal wb_reg, wb_reg_nxt : writeback_rec; + + data_ram : r_w_ram + generic map ( + PHYS_DATA_ADDR_WIDTH, + WORD_WIDTH + ) + + port map ( + clk, + wb_reg_nxt.address(PHYS_DATA_ADDR_WIDTH+1 downto 2), + wb_reg_nxt.address(PHYS_DATA_ADDR_WIDTH+1 downto 2), + wb_reg_nxt.dmem_write_en, + ram_data, + data_ram_read + ); + + syn: process(sys_clk, reset) begin if (reset = RESET_VALUE) then - + elsif rising_edge(sys_clk) then - + wb_reg <= wb_reg_nxt; end if; end process; +-- type writeback_rec is record +-- address : in word_t; --ureg +-- dmem_en : in std_logic; --ureg (jump addr in mem or in address) +-- dmem_write_en : in std_logic; --ureg +-- hword_hl : in std_logic --ureg +-- end record; + + + +shift_input: process(data_ram_read, address, dmem_en, dmem_write_en, hword_hl, wb_reg, result) + +begin + wb_reg_nxt.address <= address; + wb_reg_nxt.dmem_en <= dmem_en; + wb_reg_nxt.dmem_write_en <= dmem_write_en; + wb_reg_nxt.hword <= hword; + wb_reg_nxt.byte_s <= byte_s; + + regfile_val <= result; --(others => '0'); + + if (wb_reg.dmem_en = '1' and wb_reg.dmem_write_en = '0') then -- ram read operation --alu_jmp = '0' and + regfile_val <= data_ram_read; + if (wb_reg.hword = '1') then + regfile_val <= (others => '0'); + if (wb_reg.address(1) = '1') then + regfile_val(15 downto 0) <= data_ram_read(31 downto 16); + else + regfile_val(15 downto 0) <= data_ram_read(15 downto 0); + end if; + end if; + if (wb_reg.byte_s = '1') then + regfile_val <= (others => '0'); + case wb_reg.address(1 downto 0) is + when "00" => regfile_val(7 downto 0) <= data_ram_read(7 downto 0); + when "01" => regfile_val(7 downto 0) <= data_ram_read(15 downto 8); + when "10" => regfile_val(7 downto 0) <= data_ram_read(23 downto 16); + when "11" => regfile_val(7 downto 0) <= data_ram_read(31 downto 24); + end case; + end if; + end if; + + jump <= alu_jmp xor br_pred; + jump_addr <= result; + if ((alu_jmp and wb_reg.dmem_en) = '1') then + jump_addr <= data_ram_read; + end if; + +end process; + +-- result : in gp_register_t; --reg (alu result or jumpaddr) +-- result_addr : in gp_addr_t; --reg +-- address : in word_t; --ureg +-- alu_jmp : in std_logic; --reg +-- br_pred : in std_logic; --reg +-- write_en : in std_logic; --reg (register file) +-- dmem_en : in std_logic; --ureg (jump addr in mem or in result) +-- dmem_write_en : in std_logic; --ureg +-- hword : in std_logic --ureg + + + +out_logic: process(write_en, result_addr) + +begin + reg_we <= write_en; + reg_addr <= result_addr; +end process; + end behav; -- 2.25.1