Newer
Older
-------------------------------------------------------------------------------
-- Project ELE8304 : Circuits intégrés à très grande échelle
-------------------------------------------------------------------------------
-- File riscv_pkg.vhd
-- Author Mickael Fiorentino <mickael.fiorentino@polymtl.ca>
-- Lab GRM - Polytechnique Montreal
-- Date 2019-08-09
-------------------------------------------------------------------------------
-- Brief Package for constants, components, and procedures
-------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
package riscv_pkg is
------------------------------------------------------------------------------
-- MAIN PARAMETERS
------------------------------------------------------------------------------
constant XLEN : positive := 32;
constant REG_WIDTH : positive := 5;
-- Main memory parameters
constant DMEM_ADDR_WIDTH : positive := 10;
constant IMEM_ADDR_WIDTH : positive := 10;
------------------------------------------------------------------------------
-- INSTRUCTION FORMATS
------------------------------------------------------------------------------
constant SHAMT_H : natural := 24;
constant SHAMT_L : natural := 20;
constant SHAMT_WIDTH : natural := SHAMT_H-SHAMT_L+1;
constant OPCODE_WIDTH : positive := 7;
-- ISA Opcodes
constant OPCODE_LUI : std_logic_vector := "0110111";
constant OPCODE_JAL : std_logic_vector := "1101111";
constant OPCODE_JALR : std_logic_vector := "1100111";
constant OPCODE_BEQ : std_logic_vector := "1100011";
constant OPCODE_LW : std_logic_vector := "0000011";
constant OPCODE_SW : std_logic_vector := "0100011";
constant OPCODE_ALU_I_TYPE : std_logic_vector := "0010011"; -- All I-types with ALU
constant OPCODE_ALU_R_TYPE : std_logic_vector := "0110011"; -- All R-types with ALU
-- FUNCT7 field
-- Identifies SUB and Arithmetic shifts
constant FUNCT7_SUB_ARITH_SH : std_logic_vector := "0100000";
constant FUNCT7_GENERIC : std_logic_vector := "0000000";
-- FUNCT3 field
-- Identifies instruction more specifically than the opcode
-- The field is the same for the I-type and R-type versions of a same operation
-- The field is the same for logic and arithmetic shifts of the same direction (L, R)
-- The field is the same for ADD and SUB (distriminated with FUNCT7)
constant FUNCT3_JALR : std_logic_vector := "000";
constant FUNCT3_BEQ : std_logic_vector := "000";
constant FUNCT3_LW : std_logic_vector := "010";
constant FUNCT3_SW : std_logic_vector := "010";
constant FUNCT3_ADD : std_logic_vector := "000";
constant FUNCT3_SLT : std_logic_vector := "010";
constant FUNCT3_SLTU : std_logic_vector := "011";
constant FUNCT3_XOR : std_logic_vector := "100";
constant FUNCT3_OR : std_logic_vector := "110";
constant FUNCT3_AND : std_logic_vector := "111";
constant FUNCT3_SL : std_logic_vector := "001";
constant FUNCT3_SR : std_logic_vector := "101";
--constant FUNCT3_SUB : std_logic_vector := "000";
------------------------------------------------------------------------------
-- ALU
------------------------------------------------------------------------------
constant ALUOP_WIDTH : natural := 3;
constant ALUOP_SH_RIGHT : std_logic_vector := "000"; -- 0
constant ALUOP_SH_LEFT : std_logic_vector := "001"; -- 1
constant ALUOP_SLT : std_logic_vector := "010"; -- 2
constant ALUOP_ADD : std_logic_vector := "011"; -- 3
constant ALUOP_AND : std_logic_vector := "100"; -- 4
constant ALUOP_XOR : std_logic_vector := "101"; -- 5
constant ALUOP_OR : std_logic_vector := "110"; -- 6
-- Bits de contrôles
constant SIGN_UNSIGNED : std_logic := '0';
constant SIGN_SIGNED : std_logic := '1';
constant ARITH_ADD : std_logic := '0';
constant ARITH_SUBTRACT : std_logic := '1';
constant SHIFT_LOGIC : std_logic := '0';
constant SHIFT_ARITH : std_logic := '1';
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
------------------------------------------------------------------------------
-- COMPONENTS
------------------------------------------------------------------------------
component riscv_adder is
generic (
N : positive);
port (
i_a : in std_logic_vector(N-1 downto 0);
i_b : in std_logic_vector(N-1 downto 0);
i_sign : in std_logic;
i_sub : in std_logic;
o_sum : out std_logic_vector(N downto 0));
end component riscv_adder;
component riscv_alu is
port (
i_arith : in std_logic;
i_sign : in std_logic;
i_opcode : in std_logic_vector(ALUOP_WIDTH-1 downto 0);
i_shamt : in std_logic_vector(SHAMT_WIDTH-1 downto 0);
i_src1 : in std_logic_vector(XLEN-1 downto 0);
i_src2 : in std_logic_vector(XLEN-1 downto 0);
o_res : out std_logic_vector(XLEN-1 downto 0));
end component riscv_alu;
component riscv_rf is
port (
i_clk : in std_logic;
i_rstn : in std_logic;
i_we : in std_logic;
i_addr_ra : in std_logic_vector(REG_WIDTH-1 downto 0);
o_data_ra : out std_logic_vector(XLEN-1 downto 0);
i_addr_rb : in std_logic_vector(REG_WIDTH-1 downto 0);
o_data_rb : out std_logic_vector(XLEN-1 downto 0);
i_addr_w : in std_logic_vector(REG_WIDTH-1 downto 0);
i_data_w : in std_logic_vector(XLEN-1 downto 0));
end component riscv_rf;
component riscv_pc is
generic (
RESET_VECTOR : natural);
port (
i_clk : in std_logic;
i_rstn : in std_logic;
i_stall : in std_logic;
i_transfert : in std_logic;
i_target : in std_logic_vector(XLEN-1 downto 0);
o_pc : out std_logic_vector(XLEN-1 downto 0));
end component riscv_pc;
component riscv_perf is
port (
i_rstn : in std_logic;
i_clk : in std_logic;
i_en : in std_logic;
o_cycles : out std_logic_vector(XLEN-1 downto 0);
o_insts : out std_logic_vector(XLEN-1 downto 0));
end component riscv_perf;
------------------------------------------------------------------------------
-- Pipeline stage interface registers
------------------------------------------------------------------------------
type fetch_reg is record
instruction : std_logic_vector(XLEN-1 downto 0); -- = imem_read
pc : std_logic_vector(XLEN-1 downto 0);
end record fetch_reg;
type decode_reg is record

