init
This commit is contained in:
53
src/alu.vhd
Normal file
53
src/alu.vhd
Normal file
@@ -0,0 +1,53 @@
|
||||
-- alu.vhd
|
||||
-- Created on: Mo 21. Nov 11:23:36 CET 2022
|
||||
-- Author(s): Carl Ries, Yannick Reiß, Alexander Graf
|
||||
-- Content: ALU
|
||||
library IEEE;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
entity alu is
|
||||
port (
|
||||
alu_opc : in aluOP; -- alu opcode.
|
||||
input1 : in word; -- input1 of alu (reg1 / pc address) rs1
|
||||
input2 : in word; -- input2 of alu (reg2 / immediate) rs2
|
||||
result : out word -- alu output.
|
||||
);
|
||||
end alu;
|
||||
|
||||
-- Architecture implementation of alu: implements operatings mode
|
||||
architecture implementation of alu is
|
||||
|
||||
begin
|
||||
-- Process log that fetches the opcode and executes it
|
||||
log : process (alu_opc, input1, input2) -- runs only, when all changed
|
||||
begin
|
||||
case alu_opc is
|
||||
when uNOP => result <= std_logic_vector(to_unsigned(0, wordWidth)); -- no operations
|
||||
when uADD => result <= std_logic_vector(unsigned(input1) + unsigned( input2 )); -- addition
|
||||
when uSUB => result <= std_logic_vector(signed(input1) - signed( input2 )); -- subtraction
|
||||
when uSLL => result <= std_logic_vector(unsigned(input1) sll 1); -- shift left logical
|
||||
when uSLT =>
|
||||
if(signed( input1 ) < signed( input2 )) then
|
||||
result <= std_logic_vector(to_unsigned(1, wordWidth));
|
||||
else
|
||||
result <= std_logic_vector(to_unsigned(0, wordWidth));
|
||||
end if; -- Set lower than
|
||||
when uSLTU =>
|
||||
if(unsigned( input1 ) < unsigned( input2 )) then
|
||||
result <= std_logic_vector(to_unsigned(1, wordWidth));
|
||||
else
|
||||
result <= std_logic_vector(to_unsigned(0, wordWidth));
|
||||
end if; -- Set lower than unsigned
|
||||
when uXOR => result <= input1 xor input2; -- exclusive or
|
||||
when uSRL => result <= std_logic_vector(unsigned(input1) srl 1); -- shift right logical
|
||||
when uSRA => result <= std_logic_vector(to_stdlogicvector(to_bitvector(input1) sra 1)); -- shift right arithmetic
|
||||
when uOR => result <= input1 or input2; -- or
|
||||
when uAND => result <= input1 and input2; -- and
|
||||
when others => result <= std_logic_vector(to_unsigned(0, wordWidth)); -- other operations return zero
|
||||
end case;
|
||||
end process;
|
||||
end implementation;
|
||||
69
src/branch.vhd
Normal file
69
src/branch.vhd
Normal file
@@ -0,0 +1,69 @@
|
||||
-- branch.vhd
|
||||
-- Created on: 19:01:2023
|
||||
-- Author(s): Yannick Reiß
|
||||
-- Copyright: WTFPL
|
||||
-- Content: Entity branch - enable B-types in CPU
|
||||
library IEEE;
|
||||
use IEEE.std_logic_1164.all;
|
||||
use IEEE.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
entity Branch is
|
||||
port (
|
||||
op_code : in uOP;
|
||||
reg1 : in word;
|
||||
reg2 : in word;
|
||||
jmp_enable : out one_bit
|
||||
);
|
||||
end Branch;
|
||||
|
||||
architecture arch of Branch is
|
||||
|
||||
begin
|
||||
|
||||
branch_process : process(op_code)
|
||||
begin
|
||||
case op_code is
|
||||
when uBEQ =>
|
||||
if reg1 = reg2 then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when uBNE =>
|
||||
if not (reg1 = reg2) then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when uBLT =>
|
||||
if signed(reg1) < signed(reg2) then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when uBGE =>
|
||||
if signed(reg1) >= signed(reg2) then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when uBLTU =>
|
||||
if unsigned(reg1) < unsigned(reg2) then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when uBGEU =>
|
||||
if unsigned(reg1) >= unsigned(reg2) then
|
||||
jmp_enable <= "1";
|
||||
else
|
||||
jmp_enable <= "0";
|
||||
end if;
|
||||
when others =>
|
||||
jmp_enable <= "0";
|
||||
end case;
|
||||
end process; -- branch
|
||||
end architecture; -- arch
|
||||
359
src/cpu.vhd
Normal file
359
src/cpu.vhd
Normal file
@@ -0,0 +1,359 @@
|
||||
-- cpu.vhd
|
||||
-- Created on: Mo 19. Dez 11:07:17 CET 2022
|
||||
-- Author(s): Yannick Reiß, Carl Ries, Alexander Graf
|
||||
-- Content: Entity cpu
|
||||
library IEEE;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
-- Entity cpu: path implementation of RISC-V cpu
|
||||
entity cpu is
|
||||
port(
|
||||
clk : in std_logic; -- clk to control the unit
|
||||
|
||||
-- Led Output
|
||||
led : out std_logic_vector(15 downto 0); -- output to 16 LEDS
|
||||
|
||||
-- RGB Output
|
||||
RGB1 : out std_logic_vector(2 downto 0); -- output to RGB 1
|
||||
RGB2 : out std_logic_vector(2 downto 0) -- output to RGB 2
|
||||
);
|
||||
end cpu;
|
||||
|
||||
-- Architecture implementation of c: control and connect different parts of cpu
|
||||
architecture implementation of cpu is
|
||||
|
||||
component pc
|
||||
port(
|
||||
clk : in std_logic; -- Clock input for timing
|
||||
en_pc : in one_bit; -- activates PC
|
||||
addr_calc : in ram_addr_t; -- Address from ALU
|
||||
doJump : in one_bit; -- Jump to Address
|
||||
addr : out ram_addr_t -- Address to Decoder
|
||||
);
|
||||
end component;
|
||||
|
||||
component ram
|
||||
port(
|
||||
clk : in std_logic; -- Clock input for timing
|
||||
instructionAdr : in ram_addr_t; -- Address instruction
|
||||
dataAdr : in ram_addr_t; -- Address data
|
||||
writeEnable : in one_bit; -- Read or write mode
|
||||
dataIn : in word; -- Write data
|
||||
instruction : out word; -- Get instruction
|
||||
dataOut : out word -- Read data
|
||||
);
|
||||
end component;
|
||||
|
||||
component alu
|
||||
port (
|
||||
alu_opc : in aluOP; -- alu opcode.
|
||||
input1 : in word; -- input1 of alu (reg1 / pc address) rs1
|
||||
input2 : in word; -- input2 of alu (reg2 / immediate) rs2
|
||||
result : out word -- alu output.
|
||||
);
|
||||
end component;
|
||||
|
||||
component decoder
|
||||
port(
|
||||
instrDecode : in instruction; -- Instruction from instruction memory
|
||||
op_code : out uOP; -- alu opcode
|
||||
regOp1 : out reg_idx; -- Rj: first register to read
|
||||
regOp2 : out reg_idx; -- Rk: second register to read
|
||||
regWrite : out reg_idx -- Ri: the register to write to
|
||||
);
|
||||
end component;
|
||||
|
||||
component imm
|
||||
port (
|
||||
instruction : in instruction;
|
||||
opcode : in uOP;
|
||||
immediate : out word
|
||||
);
|
||||
end component;
|
||||
|
||||
component registers
|
||||
port(
|
||||
clk : in std_logic; -- input for clock (control device)
|
||||
en_reg_wb : in one_bit; -- enable register write back (?)
|
||||
data_in : in word; -- Data to be written into the register
|
||||
wr_idx : in reg_idx; -- register to write to
|
||||
r1_idx : in reg_idx; -- first register to read from
|
||||
r2_idx : in reg_idx; -- second register to read from
|
||||
write_enable : in one_bit; -- enable writing to wr_idx
|
||||
r1_out : out word; -- data from first register
|
||||
r2_out : out word; -- data from second register
|
||||
led_out : out word -- output led
|
||||
);
|
||||
end component;
|
||||
|
||||
component Branch
|
||||
port(
|
||||
op_code : in uOP;
|
||||
reg1 : in word;
|
||||
reg2 : in word;
|
||||
jmp_enable : out one_bit
|
||||
);
|
||||
end component;
|
||||
|
||||
-- SIGNALS GLOBAL
|
||||
signal s_clock : std_logic;
|
||||
signal s_reg_wb_enable : one_bit; --enables: register writeback
|
||||
signal s_reg_wr_enable : one_bit; --enables: register write to index
|
||||
signal s_pc_enable : one_bit; --enables: pc
|
||||
signal s_pc_jump_enable : one_bit; --enables: pc jump to address
|
||||
signal s_ram_enable : one_bit; --enables: ram write enalbe
|
||||
signal s_led_out : word := "10110011100001110111010110101110"; -- stores the exact output
|
||||
|
||||
|
||||
|
||||
-- decoder -> registers
|
||||
signal s_idx_1 : reg_idx;
|
||||
signal s_idx_2 : reg_idx;
|
||||
signal s_idx_wr : reg_idx;
|
||||
|
||||
-- decoder -> imm ( + decoder)
|
||||
signal s_opcode : uOP;
|
||||
|
||||
-- register -> alu
|
||||
signal s_reg_data1 : word;
|
||||
signal s_reg_data2 : word;
|
||||
|
||||
-- pc -> ram
|
||||
signal s_instAdr : ram_addr_t;
|
||||
signal s_cycle_cnt : cpuStates := stIF;
|
||||
signal s_branch_jump_enable : one_bit;
|
||||
|
||||
-- alu -> ram + register
|
||||
signal s_alu_data : word;
|
||||
|
||||
-- ram -> register
|
||||
signal s_ram_data : word;
|
||||
|
||||
--ram -> decoder + imm
|
||||
signal s_inst : instruction;
|
||||
signal s_data_in_addr : ram_addr_t;
|
||||
|
||||
|
||||
|
||||
-- v dummy signals below v
|
||||
|
||||
--imm -> ???
|
||||
signal s_immediate : word;
|
||||
|
||||
-- ??? -> alu
|
||||
signal X_aluOP : aluOP;
|
||||
|
||||
-- ??? -> alu
|
||||
signal X_addr_calc : ram_addr_t;
|
||||
|
||||
-- Clock signals
|
||||
signal reset : std_logic;
|
||||
signal locked : std_logic;
|
||||
|
||||
-------------------------
|
||||
-- additional ALU signals
|
||||
-------------------------
|
||||
signal aluIn1 : word;
|
||||
signal aluIn2 : word;
|
||||
|
||||
-------------------------
|
||||
-- additional REG signals
|
||||
-------------------------
|
||||
signal reg_data_in : word;
|
||||
|
||||
begin
|
||||
|
||||
s_clock <= clk;
|
||||
|
||||
decoder_RISCV : decoder
|
||||
port map(
|
||||
instrDecode => s_inst,
|
||||
op_code => s_opcode,
|
||||
regOp1 => s_idx_1,
|
||||
regOp2 => s_idx_2,
|
||||
regWrite => s_idx_wr
|
||||
);
|
||||
|
||||
registers_RISCV : registers
|
||||
port map(
|
||||
clk => s_clock,
|
||||
en_reg_wb => s_reg_wb_enable,
|
||||
data_in => reg_data_in,
|
||||
wr_idx => s_idx_wr,
|
||||
r1_idx => s_idx_1,
|
||||
r2_idx => s_idx_2,
|
||||
write_enable => s_reg_wr_enable,
|
||||
r1_out => s_reg_data1,
|
||||
r2_out => s_reg_data2,
|
||||
led_out => s_led_out
|
||||
);
|
||||
|
||||
imm_RISCV : imm
|
||||
port map(
|
||||
instruction => s_inst,
|
||||
opcode => s_opcode,
|
||||
immediate => s_immediate
|
||||
);
|
||||
|
||||
pc_RISCV : pc
|
||||
port map(
|
||||
clk => s_clock,
|
||||
en_pc => s_pc_enable,
|
||||
addr_calc => X_addr_calc,
|
||||
doJump => s_pc_jump_enable,
|
||||
addr => s_instAdr
|
||||
);
|
||||
|
||||
alu_RISCV : alu
|
||||
port map(
|
||||
alu_opc => X_aluOP, -- switch case from s_opcode
|
||||
input1 => aluIn1,
|
||||
input2 => aluIn2,
|
||||
result => s_alu_data
|
||||
);
|
||||
|
||||
ram_RISCV : ram
|
||||
port map(
|
||||
clk => s_clock, --
|
||||
instructionAdr => s_instAdr, -- instruction from pc
|
||||
dataAdr => s_data_in_addr, -- data address from alu
|
||||
writeEnable => s_ram_enable, --
|
||||
dataIn => s_reg_data2, -- data from register
|
||||
instruction => s_inst, --
|
||||
dataOut => s_ram_data
|
||||
);
|
||||
|
||||
branch_RISCV : Branch
|
||||
port map(
|
||||
op_code => s_opcode,
|
||||
reg1 => aluIn1,
|
||||
reg2 => aluIn2,
|
||||
jmp_enable => s_branch_jump_enable
|
||||
);
|
||||
|
||||
------------------------
|
||||
-- ALU opcode and input connection
|
||||
------------------------
|
||||
-- Process alu_control set alu opcode
|
||||
|
||||
-----------------------------------------
|
||||
-- Output
|
||||
-----------------------------------------
|
||||
led <= s_led_out(15 downto 0);
|
||||
RGB1 <= s_clock & s_clock & s_clock;
|
||||
|
||||
alu_control : process (s_immediate, s_opcode, s_reg_data1, s_reg_data2) -- runs only, when item in list changed
|
||||
begin
|
||||
-- Connect opcode
|
||||
case s_opcode is
|
||||
when uADD | uADDI => X_aluOP <= uADD;
|
||||
when uSUB => X_aluOP <= uSUB;
|
||||
when uSLL | uSLLI => X_aluOP <= uSLL;
|
||||
when uSLT | uSLTI => X_aluOP <= uSLT;
|
||||
when uSLTU | uSLTIU => X_aluOP <= uSLTU;
|
||||
when uXOR | uXORI => X_aluOP <= uXOR;
|
||||
when uSRL | uSRLI => X_aluOP <= uSRL;
|
||||
when uSRA | uSRAI => X_aluOP <= uSRA;
|
||||
when uOR | uORI => X_aluOP <= uOR;
|
||||
when uAND | uANDI => X_aluOP <= uAND;
|
||||
when others => X_aluOP <= uNOP;
|
||||
end case;
|
||||
-- connect input1
|
||||
case s_opcode is
|
||||
-- add nonstandard inputs for aluIn1 here
|
||||
when others => aluIn1 <= s_reg_data1;
|
||||
end case;
|
||||
|
||||
-- TODO: why line from pc to alu inp1?
|
||||
-- connect input 2
|
||||
case s_opcode is
|
||||
when uADDI | uSLTI | uSLTIU | uXORI | uORI | uANDI => aluIn2 <= s_immediate;
|
||||
when others => aluIn2 <= s_reg_data2; -- use rs2 as default
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Process register_data_input select which input is needed for register
|
||||
register_data_input : process (s_cycle_cnt, s_opcode, s_ram_data, s_alu_data) -- runs only, when item in list changed
|
||||
begin
|
||||
s_reg_wb_enable <= "0";
|
||||
case s_opcode is
|
||||
when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU | uSB | uSH | uSW | uECALL | uNOP => s_reg_wr_enable <= "0";
|
||||
when others =>
|
||||
if s_cycle_cnt = stEXEC then
|
||||
s_reg_wr_enable <= "1";
|
||||
else
|
||||
s_reg_wr_enable <= "0";
|
||||
end if;
|
||||
end case;
|
||||
|
||||
case s_opcode is
|
||||
when uLB | uLH | uLW | uLBU | uLHU => reg_data_in <= s_ram_data; -- use value from
|
||||
-- RAM (Load instructions)
|
||||
when others => reg_data_in <= s_alu_data; -- alu operations as default
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- Process pc input
|
||||
pc_addr_input : process(s_opcode, s_cycle_cnt, s_instAdr, s_immediate)
|
||||
begin
|
||||
if s_cycle_cnt = stWB then
|
||||
s_pc_enable <= "1";
|
||||
else
|
||||
s_pc_enable <= "0";
|
||||
-- X_addr_calc <= s_instAdr; -- should not be necessary, every case option sets X_addr_calc
|
||||
end if;
|
||||
case s_opcode is
|
||||
when uJALR | uJAL =>
|
||||
s_pc_jump_enable <= "1";
|
||||
X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAdr));
|
||||
|
||||
-- Branch op_codes
|
||||
when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU =>
|
||||
-- always load address from immediate on B-Type
|
||||
X_addr_calc <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_instAdr));
|
||||
-- check for opcodes and evaluate condition
|
||||
s_pc_jump_enable <= s_branch_jump_enable;
|
||||
when others =>
|
||||
s_pc_jump_enable <= "0";
|
||||
X_addr_calc <= s_instAdr;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- process ram
|
||||
ram_input : process(s_opcode, s_cycle_cnt)
|
||||
begin
|
||||
s_data_in_addr <= std_logic_vector(signed(s_immediate(11 downto 0)) + signed(s_reg_data1(11 downto 0)));
|
||||
if s_cycle_cnt = stWB then
|
||||
case s_opcode is
|
||||
when uSB | uSH | uSW => s_ram_enable <= "1";
|
||||
when others => s_ram_enable <= "0";
|
||||
end case;
|
||||
else
|
||||
s_ram_enable <= "0";
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- pc cycle control
|
||||
pc_cycle_control : process(s_clock)
|
||||
begin
|
||||
if rising_edge(s_clock) then
|
||||
case s_cycle_cnt is
|
||||
when stIF => s_cycle_cnt <= stDEC;
|
||||
RGB2 <= "001";
|
||||
when stDEC => s_cycle_cnt <= stOF;
|
||||
RGB2 <= "010";
|
||||
when stOF => s_cycle_cnt <= stEXEC;
|
||||
RGB2 <= "011";
|
||||
when stEXEC => s_cycle_cnt <= stWB;
|
||||
RGB2 <= "100";
|
||||
when others => s_cycle_cnt <= stIF;
|
||||
RGB2 <= "101";
|
||||
end case;
|
||||
end if;
|
||||
end process pc_cycle_control;
|
||||
|
||||
end implementation;
|
||||
125
src/decoder.vhd
Normal file
125
src/decoder.vhd
Normal file
@@ -0,0 +1,125 @@
|
||||
-- vsg_off
|
||||
-- decoder_reloaded.vhd
|
||||
-- Created on: Do 8. Dez 18:45:24 CET 2022
|
||||
-- Author(s): Axel, Carsten und Jannis
|
||||
-- Content: Decoder Version 2 (ständige vollbelegung)
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
-- Entity decode: Decoder currently supporting read operations
|
||||
entity decoder is
|
||||
port(
|
||||
instrDecode : in instruction; -- Instruction from instruction memory
|
||||
op_code : out uOP; -- alu opcode
|
||||
regOp1 : out reg_idx; -- Rj: first register to read
|
||||
regOp2 : out reg_idx; -- Rk: second register to read
|
||||
regWrite : out reg_idx -- Ri: the register to write to
|
||||
);
|
||||
end decoder;
|
||||
|
||||
-- Architecture schematic of decode: Split up instruction into registers
|
||||
architecture decode of decoder is
|
||||
|
||||
begin
|
||||
|
||||
-- Process decode splits up instruction for alu
|
||||
process (instrDecode(11 downto 7), instrDecode(14 downto 12),
|
||||
instrDecode(19 downto 15), instrDecode(24 downto 20),
|
||||
instrDecode(31 downto 25), instrDecode(6 downto 0)) -- runs only, when instrDecode changed
|
||||
begin
|
||||
-- ONLY DECODES RV32I Base Instruction Set
|
||||
-- op_code (funct7 + funct3 + operand)
|
||||
case instrDecode(6 downto 0) is
|
||||
-- R-Type
|
||||
when "0110011" =>
|
||||
case instrDecode(14 downto 12) is
|
||||
when "000" =>
|
||||
if instrDecode(31 downto 25) = "0000000" then
|
||||
op_code <= uADD;
|
||||
else
|
||||
op_code <= uSUB;
|
||||
end if; -- ADD / SUB
|
||||
when "001" => op_code <= uSLL;
|
||||
when "010" => op_code <= uSLT;
|
||||
when "011" => op_code <= uSLTU;
|
||||
when "100" => op_code <= uXOR;
|
||||
when "101" =>
|
||||
if instrDecode(31 downto 25) = "0000000" then
|
||||
op_code <= uSRL;
|
||||
else
|
||||
op_code <= uSRA;
|
||||
end if;
|
||||
when "110" => op_code <= uOR;
|
||||
when "111" => op_code <= uAND;
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
|
||||
-- I-Type
|
||||
when "1100111" => op_code <= uJALR;
|
||||
when "0000011" =>
|
||||
case instrDecode(14 downto 12) is
|
||||
when "000" => op_code <= uLB;
|
||||
when "001" => op_code <= uLH;
|
||||
when "010" => op_code <= uLW;
|
||||
when "100" => op_code <= uLBU;
|
||||
when "101" => op_code <= uLHU;
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
when "0010011" =>
|
||||
case instrDecode(14 downto 12) is
|
||||
when "000" => op_code <= uADDI;
|
||||
when "001" => op_code <= uSLTI;
|
||||
when "010" => op_code <= uSLTIU;
|
||||
when "011" => op_code <= uXORI;
|
||||
when "100" => op_code <= uORI;
|
||||
when "101" => op_code <= uANDI;
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
|
||||
-- S-Type
|
||||
when "0100011" =>
|
||||
case instrDecode(14 downto 12) is
|
||||
when "000" => op_code <= uSB;
|
||||
when "001" => op_code <= uSH;
|
||||
when "010" => op_code <= uSW;
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
|
||||
-- B-Type
|
||||
when "1100011" =>
|
||||
case instrDecode(14 downto 12) is
|
||||
when "000" => op_code <= uBEQ;
|
||||
when "001" => op_code <= uBNE;
|
||||
when "100" => op_code <= uBLT;
|
||||
when "101" => op_code <= uBGE;
|
||||
when "110" => op_code <= uBLTU;
|
||||
when "111" => op_code <= uBGEU;
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
|
||||
-- U-Type
|
||||
when "0110111" => op_code <= uLUI;
|
||||
when "0010111" => op_code <= uAUIPC;
|
||||
|
||||
-- J-Type
|
||||
when "1101111" => op_code <= uJAL;
|
||||
|
||||
-- Add more Operandtypes here
|
||||
when others => op_code <= uNOP;
|
||||
end case;
|
||||
|
||||
-- regOp1 (19-15)
|
||||
regOp1 <= instrDecode(19 downto 15);
|
||||
|
||||
-- regOp2 (24-20)
|
||||
regOp2 <= instrDecode(24 downto 20);
|
||||
|
||||
-- regWrite (11-7)
|
||||
regWrite <= instrDecode(11 downto 7);
|
||||
end process;
|
||||
end decode;
|
||||
54
src/imem.vhd
Normal file
54
src/imem.vhd
Normal file
@@ -0,0 +1,54 @@
|
||||
-- imem.vhd
|
||||
-- Created on: Do 29. Dez 20:44:53 CET 2022
|
||||
-- Author(s): Yannick Reiß, Alexander Graf, Carl Ries
|
||||
-- Content: Entity instruction memory as part of ram
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
entity instr_memory is
|
||||
|
||||
generic (initMem : ram_t := (others => (others => '0')));
|
||||
|
||||
port (clk : in std_logic;
|
||||
|
||||
addr_a : in std_logic_vector(ram_addr_size - 3 downto 0);
|
||||
data_read_a : out std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
write_b : in one_bit;
|
||||
addr_b : in std_logic_vector(ram_addr_size - 3 downto 0);
|
||||
data_read_b : out std_logic_vector(wordWidth - 1 downto 0);
|
||||
data_write_b : in std_logic_vector(wordWidth - 1 downto 0)
|
||||
|
||||
);
|
||||
|
||||
end instr_memory;
|
||||
|
||||
-- START:
|
||||
-- addi x1 x0 1
|
||||
-- add x2 x0 x0
|
||||
-- add x3 x0 x0
|
||||
-- addi x4 x0 2047
|
||||
-- slli x4 x4 5
|
||||
-- REG2UP:
|
||||
-- add x2 x2 x1
|
||||
-- add x3 x0 x0
|
||||
-- REG3UP:
|
||||
-- add x3 x3 x1
|
||||
-- bgeu x3 x4 REG2UP
|
||||
-- jal REG3UP
|
||||
architecture behavioral of instr_memory is
|
||||
signal store : ram_t :=
|
||||
(
|
||||
x"00100093", x"00000133", x"000001b3", x"7ff00213", x"00521213", x"00110133", x"000001b3", x"001181b3", x"fe41fae3", x"ff9ff0ef", others => (others => '0')
|
||||
);
|
||||
begin
|
||||
|
||||
-- Two synchron read ports
|
||||
data_read_a <= store(to_integer(unsigned(addr_a(9 downto 2))));
|
||||
data_read_b <= store(to_integer(unsigned(addr_b(9 downto 2))));
|
||||
|
||||
end behavioral;
|
||||
44
src/imm.vhd
Normal file
44
src/imm.vhd
Normal file
@@ -0,0 +1,44 @@
|
||||
library IEEE;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
entity imm is
|
||||
port (
|
||||
instruction : in instruction;
|
||||
opcode : in uOP;
|
||||
immediate : out word
|
||||
);
|
||||
end imm;
|
||||
|
||||
-- Architecture slicing of imm: slices immediate out of instruction
|
||||
architecture slicing of imm is
|
||||
|
||||
begin
|
||||
-- Process immediate slice
|
||||
process (opcode, instruction)
|
||||
begin
|
||||
case opcode is
|
||||
-- I-Type
|
||||
when uLB | uLH | uLW | uLBU | uLHU | uADDI | uSLTI | uSLTIU | uXORI | uORI | uANDI => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 12)) & instruction(31 downto 20);
|
||||
|
||||
-- S-Type
|
||||
when uSB | uSH | uSW => immediate <= std_logic_vector(to_unsigned(0, wordWidth-12)) & instruction(31 downto 25) & instruction(11 downto 7);
|
||||
|
||||
-- B-Type
|
||||
when uBEQ | uBNE | uBLT | uBGE | uBLTU | uBGEU => immediate <= std_logic_vector(to_unsigned(0, 19)) & instruction(31) & instruction(7) & instruction(30 downto 25) & instruction(11 downto 8) & "0";
|
||||
|
||||
-- U-Type
|
||||
when uLUI | uAUIPC => immediate <= instruction(31 downto 12) & std_logic_vector(to_unsigned(0, 12));
|
||||
|
||||
-- J-Type
|
||||
when uJAL => immediate <= std_logic_vector(to_unsigned(0, wordWidth - 21)) & instruction(31) & instruction(19 downto 12) & instruction(20) & instruction(30 downto 21) & "0";
|
||||
|
||||
when others => immediate <= x"C000FFEE";
|
||||
end case;
|
||||
end process;
|
||||
|
||||
end slicing;
|
||||
|
||||
46
src/pc.vhd
Normal file
46
src/pc.vhd
Normal file
@@ -0,0 +1,46 @@
|
||||
-- pc.vhd
|
||||
-- Created on: Mo 05. Dec 14:21:39 CET 2022
|
||||
-- Author(s): Carl Ries, Yannick Reiß, Alexander Graf
|
||||
-- Content: program counter
|
||||
library IEEE;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
-- Entity PC: entity defining the pins and ports of the programmcounter
|
||||
entity pc is
|
||||
port (clk : in std_logic; -- Clock input for timing
|
||||
en_pc : in one_bit; -- activates PC
|
||||
addr_calc : in ram_addr_t; -- Address from ALU
|
||||
doJump : in one_bit; -- Jump to Address
|
||||
addr : out ram_addr_t -- Address to Decoder
|
||||
);
|
||||
|
||||
end PC;
|
||||
|
||||
|
||||
architecture pro_count of pc is
|
||||
signal addr_out : ram_addr_t := (others => '0');
|
||||
signal addr_out_plus : ram_addr_t := (others => '0');
|
||||
begin
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if en_pc = "1" then
|
||||
-- count
|
||||
if doJump = "1" then
|
||||
addr_out <= addr_calc;
|
||||
-- jump
|
||||
else
|
||||
addr_out <= addr_out_plus;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
addr_out_plus <= (std_logic_vector(to_unsigned(to_integer(unsigned(addr_out)) + 4, ram_addr_size)));
|
||||
addr <= addr_out;
|
||||
|
||||
end pro_count;
|
||||
54
src/ram_block.vhd
Executable file
54
src/ram_block.vhd
Executable file
@@ -0,0 +1,54 @@
|
||||
-- ram_block.vhd
|
||||
-- Created on: Do 3. Nov 20:06:13 CET 2022
|
||||
-- Author(s): Alexander Graf, Carl Ries, Yannick Reiß
|
||||
-- Content: Entity ram_block
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
entity ram_block is
|
||||
|
||||
generic (initMem : ram_t := (others => (others => '0')));
|
||||
|
||||
port (clk : in std_logic;
|
||||
|
||||
addr_a : in std_logic_vector(ram_addr_size - 3 downto 0);
|
||||
data_read_a : out std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
write_b : in one_bit;
|
||||
addr_b : in std_logic_vector(ram_addr_size - 3 downto 0);
|
||||
data_read_b : out std_logic_vector(wordWidth - 1 downto 0);
|
||||
data_write_b : in std_logic_vector(wordWidth - 1 downto 0)
|
||||
|
||||
);
|
||||
|
||||
end ram_block;
|
||||
|
||||
--
|
||||
architecture behavioral of ram_block is
|
||||
|
||||
signal store : ram_t := initMem;
|
||||
|
||||
begin
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
|
||||
-- One synchron write port
|
||||
if write_b = "1" then
|
||||
store(to_integer(unsigned(addr_b(9 downto 2)))) <= data_write_b;
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Two synchron read ports
|
||||
data_read_a <= store(to_integer(unsigned(addr_a(9 downto 2))));
|
||||
data_read_b <= store(to_integer(unsigned(addr_b(9 downto 2))));
|
||||
|
||||
end behavioral;
|
||||
|
||||
147
src/ram_entity_only.vhd
Executable file
147
src/ram_entity_only.vhd
Executable file
@@ -0,0 +1,147 @@
|
||||
-- Created on: Do 3. Nov 20:11:50 CET 2022
|
||||
-- Author(s): Alexander Graf, Carl Ries, Yannick Reiß
|
||||
-- Content: Entity ram and architecture of ram
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
-- Entity ram: Ram storage
|
||||
entity ram is
|
||||
|
||||
generic (zeros : ram_t := (others => (others => '0')));
|
||||
port(
|
||||
clk : in std_logic; -- Clock input for timing
|
||||
instructionAdr : in ram_addr_t; -- Address instruction
|
||||
dataAdr : in ram_addr_t; -- Address data
|
||||
|
||||
writeEnable : in one_bit; -- Read or write mode
|
||||
|
||||
dataIn : in word; -- Write data
|
||||
instruction : out word; -- Get instruction
|
||||
dataOut : out word -- Read data
|
||||
);
|
||||
end ram;
|
||||
|
||||
-- Architecture behavioral of ram: control different ram blocks
|
||||
architecture behavioral of ram is
|
||||
-- write signals
|
||||
signal wr1 : one_bit := "0";
|
||||
signal wr2 : one_bit := "0";
|
||||
signal wr3 : one_bit := "0";
|
||||
signal wr4 : one_bit := "0";
|
||||
|
||||
-- instruction signals
|
||||
signal inst1 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal inst2 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal inst3 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal inst4 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
-- data signals
|
||||
signal data1 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal data2 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal data3 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
signal data4 : std_logic_vector(wordWidth - 1 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
block1 : entity work.instr_memory(behavioral)
|
||||
port map (
|
||||
clk => clk,
|
||||
addr_a => instructionAdr(ram_addr_size - 3 downto 0),
|
||||
write_b => wr1,
|
||||
addr_b => dataAdr(ram_addr_size - 3 downto 0),
|
||||
data_write_b => dataIn,
|
||||
|
||||
data_read_a => inst1,
|
||||
data_read_b => data1
|
||||
);
|
||||
|
||||
block2 : entity work.ram_block(behavioral)
|
||||
port map (
|
||||
clk => clk,
|
||||
addr_a => instructionAdr(9 downto 0),
|
||||
write_b => wr2,
|
||||
addr_b => dataAdr(9 downto 0),
|
||||
data_write_b => dataIn,
|
||||
|
||||
data_read_a => inst2,
|
||||
data_read_b => data2
|
||||
);
|
||||
|
||||
block3 : entity work.ram_block(behavioral)
|
||||
port map (
|
||||
clk => clk,
|
||||
addr_a => instructionAdr(9 downto 0),
|
||||
write_b => wr3,
|
||||
addr_b => dataAdr(9 downto 0),
|
||||
data_write_b => dataIn,
|
||||
|
||||
data_read_a => inst3,
|
||||
data_read_b => data3
|
||||
);
|
||||
|
||||
block4 : entity work.ram_block(behavioral)
|
||||
port map (
|
||||
clk => clk,
|
||||
addr_a => instructionAdr(9 downto 0),
|
||||
write_b => wr4,
|
||||
addr_b => dataAdr(9 downto 0),
|
||||
data_write_b => dataIn,
|
||||
|
||||
data_read_a => inst4,
|
||||
data_read_b => data4
|
||||
);
|
||||
|
||||
addr_block : process (data1, data2, data3, data4, dataAdr(11 downto 10),
|
||||
inst1, inst2, inst3, inst4,
|
||||
instructionAdr(11 downto 10), writeEnable) -- run process addr_block when list changes
|
||||
begin
|
||||
-- enable write
|
||||
case dataAdr(11 downto 10) is
|
||||
when "00" =>
|
||||
wr1 <= writeEnable;
|
||||
wr2 <= "0";
|
||||
wr3 <= "0";
|
||||
wr4 <= "0";
|
||||
when "01" =>
|
||||
wr1 <= "0";
|
||||
wr2 <= writeEnable;
|
||||
wr3 <= "0";
|
||||
wr4 <= "0";
|
||||
when "10" =>
|
||||
wr1 <= "0";
|
||||
wr2 <= "0";
|
||||
wr3 <= writeEnable;
|
||||
wr4 <= "0";
|
||||
when "11" =>
|
||||
wr1 <= "0";
|
||||
wr2 <= "0";
|
||||
wr3 <= "0";
|
||||
wr4 <= writeEnable;
|
||||
when others =>
|
||||
wr1 <= "0";
|
||||
wr2 <= "0";
|
||||
wr3 <= "0";
|
||||
wr4 <= "0";
|
||||
end case;
|
||||
|
||||
-- instruction data
|
||||
case instructionAdr(11 downto 10) is
|
||||
when "00" => instruction <= inst1;
|
||||
when "01" => instruction <= inst2;
|
||||
when "10" => instruction <= inst3;
|
||||
when others => instruction <= inst4;
|
||||
end case;
|
||||
|
||||
-- data data
|
||||
case dataAdr(11 downto 10) is
|
||||
when "00" => dataOut <= data1;
|
||||
when "01" => dataOut <= data2;
|
||||
when "10" => dataOut <= data3;
|
||||
when others => dataOut <= data4;
|
||||
end case;
|
||||
end process;
|
||||
end behavioral;
|
||||
59
src/registers.vhd
Normal file
59
src/registers.vhd
Normal file
@@ -0,0 +1,59 @@
|
||||
-- registers.vhd
|
||||
-- Created on: So 13. Nov 19:06:55 CET 2022
|
||||
-- Author(s): Alexander Graf, Carl Ries, Yannick Reiß
|
||||
-- Content: Entity registers
|
||||
|
||||
--------------------------------------------------------------
|
||||
-- important constants and types from riscv_types (LN 104ff.)
|
||||
--
|
||||
-- constant reg_adr_size : integer := 5;
|
||||
-- constant reg_size : integer := 32;
|
||||
-- type regFile is array (reg_size - 1 downto 0) of word;
|
||||
--------------------------------------------------------------
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.riscv_types.all;
|
||||
|
||||
-- Entity registers: entity defining the pins and ports of the registerblock
|
||||
entity registers is
|
||||
generic (initRegs : regFile := (others => (others => '0')));
|
||||
port(
|
||||
clk : in std_logic; -- input for clock (control device)
|
||||
en_reg_wb : in one_bit; -- enable register write back (?)
|
||||
data_in : in word; -- Data to be written into the register
|
||||
wr_idx : in reg_idx; -- register to write to
|
||||
r1_idx : in reg_idx; -- first register to read from
|
||||
r2_idx : in reg_idx; -- second register to read from
|
||||
write_enable : in one_bit; -- enable writing to wr_idx
|
||||
r1_out : out word; -- data from first register
|
||||
r2_out : out word; -- data from second register
|
||||
led_out : out word -- output reg 2 to led
|
||||
);
|
||||
end registers;
|
||||
|
||||
-- Architecture structure of registers: read from two, write to one
|
||||
architecture structure of registers is
|
||||
signal registerbench : regFile := initRegs;
|
||||
begin
|
||||
|
||||
-- react only on clock changes
|
||||
process (clk) -- runs only, when clk changed
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
-- check if write is enabled
|
||||
if to_integer(unsigned(write_enable)) = 1 then
|
||||
-- write data_in to wr_idx
|
||||
registerbench(to_integer(unsigned(wr_idx))) <= data_in;
|
||||
end if;
|
||||
registerbench(0) <= std_logic_vector(to_unsigned(0, wordWidth));
|
||||
end if;
|
||||
end process;
|
||||
-- read from both reading registers
|
||||
r1_out <= registerbench(to_integer(unsigned(r1_idx)));
|
||||
r2_out <= registerbench(to_integer(unsigned(r2_idx)));
|
||||
led_out <= registerbench(2);
|
||||
|
||||
end structure;
|
||||
136
src/riscv_types.vhd
Executable file
136
src/riscv_types.vhd
Executable file
@@ -0,0 +1,136 @@
|
||||
-- riscv_types.vhd
|
||||
-- Created on: So 13. Nov 19:05:44 CET 2022
|
||||
-- Author(s): Carl Ries, Yannick Reiß, Alexander Graf
|
||||
-- Content: All types needed in processor
|
||||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package riscv_types is
|
||||
|
||||
-- internal opCodes/enums for instructions
|
||||
type uOP is (uNOP, uLUI, uAUIPC, uJAL, uJALR, uBEQ, uBNE, uBLT, uBGE, uBLTU, uBGEU,
|
||||
uLB, uLH, uLW, uLBU, uLHU, uSB, uSH, uSW, uADDI, uSLTI, uSLTIU,
|
||||
uXORI, uORI, uANDI, uSLLI, uSRLI, uSRAI, uADD, uSUB, uSLL, uSLT,
|
||||
uSLTU, uXOR, uSRL, uSRA, uOR, uAND, uECALL);
|
||||
|
||||
-- internal opCodes/enums for alu instructions
|
||||
type aluOP is (uNOP, uADD, uSUB, uSLL, uSLT, uSLTU, uXOR, uSRL, uSRA, uOR, uAND);
|
||||
|
||||
-- internal instruction formats
|
||||
type inst_formats is (R, I, S, B, U, J);
|
||||
|
||||
-- internal immediat formats
|
||||
type imm_formats is (I, S, B, U, J);
|
||||
|
||||
-- cpu states
|
||||
type cpuStates is (stIF, stDEC, stOF, stEXEC, stWB);
|
||||
|
||||
-- internal opCodes/enums for memory operation
|
||||
type memOP is (uNOP, uLB, uLH, uLW, uLBU, uLHU, uSB, uSH, uSW);
|
||||
|
||||
-- internal opCodes/enums for branching
|
||||
type branchOP is (uNOP, uEQ, uNE, uLT, uLTU, uGE, uGEU);
|
||||
|
||||
-- Size of words
|
||||
constant wordWidth : integer := 32;
|
||||
|
||||
-- bit vectors for different types
|
||||
subtype word is std_logic_vector(wordWidth - 1 downto 0); -- 32bit (word)
|
||||
subtype half is std_logic_vector(16 - 1 downto 0); -- 16bit (half)
|
||||
subtype byte is std_logic_vector(8 - 1 downto 0); -- 8bit (byte)
|
||||
subtype four_bit is std_logic_vector(4 - 1 downto 0); -- 4bit vector
|
||||
subtype two_bit is std_logic_vector(2 - 1 downto 0); -- 2bit vector
|
||||
subtype one_bit is std_logic_vector(1 - 1 downto 0); -- 1bit vector
|
||||
subtype instruction is std_logic_vector(wordWidth - 1 downto 0); -- instruction
|
||||
subtype opcode is std_logic_vector(7 - 1 downto 0); -- 7bit opcode
|
||||
subtype reg_idx is std_logic_vector(5 - 1 downto 0); -- register index
|
||||
subtype funct3 is std_logic_vector(3 - 1 downto 0); -- 3bit sub opcode
|
||||
subtype shamt is std_logic_vector(5 - 1 downto 0); -- shift amount
|
||||
subtype upper_imm is std_logic_vector(31 downto 12); -- upper immediate
|
||||
subtype imm_12 is std_logic_vector(12 - 1 downto 0); -- 12bit immediate
|
||||
|
||||
|
||||
-- constants for the 7bit opcode field in a normal 32bit instruction.
|
||||
-- for 32bit size instructions the last 2 bits always have to be '1'
|
||||
-- xxxxx11
|
||||
constant opc_LUI : opcode := "0110111"; -- load upper immediate
|
||||
constant opc_AUIPC : opcode := "0010111"; -- add upper immediate to pc
|
||||
constant opc_JAL : opcode := "1101111"; -- jump and link
|
||||
constant opc_JALR : opcode := "1100111"; -- jump and link register
|
||||
constant opc_BRANCH : opcode := "1100011"; -- branch --
|
||||
constant opc_LOAD : opcode := "0000011"; -- load --
|
||||
constant opc_STORE : opcode := "0100011"; -- store --
|
||||
constant opc_ALUI : opcode := "0010011"; -- alu immediate --
|
||||
constant opc_ALUR : opcode := "0110011"; -- alu register --
|
||||
constant opc_FENCE : opcode := "0001111"; -- fence
|
||||
constant opc_ECALL : opcode := "1110011"; -- ecall
|
||||
constant opc_EBREAK : opcode := "1110011"; -- break
|
||||
constant opc_NULL : opcode := "0000000"; -- invalid
|
||||
|
||||
-- constant for alu double funct3 entrys. (e.g. SUB instruction)
|
||||
constant alu_flag : std_logic_vector(7 - 1 downto 0) := "0100000";
|
||||
|
||||
-- constants for the funct3 field on branches
|
||||
constant branch_EQ : funct3 := "000";
|
||||
constant branch_NE : funct3 := "001";
|
||||
constant branch_LT : funct3 := "100";
|
||||
constant branch_GE : funct3 := "101";
|
||||
constant branch_LTU : funct3 := "110";
|
||||
constant branch_GEU : funct3 := "111";
|
||||
|
||||
-- constants for the funct3 field on loads
|
||||
constant load_B : funct3 := "000"; -- byte
|
||||
constant load_H : funct3 := "001"; -- half
|
||||
constant load_W : funct3 := "010"; -- word
|
||||
constant load_LBU : funct3 := "100"; -- byte unsigned
|
||||
constant load_LHU : funct3 := "101"; -- half unsigned
|
||||
|
||||
-- constants for the funct3 field on stores
|
||||
constant store_B : funct3 := "000"; -- byte
|
||||
constant store_H : funct3 := "001"; -- half
|
||||
constant store_W : funct3 := "010"; -- word
|
||||
|
||||
-- constants for the funct3 field for alu
|
||||
constant alu_ADD : funct3 := "000"; -- add
|
||||
constant alu_SUB : funct3 := "000"; -- sub also needs alu_flag set
|
||||
constant alu_SLT : funct3 := "010"; -- set less than
|
||||
constant alu_SLTU : funct3 := "011"; -- set less than immediate
|
||||
constant alu_AND : funct3 := "111"; -- and
|
||||
constant alu_OR : funct3 := "110"; -- or
|
||||
constant alu_XOR : funct3 := "100"; -- xor
|
||||
constant alu_SLL : funct3 := "001"; -- shift left logical
|
||||
constant alu_SRL : funct3 := "101"; -- shift right logical
|
||||
constant alu_SRA : funct3 := "101"; -- shift right arithmetic
|
||||
|
||||
-- regFile constants and type
|
||||
constant reg_adr_size : integer := 5;
|
||||
constant reg_size : integer := 32;
|
||||
type regFile is array (reg_size - 1 downto 0) of word;
|
||||
|
||||
-- ram constants and type
|
||||
constant ram_size : natural := 4096;
|
||||
constant ram_block_size : natural := 1024;
|
||||
constant ram_addr_size : natural := 12;
|
||||
|
||||
subtype ram_addr_t is std_logic_vector(ram_addr_size -1 downto 0);
|
||||
-- type ram_t is array(0 to ram_addr_size - 1) of word;
|
||||
type ram_t is array(0 to 255) of word;
|
||||
|
||||
-- const for multiplexer sources
|
||||
constant mul_wr_alures : two_bit := "00";
|
||||
constant mul_wr_memread : two_bit := "01";
|
||||
constant mul_wr_pc4 : two_bit := "10";
|
||||
|
||||
constant mul_alu_reg : one_bit := "0";
|
||||
|
||||
constant mul_alu_pc : one_bit := "1";
|
||||
constant mul_alu_imm : one_bit := "1";
|
||||
|
||||
constant mul_pc_pc4 : one_bit := "0";
|
||||
constant mul_pc_alu : one_bit := "1";
|
||||
|
||||
end riscv_types;
|
||||
|
||||
package body riscv_types is
|
||||
end riscv_types;
|
||||
Reference in New Issue
Block a user