From eb2445b8d321a01d8120bf8dd05e1370f0d9d9af Mon Sep 17 00:00:00 2001 From: Manfred Date: Tue, 30 Nov 2010 22:37:58 +0100 Subject: [PATCH] extension: entity + splitter zur adressierung --- cpu/src/extension.vhd | 28 ++++++ cpu/src/extension_b.vhd | 31 ++++++ cpu/src/extension_pkg.vhd | 31 ++++-- cpu/src/writeback_stage_b.vhd | 59 ++++++++++- cpu/src/writeback_stage_b.vhd.bak | 156 ++++++++++++++++++++++++++++++ 5 files changed, 298 insertions(+), 7 deletions(-) create mode 100644 cpu/src/extension.vhd create mode 100644 cpu/src/extension_b.vhd create mode 100644 cpu/src/writeback_stage_b.vhd.bak diff --git a/cpu/src/extension.vhd b/cpu/src/extension.vhd new file mode 100644 index 0000000..53c4e96 --- /dev/null +++ b/cpu/src/extension.vhd @@ -0,0 +1,28 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.extension_pkg.all; + +entity extension is + + generic ( + -- active reset value + RESET_VALUE : std_logic; + ); + port( + --System inputs + clk : in std_logic; + reset : in std_logic; + -- Input + ext_reg : in extmod_rec; + pointer : in pointer_count; + dec_inc : in std_logic; + -- Ouput + data_out : out gp_register_t; + pointer_val : out gp_register_t + + ); + +end extension; diff --git a/cpu/src/extension_b.vhd b/cpu/src/extension_b.vhd new file mode 100644 index 0000000..1947bde --- /dev/null +++ b/cpu/src/extension_b.vhd @@ -0,0 +1,31 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.core_pkg.all; + +use work.mem_pkg.all; +use work.extension_pkg.all; + +architecture behav of extension is + + +begin + + +syn: process(clk, reset) + +begin + + if (reset = RESET_VALUE) then + + elsif rising_edge(clk) then + + end if; + +end process; + + +end behav; + diff --git a/cpu/src/extension_pkg.vhd b/cpu/src/extension_pkg.vhd index be46852..af6ae70 100644 --- a/cpu/src/extension_pkg.vhd +++ b/cpu/src/extension_pkg.vhd @@ -8,16 +8,35 @@ use work.common_pkg.all; package extension_pkg is +constant EXTWORDL : integer := log2c(4); +constant BYTEADDR : integer := log2c(4); +constant PCOUNT : integer := log2c(4); +constant EXTWORDS : integer := EXTWORDL + BYTEADDR; + +subtype ext_addrid_t is std_logic_vector(gp_register_t'high - EXTWORDS downto 0); +subtype ext_addr_t is std_logic_vector((gp_register_t'high-BYTEADDR) downto 0); +subtype pointer_count is std_logic_vector(PCOUNT-1 downto 0); + type extmod_rec is record - clk : std_logic; - reset : std_logic; sel : std_logic; - wr_en : std_logic; byte_en : std_logic_vector(gp_register_t'length/byte_t'length-1 downto 0); data : gp_register_t; - addr : gp_register_t; + addr : ext_addr_t; end record; - - + + + + +constant EXT_7SEG_ADDR: ext_addrid_t := x"FFFFFFA"; +constant EXT_EXTMEM_ADDR: ext_addrid_t := x"FFFFFFB"; +constant EXT_TIMER_ADDR: ext_addrid_t := x"FFFFFFC"; +constant EXT_AC97_ADDR: ext_addrid_t := x"FFFFFFD"; +constant EXT_UART_ADDR: ext_addrid_t := x"FFFFFFE"; +constant EXT_GPM_ADDR: ext_addrid_t := x"FFFFFFF"; + + + + + end package extension_pkg; diff --git a/cpu/src/writeback_stage_b.vhd b/cpu/src/writeback_stage_b.vhd index 196af9c..9506813 100644 --- a/cpu/src/writeback_stage_b.vhd +++ b/cpu/src/writeback_stage_b.vhd @@ -6,13 +6,16 @@ use work.common_pkg.all; use work.core_pkg.all; use work.mem_pkg.all; +use work.extension_pkg.all; architecture behav of writeback_stage is - signal data_ram_read : word_t; signal wb_reg, wb_reg_nxt : writeback_rec; +signal ext_uart,ext_timer,ext_gpm : extmod_rec; + + begin @@ -118,5 +121,59 @@ begin reg_addr <= result_addr; end process; + +addr_de_mult: process(wb_reg_nxt.address) + +begin + + ext_uart.sel <='0'; + ext_uart.wr_en <= '0'; + ext_uart.byte_en <= (others => '0'); + ext_uart.data <= (others => '0'); + ext_uart.addr <= (others => '0'); + -- wenn ich hier statt dem 4rer die konstante nehme dann gibts an fehler wegen nicht lokaler variable -.- + case wb_reg_nxt.address(wb_reg_nxt.address'high downto 4) is + when EXT_UART_ADDR => + ext_uart.sel <='1'; + ext_uart.wr_en <= wb_reg_nxt.dmem_write_en; + ext_uart.data <= ram_data; + ext_uart.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR); + case wb_reg.address(1 downto 0) is + when "00" => ext_uart.byte_en <= "0001"; + when "01" => ext_uart.byte_en <= "0010"; + when "10" => ext_uart.byte_en <= "0100"; + when "11" => ext_uart.byte_en <= "1000"; + when others => null; + end case; + when EXT_TIMER_ADDR => + ext_timer.sel <='1'; + ext_timer.wr_en <= wb_reg_nxt.dmem_write_en; + ext_timer.data <= ram_data; + ext_timer.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR); + case wb_reg.address(1 downto 0) is + when "00" => ext_timer.byte_en <= "0001"; + when "01" => ext_timer.byte_en <= "0010"; + when "10" => ext_timer.byte_en <= "0100"; + when "11" => ext_timer.byte_en <= "1000"; + when others => null; + end case; + when EXT_GPM_ADDR => + ext_gpm.sel <='1'; + ext_gpm.wr_en <= wb_reg_nxt.dmem_write_en; + ext_gpm.data <= ram_data; + ext_gpm.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR); + case wb_reg.address(1 downto 0) is + when "00" => ext_gpm.byte_en <= "0001"; + when "01" => ext_gpm.byte_en <= "0010"; + when "10" => ext_gpm.byte_en <= "0100"; + when "11" => ext_gpm.byte_en <= "1000"; + when others => null; + end case; + -- hier kann man weiter extensions adden :) Konstanten sind im extension pkg definiert + when others => null; + end case; + +end process; + end behav; diff --git a/cpu/src/writeback_stage_b.vhd.bak b/cpu/src/writeback_stage_b.vhd.bak new file mode 100644 index 0000000..2c449ba --- /dev/null +++ b/cpu/src/writeback_stage_b.vhd.bak @@ -0,0 +1,156 @@ +library IEEE; +use IEEE.std_logic_1164.all; +use IEEE.numeric_std.all; + +use work.common_pkg.all; +use work.core_pkg.all; + +use work.mem_pkg.all; +use work.extension_pkg.all; + +architecture behav of writeback_stage is + +signal data_ram_read : word_t; + +signal wb_reg, wb_reg_nxt : writeback_rec; +signal ext_uart : extmod_rec; + + + +begin + + + data_ram : r_w_ram + generic map ( + DATA_ADDR_WIDTH, + WORD_WIDTH + ) + + port map ( + clk, + wb_reg_nxt.address(DATA_ADDR_WIDTH+1 downto 2), + wb_reg_nxt.address(DATA_ADDR_WIDTH+1 downto 2), + wb_reg_nxt.dmem_write_en, + ram_data, + data_ram_read + ); + + +syn: process(clk, reset) + +begin + + if (reset = RESET_VALUE) then + wb_reg.address <= (others => '0'); + wb_reg.dmem_en <= '0'; + wb_reg.dmem_write_en <= '0'; + wb_reg.hword <= '0'; + wb_reg.byte_s <= '0'; + elsif rising_edge(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, wb_reg, result, byte_s, alu_jmp, br_pred) + +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); + when others => null; + 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, wb_reg, alu_jmp) + +begin + reg_we <= (write_en or (wb_reg.dmem_en and not(wb_reg.dmem_write_en))) and not(alu_jmp); + reg_addr <= result_addr; +end process; + + +addr_de_mult: process(address) + +begin + + ext_uart.sel <='0'; + ext_uart.wr_en <= '0'; + ext_uart.byte_en <= (others => '0'); + ext_uart.data <= (others => '0'); + ext_uart.addr <= (others => '0'); + case wb_reg_nxt.address(wb_reg_nxt.address'high downto EXTWORDS) is + when EXT_UART_ADDR => + ext_uart.sel <='1'; + ext_uart.wr_en <= wb_reg_nxt.dmem_write_en; + ext_uart.data <= ram_data; + ext_uart.addr <= wb_reg_nxt.address(wb_reg_nxt.address'high downto BYTEADDR); + case wb_reg.address(1 downto 0) is + when "00" => ext_uart.byte_en <= "0001"; + when "01" => ext_uart.byte_en <= "0010"; + when "10" => ext_uart.byte_en <= "0100"; + when "11" => ext_uart.byte_en <= "1000"; + when others => null; + end case; + + + + when others => null; + end case;s + +end process; + +end behav; + -- 2.25.1