Yann Roberge
committed
opcode : std_logic_vector(OPCODE_WIDTH-1 downto 0);
alu_opcode : std_logic_vector(ALUOP_WIDTH-1 downto 0);
arith : std_logic;
sign : std_logic;
jump : std_logic;
branch : std_logic;
pc : std_logic_vector(XLEN-1 downto 0);
imm : std_logic_vector(XLEN-1 downto 0);

Yann Roberge
committed
rs1_addr : std_logic_vector(REG_WIDTH-1 downto 0);
rs2_addr : std_logic_vector(REG_WIDTH-1 downto 0);
rd_addr : std_logic_vector(REG_WIDTH-1 downto 0);
end record decode_reg;
type execute_reg is record

Yann Roberge
committed
opcode : std_logic_vector(OPCODE_WIDTH-1 downto 0);

Yann Roberge
committed
alu_result : std_logic_vector(XLEN-1 downto 0);
store_data : std_logic_vector(XLEN-1 downto 0);
rd_addr : std_logic_vector(REG_WIDTH-1 downto 0);
end record execute_reg;
type memory_reg is record
opcode : std_logic_vector(OPCODE_WIDTH-1 downto 0);
alu_result : std_logic_vector(XLEN-1 downto 0);
rd_addr : std_logic_vector(REG_WIDTH-1 downto 0);
end record memory_reg;
type write_back_reg is record
opcode : std_logic_vector(OPCODE_WIDTH-1 downto 0);
wr_addr : std_logic_vector(REG_WIDTH-1 downto 0); -- rd_addr
wr_data : std_logic_vector(XLEN-1 downto 0); -- rd_data
end record write_back_reg;