mirror of
https://github.com/xarc/harv.git
synced 2025-04-18 19:24:51 -04:00
HARV project
This commit is contained in:
parent
807fe54447
commit
3dcef8bce8
22 changed files with 3161 additions and 2 deletions
12
.gitignore
vendored
Normal file
12
.gitignore
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
*/**
|
||||
!*/
|
||||
!/hdl/**/*.vhd
|
||||
!/sim/**/*.vhd
|
||||
!/src/**/*.asm
|
||||
!/script/*.sh
|
||||
!/script/*.py
|
||||
!/script/*.do
|
||||
!/script/*.tcl
|
||||
!/script/*.ld
|
||||
!/xilinx/*.wcfg
|
||||
!/images/*.png
|
44
README.md
44
README.md
|
@ -1,2 +1,42 @@
|
|||
# harv
|
||||
HARV - HArdened Risc-V
|
||||
# HARV - HArdened Risc-V
|
||||
|
||||
The focus of the HARV processor core is harsh environments. It implements the integer instruction-set of the RISC-V specification (RV32I), except system calls. To provide reliability for harsh environments, we implement the fault tolerance techniques TMR (Triple-Modular Redundancy) and Hamming code to the different parts of the processor. These techniques improve the reliability by mitigating or correcting errors caused by the single-event effects SEU (Single-Event Upset) and SET (Single-Event Transient).
|
||||
|
||||
HARV is being developed in partnership between the **LEDS - Laboratory of Embedded and Distributed Systems** and the **LIRMM - Laboratoire d’Informatique, de Robotique et de Microélectronique de Montpellier**.
|
||||
|
||||
The HARV was introduced by the following paper published at the IEEE DTIS 2021:
|
||||
|
||||
D. A. Santos, L. M. Luza, C. A. Zeferino, L. Dilillo and D. R. Melo, "A Low-Cost Fault-Tolerant RISC-V Processor for Space Systems," *2020 15th Design & Technology of Integrated Systems in Nanoscale Era (DTIS), 2020*, pp. 1-5, doi: [10.1109/DTIS48698.2020.9081185](https://doi.org/10.1109/DTIS48698.2020.9081185).
|
||||
|
||||
The current mantainer of this repository is [Douglas Almeida dos Santos](https://github.com/Douglasas).
|
||||
|
||||
## Getting started
|
||||
|
||||
This getting started is a tutorial for the simulation of the simple assembly program `src/test.asm`
|
||||
|
||||
Requirements:
|
||||
- Vivado 2020.2
|
||||
- RARS 1.5
|
||||
|
||||
Open the RARS and open the assembly file from the sources folder.
|
||||
|
||||
You will need to configure the memory to work with the testbench parameters. The following image shows the required memory configuration.
|
||||
|
||||

|
||||
|
||||
After that, you may export the assembly code so it can be used by the testbench.
|
||||
Dump both the `.text` and `.data` sections to the `src` folder. The following images shows the configurations that must be used for the memory dump.
|
||||
The file paths must be `src/test_text.dump` and `src/test_data.dump` for the sections, respectively.
|
||||
|
||||

|
||||

|
||||
|
||||
The next step is to create and open the Vivado project.
|
||||
|
||||
Execute the following command at the terminal and at the root project directory. Note that Vivado must be in the path.
|
||||
|
||||
```
|
||||
vivado -mode tcl -source script/project.tcl
|
||||
```
|
||||
|
||||
After that, you may open the Vivado project through the interface and run the simulation set 1.
|
||||
|
|
59
hdl/alu.vhd
Normal file
59
hdl/alu.vhd
Normal file
|
@ -0,0 +1,59 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.all;
|
||||
|
||||
entity alu is
|
||||
port (
|
||||
-- input ports
|
||||
data1_i : in std_logic_vector(31 downto 0);
|
||||
data2_i : in std_logic_vector(31 downto 0);
|
||||
operation_i : in std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
-- output ports
|
||||
zero_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of alu is
|
||||
signal add_sub_data2_w : signed(31 downto 0);
|
||||
signal add_sub_w : std_logic_vector(31 downto 0);
|
||||
signal and_w : std_logic_vector(31 downto 0);
|
||||
signal or_w : std_logic_vector(31 downto 0);
|
||||
signal xor_w : std_logic_vector(31 downto 0);
|
||||
signal sll_w : std_logic_vector(31 downto 0);
|
||||
signal srl_w : std_logic_vector(31 downto 0);
|
||||
signal sra_w : std_logic_vector(31 downto 0);
|
||||
signal slt_w : std_logic_vector(31 downto 0);
|
||||
signal sltu_w : std_logic_vector(31 downto 0);
|
||||
signal result_w : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
add_sub_data2_w <= signed(data2_i) when operation_i = ALU_ADD_OP else -signed(data2_i);
|
||||
add_sub_w <= std_logic_vector(signed(data1_i) + add_sub_data2_w);
|
||||
and_w <= data1_i and data2_i;
|
||||
or_w <= data1_i or data2_i;
|
||||
xor_w <= data1_i xor data2_i;
|
||||
sll_w <= std_logic_vector(shift_left(unsigned(data1_i), to_integer(unsigned(data2_i))));
|
||||
srl_w <= std_logic_vector(shift_right(unsigned(data1_i), to_integer(unsigned(data2_i))));
|
||||
sra_w <= std_logic_vector(shift_right(signed(data1_i), to_integer(unsigned(data2_i))));
|
||||
slt_w <= (0 => '1', others => '0') when signed(data1_i) < signed(data2_i) else (others => '0');
|
||||
sltu_w <= (0 => '1', others => '0') when unsigned(data1_i) < unsigned(data2_i) else (others => '0');
|
||||
|
||||
with operation_i select result_w <=
|
||||
add_sub_w when ALU_ADD_OP,
|
||||
add_sub_w when ALU_SUB_OP,
|
||||
sll_w when ALU_SLL_OP,
|
||||
slt_w when ALU_SLT_OP,
|
||||
sltu_w when ALU_SLTU_OP,
|
||||
xor_w when ALU_XOR_OP,
|
||||
srl_w when ALU_SRL_OP,
|
||||
sra_w when ALU_SRA_OP,
|
||||
or_w when ALU_OR_OP,
|
||||
and_w when ALU_AND_OP,
|
||||
(others => '0') when others;
|
||||
|
||||
data_o <= result_w;
|
||||
zero_o <= '1' when result_w = (31 downto 0 => '0') else '0';
|
||||
end architecture;
|
282
hdl/control.vhd
Normal file
282
hdl/control.vhd
Normal file
|
@ -0,0 +1,282 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.all;
|
||||
|
||||
entity control is
|
||||
port (
|
||||
-- input ports
|
||||
-- processor status
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
|
||||
-- instruction decode
|
||||
opcode_i : in std_logic_vector(6 downto 0);
|
||||
funct3_i : in std_logic_vector(2 downto 0);
|
||||
funct7_i : in std_logic_vector(6 downto 0);
|
||||
funct12_i : in std_logic_vector(11 downto 0);
|
||||
|
||||
-- sync
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
|
||||
-- output ports
|
||||
-- processor status
|
||||
imem_req_o : out std_logic;
|
||||
dmem_req_o : out std_logic;
|
||||
|
||||
update_pc_o : out std_logic;
|
||||
trap_o : out std_logic;
|
||||
|
||||
-- ALU operations
|
||||
aluop_o : out std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
alusrc_imm_o : out std_logic;
|
||||
-- immediate selector
|
||||
imm_shamt_o : out std_logic;
|
||||
imm_up_o : out std_logic;
|
||||
-- register bank
|
||||
regwr_o : out std_logic;
|
||||
-- control transfer
|
||||
inv_branch_o : out std_logic;
|
||||
branch_o : out std_logic;
|
||||
jump_o : out std_logic;
|
||||
jalr_o : out std_logic;
|
||||
ecall_o : out std_logic;
|
||||
-- mem access
|
||||
memrd_o : out std_logic;
|
||||
memwr_o : out std_logic;
|
||||
byte_en_o : out std_logic_vector(1 downto 0);
|
||||
mem_usgn_o : out std_logic; -- unsigned data
|
||||
-- U type
|
||||
load_upimm_o : out std_logic;
|
||||
auipc_o : out std_logic;
|
||||
-- csr control
|
||||
csr_enable_o : out std_logic;
|
||||
csr_source_imm_o : out std_logic;
|
||||
csr_maskop_o : out std_logic;
|
||||
csr_clearop_o : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of control is
|
||||
--------- PROCESSOR STATUS -----------
|
||||
subtype proc_status_t is std_logic_vector(2 downto 0);
|
||||
constant STAT_IDLE : proc_status_t := "000";
|
||||
constant STAT_REQ_INSTR : proc_status_t := "001";
|
||||
constant STAT_RUN : proc_status_t := "010";
|
||||
constant STAT_DMEM_STALL : proc_status_t := "011";
|
||||
constant STAT_UPDATE_PC : proc_status_t := "100";
|
||||
constant STAT_TRAP : proc_status_t := "101";
|
||||
|
||||
signal proc_status_r : proc_status_t;
|
||||
signal next_proc_status_w : proc_status_t;
|
||||
|
||||
-------- INSTRUCTION DECODE ----------
|
||||
subtype instr_format_t is std_logic_vector(3 downto 0);
|
||||
constant R : instr_format_t := x"1";
|
||||
constant I_jalr : instr_format_t := x"2";
|
||||
constant I_load : instr_format_t := x"3";
|
||||
constant I_arith : instr_format_t := x"4";
|
||||
constant I_fence : instr_format_t := x"5";
|
||||
constant I_system : instr_format_t := x"6";
|
||||
constant S : instr_format_t := x"7";
|
||||
constant B : instr_format_t := x"8";
|
||||
constant U_lui : instr_format_t := x"9";
|
||||
constant U_auipc : instr_format_t := x"A";
|
||||
constant U_jal : instr_format_t := x"B";
|
||||
|
||||
--- CSR TYPES ---
|
||||
constant SYS_ECALL : std_logic_vector(2 downto 0) := "000";
|
||||
constant SYS_CSRRW : std_logic_vector(2 downto 0) := "001"; -- Atomic Read/Write CSR
|
||||
constant SYS_CSRRS : std_logic_vector(2 downto 0) := "010"; -- Atomic Read and Set Bits in CSR
|
||||
constant SYS_CSRRC : std_logic_vector(2 downto 0) := "011"; -- Atomic Read and Clear Bits in CSR
|
||||
constant SYS_CSRRWI : std_logic_vector(2 downto 0) := "101";
|
||||
constant SYS_CSRRSI : std_logic_vector(2 downto 0) := "110";
|
||||
constant SYS_CSRRCI : std_logic_vector(2 downto 0) := "111";
|
||||
|
||||
-- auxiliar signals
|
||||
signal memwr_w : std_logic;
|
||||
signal memrd_w : std_logic;
|
||||
signal memreq_w : std_logic;
|
||||
|
||||
-- opcodes
|
||||
|
||||
signal instr_format_w : instr_format_t;
|
||||
|
||||
-- signal rshift_op_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
-- signal add_op_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
signal arith_aluop_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
signal branch_op_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
|
||||
begin
|
||||
------------------------- PROCESSOR STATUS ------------------------------
|
||||
-- STAT_REQ_INSTR
|
||||
imem_req_o <= '1' when proc_status_r = STAT_REQ_INSTR else '0';
|
||||
|
||||
-- STAT_DMEM_STALL
|
||||
memreq_w <= memrd_w or memwr_w;
|
||||
dmem_req_o <= '1' when proc_status_r = STAT_DMEM_STALL else '0';
|
||||
|
||||
-- STAT_UPDATE_PC
|
||||
update_pc_o <= '1' when proc_status_r = STAT_UPDATE_PC else
|
||||
'1' when proc_status_r = STAT_TRAP else
|
||||
'0';
|
||||
trap_o <= '1' when proc_status_r = STAT_TRAP else '0';
|
||||
|
||||
|
||||
PROC_CURRENT_STATUS : process(clk_i, rstn_i)
|
||||
begin
|
||||
if rstn_i = '0' then
|
||||
proc_status_r <= STAT_IDLE;
|
||||
elsif rising_edge(clk_i) then
|
||||
proc_status_r <= next_proc_status_w;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
PROC_NEXT_STATUS : process(proc_status_r, start_i, imem_gnt_i, imem_err_i, dmem_outofrange_i, memreq_w, dmem_gnt_i)
|
||||
begin
|
||||
case proc_status_r is
|
||||
|
||||
when STAT_IDLE =>
|
||||
if start_i = '1' then
|
||||
next_proc_status_w <= STAT_REQ_INSTR;
|
||||
else
|
||||
next_proc_status_w <= STAT_IDLE;
|
||||
end if;
|
||||
|
||||
when STAT_REQ_INSTR =>
|
||||
if imem_err_i = '1' then
|
||||
next_proc_status_w <= STAT_IDLE;
|
||||
|
||||
elsif imem_gnt_i = '1' then
|
||||
next_proc_status_w <= STAT_RUN;
|
||||
|
||||
else
|
||||
next_proc_status_w <= STAT_REQ_INSTR;
|
||||
end if;
|
||||
|
||||
when STAT_RUN =>
|
||||
if memreq_w = '1' then
|
||||
next_proc_status_w <= STAT_DMEM_STALL;
|
||||
else
|
||||
next_proc_status_w <= STAT_UPDATE_PC;
|
||||
end if;
|
||||
|
||||
when STAT_DMEM_STALL =>
|
||||
if dmem_outofrange_i = '1' then -- or dmem_sbu_i = '1' or dmem_dbu_i = '1' then
|
||||
next_proc_status_w <= STAT_TRAP;
|
||||
elsif dmem_gnt_i = '1' then
|
||||
next_proc_status_w <= STAT_UPDATE_PC;
|
||||
else
|
||||
next_proc_status_w <= STAT_DMEM_STALL;
|
||||
end if;
|
||||
|
||||
when STAT_UPDATE_PC =>
|
||||
next_proc_status_w <= STAT_REQ_INSTR;
|
||||
|
||||
when STAT_TRAP =>
|
||||
next_proc_status_w <= STAT_REQ_INSTR;
|
||||
|
||||
when others =>
|
||||
next_proc_status_w <= STAT_TRAP;
|
||||
|
||||
end case;
|
||||
end process;
|
||||
|
||||
------------------------ INSTRUCTIONS DECODE ----------------------------
|
||||
with opcode_i select instr_format_w <=
|
||||
R when "0110011",
|
||||
I_jalr when "1100111",
|
||||
I_load when "0000011",
|
||||
I_arith when "0010011",
|
||||
I_fence when "0001111",
|
||||
I_system when "1110011",
|
||||
S when "0100011",
|
||||
B when "1100011",
|
||||
U_lui when "0110111",
|
||||
U_auipc when "0010111",
|
||||
U_jal when "1101111",
|
||||
(others => '0') when others;
|
||||
--------------------------------- ALU -----------------------------------
|
||||
-- rshift_op_w <= ALU_SRL_OP when funct7_i = "0000000" else ALU_SRA_OP;
|
||||
-- add_op_w <= ALU_SUB_OP when funct7_i = "0100000" and instr_format_w = R else ALU_ADD_OP;
|
||||
--
|
||||
-- with funct3_i select arith_aluop_w <=
|
||||
-- add_op_w when "000",
|
||||
-- ALU_SLL_OP when "001",
|
||||
-- ALU_SLT_OP when "010",
|
||||
-- ALU_SLTU_OP when "011",
|
||||
-- ALU_XOR_OP when "100",
|
||||
-- rshift_op_w when "101",
|
||||
-- ALU_OR_OP when "110",
|
||||
-- ALU_AND_OP when "111",
|
||||
-- (others => '0') when others;
|
||||
arith_aluop_w <= funct7_i(5) & funct3_i;
|
||||
|
||||
with funct3_i(2 downto 1) select branch_op_w <=
|
||||
ALU_XOR_OP when "00", -- beq or bne
|
||||
ALU_SLT_OP when "10", -- blt or bge
|
||||
ALU_SLTU_OP when "11", -- bltu or bgeu
|
||||
(others => '0') when others;
|
||||
|
||||
aluop_o <= arith_aluop_w when instr_format_w = I_arith or
|
||||
instr_format_w = R else
|
||||
branch_op_w when instr_format_w = B else
|
||||
ALU_ADD_OP; -- when instr_format_w = U_auipc, I_load, S
|
||||
alusrc_imm_o <= '1' when instr_format_w /= R and instr_format_w /= B else '0';
|
||||
|
||||
------------------------ IMMEDIATE SELECTOR ------------------------------
|
||||
-- instr[24:20]
|
||||
imm_shamt_o <= '1' when (arith_aluop_w = ALU_SLL_OP or
|
||||
arith_aluop_w = ALU_SRL_OP or
|
||||
arith_aluop_w = ALU_SRA_OP) and
|
||||
instr_format_w = I_arith else '0';
|
||||
-- instr[31:12] -> imm[31:12]
|
||||
imm_up_o <= '1' when instr_format_w = U_lui or
|
||||
instr_format_w = U_auipc else '0';
|
||||
|
||||
----------------------------- REGISTER BANK -------------------------------
|
||||
regwr_o <= '1' when proc_status_r = STAT_UPDATE_PC and not (
|
||||
instr_format_w = I_fence or
|
||||
(instr_format_w = I_system and funct3_i = SYS_ECALL) or
|
||||
instr_format_w = S or instr_format_w = I_load or
|
||||
instr_format_w = B) else
|
||||
'1' when proc_status_r = STAT_DMEM_STALL and
|
||||
instr_format_w = I_load and
|
||||
dmem_gnt_i = '1' else
|
||||
'0';
|
||||
|
||||
------------------------------- BRANCHES ----------------------------------
|
||||
inv_branch_o <= funct3_i(2) xor funct3_i(0);
|
||||
branch_o <= '1' when instr_format_w = B else '0';
|
||||
jump_o <= '1' when instr_format_w = U_jal or instr_format_w = I_jalr else '0';
|
||||
jalr_o <= '1' when instr_format_w = I_jalr else '0';
|
||||
|
||||
ecall_o <= '0'; -- '1' when instr_format_w = I_system else
|
||||
|
||||
------------------------------ MEM ACCESS ---------------------------------
|
||||
memrd_w <= '1' when instr_format_w = I_load else '0';
|
||||
memrd_o <= memrd_w;
|
||||
memwr_w <= '1' when instr_format_w = S else '0';
|
||||
memwr_o <= memwr_w;
|
||||
byte_en_o <= funct3_i(1 downto 0) when funct3_i(1) = '0' else "11"; -- byte or halfword -- else word
|
||||
mem_usgn_o <= funct3_i(2);
|
||||
|
||||
-------------------------------- U type -----------------------------------
|
||||
load_upimm_o <= '1' when instr_format_w = U_lui else '0';
|
||||
auipc_o <= '1' when instr_format_w = U_auipc else '0';
|
||||
|
||||
-------------------------- CSR instructions ------------------------------
|
||||
csr_enable_o <= '1' when instr_format_w = I_system and funct3_i /= SYS_ECALL else '0';
|
||||
csr_source_imm_o <= funct3_i(2); -- select source to write the CSR (immediate or register)
|
||||
csr_maskop_o <= funct3_i(1); -- write operation based on mask
|
||||
csr_clearop_o <= funct3_i(0); -- operation is CLEAR, if not, operation is SET
|
||||
|
||||
end architecture;
|
357
hdl/csr.vhd
Normal file
357
hdl/csr.vhd
Normal file
|
@ -0,0 +1,357 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.math_real.ceil;
|
||||
use ieee.math_real.log2;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
entity csr is
|
||||
generic (
|
||||
TMR_CONTROL : boolean;
|
||||
TMR_ALU : boolean;
|
||||
HAMMING_REGFILE : boolean;
|
||||
HAMMING_PC : boolean
|
||||
);
|
||||
port (
|
||||
-- sync
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
-- access interface
|
||||
addr_i : in std_logic_vector(11 downto 0);
|
||||
data_o : out std_logic_vector(31 downto 0);
|
||||
rs1_data_i : in std_logic_vector(31 downto 0);
|
||||
imm_data_i : in std_logic_vector(4 downto 0);
|
||||
-- write control
|
||||
wren_i : in std_logic;
|
||||
source_imm_i : in std_logic;
|
||||
csr_maskop_i : in std_logic;
|
||||
csr_clearop_i : in std_logic;
|
||||
-- trap handling
|
||||
trap_i : in std_logic;
|
||||
uscratch_i : in std_logic_vector(31 downto 0);
|
||||
uepc_i : in std_logic_vector(31 downto 0);
|
||||
ucause_i : in std_logic_vector(31 downto 0);
|
||||
utval_i : in std_logic_vector(31 downto 0);
|
||||
uip_i : in std_logic_vector(31 downto 0);
|
||||
-- error counter inputs
|
||||
reg1_cen_i : in std_logic;
|
||||
reg1_sbu_i : in std_logic;
|
||||
reg1_dbu_i : in std_logic;
|
||||
reg2_cen_i : in std_logic;
|
||||
reg2_sbu_i : in std_logic;
|
||||
reg2_dbu_i : in std_logic;
|
||||
pc_cen_i : in std_logic;
|
||||
pc_sbu_i : in std_logic;
|
||||
pc_dbu_i : in std_logic;
|
||||
dmem_cen_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
control_cen_i : in std_logic;
|
||||
control_err_i : in std_logic;
|
||||
alu_cen_i : in std_logic;
|
||||
alu_err_i : in std_logic;
|
||||
-- hardening configuration outputs
|
||||
hard_pc_o : out std_logic;
|
||||
hard_regfile_o : out std_logic;
|
||||
hard_dmem_o : out std_logic;
|
||||
hard_control_o : out std_logic;
|
||||
hard_alu_o : out std_logic;
|
||||
-- reset cause input
|
||||
poweron_rstn_i : in std_logic;
|
||||
wdt_rstn_i : in std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of csr is
|
||||
-- USER: Counter/Timers
|
||||
constant CYCLE_ADDR : std_logic_vector(11 downto 0) := x"C00";
|
||||
constant TIME_ADDR : std_logic_vector(11 downto 0) := x"C01";
|
||||
constant INSTRET_ADDR : std_logic_vector(11 downto 0) := x"C02";
|
||||
constant CYCLEH_ADDR : std_logic_vector(11 downto 0) := x"C80";
|
||||
constant TIMEH_ADDR : std_logic_vector(11 downto 0) := x"C81";
|
||||
constant INSTRETH_ADDR : std_logic_vector(11 downto 0) := x"C82";
|
||||
-- USER: trap handling
|
||||
constant USCRATCH_ADDR : std_logic_vector(11 downto 0) := x"040";
|
||||
constant UEPC_ADDR : std_logic_vector(11 downto 0) := x"041";
|
||||
constant UCAUSE_ADDR : std_logic_vector(11 downto 0) := x"042";
|
||||
constant UTVAL_ADDR : std_logic_vector(11 downto 0) := x"043";
|
||||
constant UIP_ADDR : std_logic_vector(11 downto 0) := x"044";
|
||||
-- MACHINE: custom error counter registers
|
||||
constant REG1_SBU_ADDR : std_logic_vector(11 downto 0) := x"7C0";
|
||||
constant REG1_DBU_ADDR : std_logic_vector(11 downto 0) := x"7C1";
|
||||
constant REG2_SBU_ADDR : std_logic_vector(11 downto 0) := x"7C2";
|
||||
constant REG2_DBU_ADDR : std_logic_vector(11 downto 0) := x"7C3";
|
||||
constant PC_SBU_ADDR : std_logic_vector(11 downto 0) := x"7C4";
|
||||
constant PC_DBU_ADDR : std_logic_vector(11 downto 0) := x"7C5";
|
||||
constant DMEM_SBU_ADDR : std_logic_vector(11 downto 0) := x"7C6";
|
||||
constant DMEM_DBU_ADDR : std_logic_vector(11 downto 0) := x"7C7";
|
||||
constant CONTROL_ERR_ADDR : std_logic_vector(11 downto 0) := x"7C8";
|
||||
constant ALU_ERR_ADDR : std_logic_vector(11 downto 0) := x"7C9";
|
||||
-- MACHINE: hardening configuration
|
||||
constant HARDEN_CONF_ADDR : std_logic_vector(11 downto 0) := x"BC0";
|
||||
-- MACHINE: information
|
||||
constant MVENDORID_ADDR : std_logic_vector(11 downto 0) := x"F11";
|
||||
constant MARCHID_ADDR : std_logic_vector(11 downto 0) := x"F12";
|
||||
constant MIMPID_ADDR : std_logic_vector(11 downto 0) := x"F13";
|
||||
constant MHARTID_ADDR : std_logic_vector(11 downto 0) := x"F14";
|
||||
-- MACHINE: reset cause
|
||||
constant RSTCAUSE_ADDR : std_logic_vector(11 downto 0) := x"FC0";
|
||||
|
||||
-- Registers from unprivileged specification -- except float CSR
|
||||
signal cycle_r : std_logic_vector(31 downto 0); -- read by RDCYCLE
|
||||
signal time_r : std_logic_vector(31 downto 0); -- read by RDTIME
|
||||
signal instret_r : std_logic_vector(31 downto 0); -- read by RDINSTRET
|
||||
signal cycleh_r : std_logic_vector(31 downto 0); -- read by RDCYCLEH
|
||||
signal timeh_r : std_logic_vector(31 downto 0); -- read by RDTIMEH
|
||||
signal instreth_r : std_logic_vector(31 downto 0); -- read by RDINSTRETH
|
||||
|
||||
-- Registers for trap handling
|
||||
signal uscratch_r : std_logic_vector(31 downto 0); --at 0x040
|
||||
signal uepc_r : std_logic_vector(31 downto 0); --at 0x041
|
||||
signal ucause_r : std_logic_vector(31 downto 0); --at 0x042
|
||||
signal utval_r : std_logic_vector(31 downto 0); --at 0x043
|
||||
signal uip_r : std_logic_vector(31 downto 0); --at 0x044
|
||||
|
||||
-- Registers for error counting
|
||||
signal reg1_sbu_r : std_logic_vector(31 downto 0); -- at 0x7C0
|
||||
signal reg1_dbu_r : std_logic_vector(31 downto 0); -- at 0x7C1
|
||||
|
||||
signal reg2_sbu_r : std_logic_vector(31 downto 0); -- at 0x7C2
|
||||
signal reg2_dbu_r : std_logic_vector(31 downto 0); -- at 0x7C3
|
||||
|
||||
signal pc_sbu_r : std_logic_vector(31 downto 0); -- at 0x7C4
|
||||
signal pc_dbu_r : std_logic_vector(31 downto 0); -- at 0x7C5
|
||||
|
||||
signal dmem_sbu_r : std_logic_vector(31 downto 0); -- at 0x7C6
|
||||
signal dmem_dbu_r : std_logic_vector(31 downto 0); -- at 0x7C7
|
||||
|
||||
signal control_err_r : std_logic_vector(31 downto 0); -- at 0x7C8
|
||||
signal alu_err_r : std_logic_vector(31 downto 0); -- at 0x7C9
|
||||
|
||||
-- Register for hardening flags
|
||||
signal harden_conf_r : std_logic_vector(31 downto 0); -- at 0xBC0
|
||||
|
||||
-- Registers for information registers
|
||||
signal mvendorid_r : std_logic_vector(31 downto 0);
|
||||
signal marchid_r : std_logic_vector(31 downto 0);
|
||||
signal mimpid_r : std_logic_vector(31 downto 0);
|
||||
signal mhartid_r : std_logic_vector(31 downto 0);
|
||||
|
||||
-- Register for reset cause
|
||||
signal rstcause_r : std_logic_vector(31 downto 0);
|
||||
|
||||
-- write and read signals
|
||||
signal wdata_w : std_logic_vector(31 downto 0);
|
||||
signal rdata_w : std_logic_vector(31 downto 0);
|
||||
|
||||
-- auxiliar signals
|
||||
signal mask_w : std_logic_vector(31 downto 0);
|
||||
signal cleared_data_w : std_logic_vector(31 downto 0);
|
||||
signal setted_data_w : std_logic_vector(31 downto 0);
|
||||
signal maskop_res_w : std_logic_vector(31 downto 0);
|
||||
|
||||
begin
|
||||
|
||||
rdata_w <= cycle_r when addr_i = CYCLE_ADDR else
|
||||
time_r when addr_i = TIME_ADDR else
|
||||
instret_r when addr_i = INSTRET_ADDR else
|
||||
cycleh_r when addr_i = CYCLEH_ADDR else
|
||||
timeh_r when addr_i = TIMEH_ADDR else
|
||||
instreth_r when addr_i = INSTRETH_ADDR else
|
||||
-- USER TRAP
|
||||
uscratch_r when addr_i = USCRATCH_ADDR else
|
||||
uepc_r when addr_i = UEPC_ADDR else
|
||||
ucause_r when addr_i = UCAUSE_ADDR else
|
||||
utval_r when addr_i = UTVAL_ADDR else
|
||||
uip_r when addr_i = UIP_ADDR else
|
||||
-- MACHINE INFORMATION
|
||||
mvendorid_r when addr_i = MVENDORID_ADDR else
|
||||
marchid_r when addr_i = MARCHID_ADDR else
|
||||
mimpid_r when addr_i = MIMPID_ADDR else
|
||||
mhartid_r when addr_i = MHARTID_ADDR else
|
||||
-- MACHINE HARDENING CONFIGURATION
|
||||
harden_conf_r when addr_i = HARDEN_CONF_ADDR else
|
||||
-- MACHINE RSTCAUSE
|
||||
rstcause_r when addr_i = RSTCAUSE_ADDR else
|
||||
-- CUSTOM ERROR
|
||||
reg1_sbu_r when addr_i = REG1_SBU_ADDR else
|
||||
reg1_dbu_r when addr_i = REG1_DBU_ADDR else
|
||||
reg2_sbu_r when addr_i = REG2_SBU_ADDR else
|
||||
reg2_dbu_r when addr_i = REG2_DBU_ADDR else
|
||||
pc_sbu_r when addr_i = PC_SBU_ADDR else
|
||||
pc_dbu_r when addr_i = PC_DBU_ADDR else
|
||||
dmem_sbu_r when addr_i = DMEM_SBU_ADDR else
|
||||
dmem_dbu_r when addr_i = DMEM_DBU_ADDR else
|
||||
control_err_r when addr_i = CONTROL_ERR_ADDR else
|
||||
alu_err_r when addr_i = ALU_ERR_ADDR else
|
||||
x"deadbeef";
|
||||
data_o <= rdata_w;
|
||||
|
||||
-- define data to be written
|
||||
mask_w <= ((31 downto 5 => '0') & imm_data_i) when source_imm_i = '1' else rs1_data_i;
|
||||
|
||||
cleared_data_w <= rdata_w and (not mask_w);
|
||||
setted_data_w <= rdata_w or mask_w;
|
||||
|
||||
maskop_res_w <= cleared_data_w when csr_clearop_i = '1' else setted_data_w;
|
||||
|
||||
-- select data that will be written
|
||||
wdata_w <= maskop_res_w when csr_maskop_i = '1' else rs1_data_i;
|
||||
|
||||
|
||||
--------------------------------------------------------------------------------------
|
||||
--------------------------------------- CSRs -----------------------------------------
|
||||
--------------------------------------------------------------------------------------
|
||||
|
||||
p_CYCLE_COUNT : process(clk_i, rstn_i)
|
||||
begin
|
||||
if rstn_i = '0' then
|
||||
cycle_r <= (others => '0');
|
||||
cycleh_r <= (others => '0');
|
||||
elsif rising_edge(clk_i) then
|
||||
-- increment cycle
|
||||
cycle_r <= std_logic_vector(unsigned(cycle_r) + 1);
|
||||
-- in case of cycle_r overflow, increase cycleh_r
|
||||
if cycle_r = x"FFFFFFFF" then
|
||||
cycleh_r <= std_logic_vector(unsigned(cycleh_r) + 1);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_TIME_COUNT : process(clk_i, rstn_i)
|
||||
begin
|
||||
if rstn_i = '0' then
|
||||
time_r <= (others => '0');
|
||||
timeh_r <= (others => '0');
|
||||
elsif rising_edge(clk_i) then
|
||||
-- increment time
|
||||
time_r <= std_logic_vector(unsigned(time_r) + 1);
|
||||
-- in case of time_r overflow, increase timeh_r
|
||||
if time_r = x"FFFFFFFF" then
|
||||
timeh_r <= std_logic_vector(unsigned(timeh_r) + 1);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_TRAP_REGISTERS : process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if trap_i = '1' then
|
||||
uscratch_r <= uscratch_i;
|
||||
uepc_r <= uepc_i;
|
||||
ucause_r <= ucause_i;
|
||||
utval_r <= utval_i;
|
||||
uip_r <= uip_i;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- information registers
|
||||
mvendorid_r <= x"CAFECAFE";
|
||||
marchid_r <= x"000000CA";
|
||||
mimpid_r(31 downto 6) <= (others => '0');
|
||||
mimpid_r( 3 downto 2) <= (others => '0');
|
||||
mimpid_r(0) <= '1' when HAMMING_PC else '0';
|
||||
mimpid_r(1) <= '1' when HAMMING_REGFILE else '0';
|
||||
mimpid_r(4) <= '1' when TMR_CONTROL else '0';
|
||||
mimpid_r(5) <= '1' when TMR_ALU else '0';
|
||||
mhartid_r <= x"00000000";
|
||||
|
||||
p_RSTCAUSE : process(poweron_rstn_i, wdt_rstn_i)
|
||||
begin
|
||||
if poweron_rstn_i = '0' then
|
||||
rstcause_r <= x"00000001";
|
||||
elsif wdt_rstn_i = '0' then
|
||||
rstcause_r <= x"00000002";
|
||||
end if;
|
||||
end process;
|
||||
|
||||
p_HARDENING : process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if wren_i = '1' and addr_i = HARDEN_CONF_ADDR then
|
||||
harden_conf_r <= wdata_w;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
-- Hamming
|
||||
hard_pc_o <= harden_conf_r(0);
|
||||
hard_regfile_o <= harden_conf_r(1);
|
||||
hard_dmem_o <= harden_conf_r(2);
|
||||
-- TMR
|
||||
hard_control_o <= harden_conf_r(4);
|
||||
hard_alu_o <= harden_conf_r(5);
|
||||
|
||||
p_ERROR_COUNT : process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
|
||||
-- Register file upsets
|
||||
if wren_i = '1' and addr_i = REG1_SBU_ADDR then
|
||||
reg1_sbu_r <= wdata_w;
|
||||
elsif reg1_cen_i = '1' and reg1_sbu_i = '1' then
|
||||
reg1_sbu_r <= std_logic_vector(unsigned(reg1_sbu_r)+1);
|
||||
end if;
|
||||
|
||||
if wren_i = '1' and addr_i = REG1_DBU_ADDR then
|
||||
reg1_dbu_r <= wdata_w;
|
||||
elsif reg1_cen_i = '1' and reg1_dbu_i = '1' then
|
||||
reg1_dbu_r <= std_logic_vector(unsigned(reg1_dbu_r)+1);
|
||||
end if;
|
||||
|
||||
-- Register file upsets
|
||||
if wren_i = '1' and addr_i = REG2_SBU_ADDR then
|
||||
reg2_sbu_r <= wdata_w;
|
||||
elsif reg2_cen_i = '1' and reg2_sbu_i = '1' then
|
||||
reg2_sbu_r <= std_logic_vector(unsigned(reg2_sbu_r)+1);
|
||||
end if;
|
||||
|
||||
if wren_i = '1' and addr_i = REG2_DBU_ADDR then
|
||||
reg2_dbu_r <= wdata_w;
|
||||
elsif reg2_cen_i = '1' and reg2_dbu_i = '1' then
|
||||
reg2_dbu_r <= std_logic_vector(unsigned(reg2_dbu_r)+1);
|
||||
end if;
|
||||
|
||||
-- PC upsets
|
||||
if wren_i = '1' and addr_i = PC_SBU_ADDR then
|
||||
pc_sbu_r <= wdata_w;
|
||||
elsif pc_cen_i = '1' and pc_sbu_i = '1' then
|
||||
pc_sbu_r <= std_logic_vector(unsigned(pc_sbu_r)+1);
|
||||
end if;
|
||||
|
||||
if wren_i = '1' and addr_i = PC_DBU_ADDR then
|
||||
pc_dbu_r <= wdata_w;
|
||||
elsif pc_cen_i = '1' and pc_dbu_i = '1' then
|
||||
pc_dbu_r <= std_logic_vector(unsigned(pc_dbu_r)+1);
|
||||
end if;
|
||||
|
||||
-- Data memory upsets
|
||||
if wren_i = '1' and addr_i = DMEM_SBU_ADDR then
|
||||
dmem_sbu_r <= wdata_w;
|
||||
elsif dmem_cen_i = '1' and dmem_sbu_i = '1' then
|
||||
dmem_sbu_r <= std_logic_vector(unsigned(dmem_sbu_r)+1);
|
||||
end if;
|
||||
|
||||
if wren_i = '1' and addr_i = DMEM_DBU_ADDR then
|
||||
dmem_dbu_r <= wdata_w;
|
||||
elsif dmem_cen_i = '1' and dmem_dbu_i = '1' then
|
||||
dmem_dbu_r <= std_logic_vector(unsigned(dmem_dbu_r)+1);
|
||||
end if;
|
||||
|
||||
-- CONTROL errors
|
||||
if wren_i = '1' and addr_i = CONTROL_ERR_ADDR then
|
||||
control_err_r <= wdata_w;
|
||||
elsif control_cen_i = '1' and control_err_i = '1' then
|
||||
control_err_r <= std_logic_vector(unsigned(control_err_r)+1);
|
||||
end if;
|
||||
|
||||
-- ALU errors
|
||||
if wren_i = '1' and addr_i = ALU_ERR_ADDR then
|
||||
alu_err_r <= wdata_w;
|
||||
elsif alu_cen_i = '1' and alu_err_i = '1' then
|
||||
alu_err_r <= std_logic_vector(unsigned(alu_err_r)+1);
|
||||
end if;
|
||||
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end architecture;
|
80
hdl/ft_components/alu_tmr.vhd
Normal file
80
hdl/ft_components/alu_tmr.vhd
Normal file
|
@ -0,0 +1,80 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.all;
|
||||
|
||||
entity alu_tmr is
|
||||
port (
|
||||
-- input ports
|
||||
data1_i : in std_logic_vector(31 downto 0);
|
||||
data2_i : in std_logic_vector(31 downto 0);
|
||||
operation_i : in std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
correct_error_i : in std_logic;
|
||||
-- output ports
|
||||
error_o : out std_logic;
|
||||
zero_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of alu_tmr is
|
||||
type tmr_std_logic_t is array(2 downto 0) of std_logic;
|
||||
signal zero_w : tmr_std_logic_t;
|
||||
signal corr_zero_w : std_logic;
|
||||
signal error_zero_w : std_logic;
|
||||
|
||||
type tmr_data_t is array(2 downto 0) of std_logic_vector(31 downto 0);
|
||||
signal data_w : tmr_data_t;
|
||||
signal corr_data_w : std_logic_vector(31 downto 0);
|
||||
signal error_data_w : std_logic;
|
||||
|
||||
begin
|
||||
gen_TMR : for i in 2 downto 0 generate
|
||||
-- Xilinx attributes to prevent optimization of TMR
|
||||
attribute DONT_TOUCH : string;
|
||||
attribute DONT_TOUCH of alu_i : label is "TRUE";
|
||||
-- Synplify attributes to prevent optimization of TMR
|
||||
attribute syn_radhardlevel : string;
|
||||
attribute syn_keep : boolean;
|
||||
attribute syn_safe_case : boolean;
|
||||
attribute syn_noprune : boolean;
|
||||
attribute syn_radhardlevel of alu_i : label is "tmr";
|
||||
attribute syn_keep of alu_i : label is TRUE;
|
||||
attribute syn_safe_case of alu_i : label is TRUE;
|
||||
attribute syn_noprune of alu_i : label is TRUE;
|
||||
begin
|
||||
alu_i : alu
|
||||
port map (
|
||||
data1_i => data1_i,
|
||||
data2_i => data2_i,
|
||||
operation_i => operation_i,
|
||||
zero_o => zero_w(i),
|
||||
data_o => data_w(i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
corr_zero_w <= (zero_w(2) and zero_w(1)) or
|
||||
(zero_w(2) and zero_w(0)) or
|
||||
(zero_w(1) and zero_w(0));
|
||||
|
||||
corr_data_w <= (data_w(2) and data_w(1)) or
|
||||
(data_w(2) and data_w(0)) or
|
||||
(data_w(1) and data_w(0));
|
||||
|
||||
error_zero_w <= (zero_w(2) xor zero_w(1)) or
|
||||
(zero_w(2) xor zero_w(0)) or
|
||||
(zero_w(1) xor zero_w(0));
|
||||
|
||||
error_data_w <= or_reduce((data_w(2) xor data_w(1)) or
|
||||
(data_w(2) xor data_w(0)) or
|
||||
(data_w(1) xor data_w(0)));
|
||||
|
||||
error_o <= error_zero_w or error_data_w;
|
||||
|
||||
zero_o <= corr_zero_w when correct_error_i = '1' else zero_w(0);
|
||||
data_o <= corr_data_w when correct_error_i = '1' else data_w(0);
|
||||
|
||||
end architecture;
|
299
hdl/ft_components/control_tmr.vhd
Normal file
299
hdl/ft_components/control_tmr.vhd
Normal file
|
@ -0,0 +1,299 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.all;
|
||||
|
||||
entity control_tmr is
|
||||
port (
|
||||
-- input ports
|
||||
-- processor status
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
|
||||
-- instruction decode
|
||||
opcode_i : in std_logic_vector(6 downto 0);
|
||||
funct3_i : in std_logic_vector(2 downto 0);
|
||||
funct7_i : in std_logic_vector(6 downto 0);
|
||||
funct12_i : in std_logic_vector(11 downto 0);
|
||||
|
||||
-- hardening
|
||||
correct_error_i : in std_logic;
|
||||
|
||||
-- sync
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
|
||||
-- output ports
|
||||
-- processor status
|
||||
imem_req_o : out std_logic;
|
||||
dmem_req_o : out std_logic;
|
||||
|
||||
update_pc_o : out std_logic;
|
||||
trap_o : out std_logic;
|
||||
|
||||
-- hardening
|
||||
error_o : out std_logic;
|
||||
|
||||
-- ALU operations
|
||||
aluop_o : out std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
alusrc_imm_o : out std_logic;
|
||||
-- immediate selector
|
||||
imm_shamt_o : out std_logic;
|
||||
imm_up_o : out std_logic;
|
||||
-- register bank
|
||||
regwr_o : out std_logic;
|
||||
-- control transfer
|
||||
inv_branch_o : out std_logic;
|
||||
branch_o : out std_logic;
|
||||
jump_o : out std_logic;
|
||||
jalr_o : out std_logic;
|
||||
ecall_o : out std_logic;
|
||||
-- mem access
|
||||
memrd_o : out std_logic;
|
||||
memwr_o : out std_logic;
|
||||
byte_en_o : out std_logic_vector(1 downto 0);
|
||||
mem_usgn_o : out std_logic; -- unsigned data
|
||||
-- U type
|
||||
load_upimm_o : out std_logic;
|
||||
auipc_o : out std_logic;
|
||||
-- csr control
|
||||
csr_enable_o : out std_logic;
|
||||
csr_source_imm_o : out std_logic;
|
||||
csr_maskop_o : out std_logic;
|
||||
csr_clearop_o : out std_logic
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of control_tmr is
|
||||
type tmr_std_logic_t is array(2 downto 0) of std_logic;
|
||||
signal imem_req_w : tmr_std_logic_t;
|
||||
signal dmem_req_w : tmr_std_logic_t;
|
||||
signal update_pc_w : tmr_std_logic_t;
|
||||
signal trap_w : tmr_std_logic_t;
|
||||
signal alusrc_imm_w : tmr_std_logic_t;
|
||||
signal imm_shamt_w : tmr_std_logic_t;
|
||||
signal imm_up_w : tmr_std_logic_t;
|
||||
signal regwr_w : tmr_std_logic_t;
|
||||
signal inv_branch_w : tmr_std_logic_t;
|
||||
signal branch_w : tmr_std_logic_t;
|
||||
signal jump_w : tmr_std_logic_t;
|
||||
signal jalr_w : tmr_std_logic_t;
|
||||
signal ecall_w : tmr_std_logic_t;
|
||||
signal memrd_w : tmr_std_logic_t;
|
||||
signal memwr_w : tmr_std_logic_t;
|
||||
signal mem_usgn_w : tmr_std_logic_t;
|
||||
signal load_upimm_w : tmr_std_logic_t;
|
||||
signal auipc_w : tmr_std_logic_t;
|
||||
signal csr_enable_w : tmr_std_logic_t;
|
||||
signal csr_source_imm_w : tmr_std_logic_t;
|
||||
signal csr_maskop_w : tmr_std_logic_t;
|
||||
signal csr_clearop_w : tmr_std_logic_t;
|
||||
|
||||
signal corr_imem_req_w : std_logic;
|
||||
signal corr_dmem_req_w : std_logic;
|
||||
signal corr_update_pc_w : std_logic;
|
||||
signal corr_trap_w : std_logic;
|
||||
signal corr_alusrc_imm_w : std_logic;
|
||||
signal corr_imm_shamt_w : std_logic;
|
||||
signal corr_imm_up_w : std_logic;
|
||||
signal corr_regwr_w : std_logic;
|
||||
signal corr_inv_branch_w : std_logic;
|
||||
signal corr_branch_w : std_logic;
|
||||
signal corr_jump_w : std_logic;
|
||||
signal corr_jalr_w : std_logic;
|
||||
signal corr_ecall_w : std_logic;
|
||||
signal corr_memrd_w : std_logic;
|
||||
signal corr_memwr_w : std_logic;
|
||||
signal corr_mem_usgn_w : std_logic;
|
||||
signal corr_load_upimm_w : std_logic;
|
||||
signal corr_auipc_w : std_logic;
|
||||
signal corr_csr_enable_w : std_logic;
|
||||
signal corr_csr_source_imm_w : std_logic;
|
||||
signal corr_csr_maskop_w : std_logic;
|
||||
signal corr_csr_clearop_w : std_logic;
|
||||
|
||||
signal error_imem_req_w : std_logic;
|
||||
signal error_dmem_req_w : std_logic;
|
||||
signal error_update_pc_w : std_logic;
|
||||
signal error_trap_w : std_logic;
|
||||
signal error_alusrc_imm_w : std_logic;
|
||||
signal error_imm_shamt_w : std_logic;
|
||||
signal error_imm_up_w : std_logic;
|
||||
signal error_regwr_w : std_logic;
|
||||
signal error_inv_branch_w : std_logic;
|
||||
signal error_branch_w : std_logic;
|
||||
signal error_jump_w : std_logic;
|
||||
signal error_jalr_w : std_logic;
|
||||
signal error_ecall_w : std_logic;
|
||||
signal error_memrd_w : std_logic;
|
||||
signal error_memwr_w : std_logic;
|
||||
signal error_mem_usgn_w : std_logic;
|
||||
signal error_load_upimm_w : std_logic;
|
||||
signal error_auipc_w : std_logic;
|
||||
signal error_csr_enable_w : std_logic;
|
||||
signal error_csr_source_imm_w : std_logic;
|
||||
signal error_csr_maskop_w : std_logic;
|
||||
signal error_csr_clearop_w : std_logic;
|
||||
|
||||
type tmr_alu_operations_t is array(2 downto 0) of std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
signal aluop_w : tmr_alu_operations_t;
|
||||
signal corr_aluop_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
signal error_aluop_w : std_logic;
|
||||
|
||||
type tmr_std_logic_2_t is array(2 downto 0) of std_logic_vector(1 downto 0);
|
||||
signal byte_en_w : tmr_std_logic_2_t;
|
||||
signal corr_byte_en_w : std_logic_vector(1 downto 0);
|
||||
signal error_byte_en_w : std_logic;
|
||||
|
||||
begin
|
||||
gen_TMR : for i in 2 downto 0 generate
|
||||
-- Xilinx attributes to prevent optimization of TMR
|
||||
attribute DONT_TOUCH : string;
|
||||
attribute DONT_TOUCH of control_i : label is "TRUE";
|
||||
-- Synplify attributes to prevent optimization of TMR
|
||||
attribute syn_radhardlevel : string;
|
||||
attribute syn_keep : boolean;
|
||||
attribute syn_safe_case : boolean;
|
||||
attribute syn_noprune : boolean;
|
||||
attribute syn_radhardlevel of control_i : label is "tmr";
|
||||
attribute syn_keep of control_i : label is TRUE;
|
||||
attribute syn_safe_case of control_i : label is TRUE;
|
||||
attribute syn_noprune of control_i : label is TRUE;
|
||||
begin
|
||||
control_i : control
|
||||
port map (
|
||||
imem_gnt_i => imem_gnt_i,
|
||||
imem_err_i => imem_err_i,
|
||||
dmem_gnt_i => dmem_gnt_i,
|
||||
dmem_outofrange_i => dmem_outofrange_i,
|
||||
dmem_sbu_i => dmem_sbu_i,
|
||||
dmem_dbu_i => dmem_dbu_i,
|
||||
opcode_i => opcode_i,
|
||||
funct3_i => funct3_i,
|
||||
funct7_i => funct7_i,
|
||||
funct12_i => funct12_i,
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
start_i => start_i,
|
||||
imem_req_o => imem_req_w(i),
|
||||
dmem_req_o => dmem_req_w(i),
|
||||
update_pc_o => update_pc_w(i),
|
||||
trap_o => trap_w(i),
|
||||
aluop_o => aluop_w(i),
|
||||
alusrc_imm_o => alusrc_imm_w(i),
|
||||
imm_shamt_o => imm_shamt_w(i),
|
||||
imm_up_o => imm_up_w(i),
|
||||
regwr_o => regwr_w(i),
|
||||
inv_branch_o => inv_branch_w(i),
|
||||
branch_o => branch_w(i),
|
||||
jump_o => jump_w(i),
|
||||
jalr_o => jalr_w(i),
|
||||
ecall_o => ecall_w(i),
|
||||
memrd_o => memrd_w(i),
|
||||
memwr_o => memwr_w(i),
|
||||
byte_en_o => byte_en_w(i),
|
||||
mem_usgn_o => mem_usgn_w(i),
|
||||
load_upimm_o => load_upimm_w(i),
|
||||
auipc_o => auipc_w(i),
|
||||
csr_enable_o => csr_enable_w(i),
|
||||
csr_source_imm_o => csr_source_imm_w(i),
|
||||
csr_maskop_o => csr_maskop_w(i),
|
||||
csr_clearop_o => csr_clearop_w(i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
corr_imem_req_w <= ( imem_req_w(2) and imem_req_w(1)) or ( imem_req_w(2) and imem_req_w(0)) or ( imem_req_w(1) and imem_req_w(0));
|
||||
corr_dmem_req_w <= ( dmem_req_w(2) and dmem_req_w(1)) or ( dmem_req_w(2) and dmem_req_w(0)) or ( dmem_req_w(1) and dmem_req_w(0));
|
||||
corr_update_pc_w <= ( update_pc_w(2) and update_pc_w(1)) or ( update_pc_w(2) and update_pc_w(0)) or ( update_pc_w(1) and update_pc_w(0));
|
||||
corr_trap_w <= ( trap_w(2) and trap_w(1)) or ( trap_w(2) and trap_w(0)) or ( trap_w(1) and trap_w(0));
|
||||
corr_aluop_w <= ( aluop_w(2) and aluop_w(1)) or ( aluop_w(2) and aluop_w(0)) or ( aluop_w(1) and aluop_w(0));
|
||||
corr_alusrc_imm_w <= ( alusrc_imm_w(2) and alusrc_imm_w(1)) or ( alusrc_imm_w(2) and alusrc_imm_w(0)) or ( alusrc_imm_w(1) and alusrc_imm_w(0));
|
||||
corr_imm_shamt_w <= ( imm_shamt_w(2) and imm_shamt_w(1)) or ( imm_shamt_w(2) and imm_shamt_w(0)) or ( imm_shamt_w(1) and imm_shamt_w(0));
|
||||
corr_imm_up_w <= ( imm_up_w(2) and imm_up_w(1)) or ( imm_up_w(2) and imm_up_w(0)) or ( imm_up_w(1) and imm_up_w(0));
|
||||
corr_regwr_w <= ( regwr_w(2) and regwr_w(1)) or ( regwr_w(2) and regwr_w(0)) or ( regwr_w(1) and regwr_w(0));
|
||||
corr_inv_branch_w <= ( inv_branch_w(2) and inv_branch_w(1)) or ( inv_branch_w(2) and inv_branch_w(0)) or ( inv_branch_w(1) and inv_branch_w(0));
|
||||
corr_branch_w <= ( branch_w(2) and branch_w(1)) or ( branch_w(2) and branch_w(0)) or ( branch_w(1) and branch_w(0));
|
||||
corr_jump_w <= ( jump_w(2) and jump_w(1)) or ( jump_w(2) and jump_w(0)) or ( jump_w(1) and jump_w(0));
|
||||
corr_jalr_w <= ( jalr_w(2) and jalr_w(1)) or ( jalr_w(2) and jalr_w(0)) or ( jalr_w(1) and jalr_w(0));
|
||||
corr_ecall_w <= ( ecall_w(2) and ecall_w(1)) or ( ecall_w(2) and ecall_w(0)) or ( ecall_w(1) and ecall_w(0));
|
||||
corr_memrd_w <= ( memrd_w(2) and memrd_w(1)) or ( memrd_w(2) and memrd_w(0)) or ( memrd_w(1) and memrd_w(0));
|
||||
corr_memwr_w <= ( memwr_w(2) and memwr_w(1)) or ( memwr_w(2) and memwr_w(0)) or ( memwr_w(1) and memwr_w(0));
|
||||
corr_byte_en_w <= ( byte_en_w(2) and byte_en_w(1)) or ( byte_en_w(2) and byte_en_w(0)) or ( byte_en_w(1) and byte_en_w(0));
|
||||
corr_mem_usgn_w <= ( mem_usgn_w(2) and mem_usgn_w(1)) or ( mem_usgn_w(2) and mem_usgn_w(0)) or ( mem_usgn_w(1) and mem_usgn_w(0));
|
||||
corr_load_upimm_w <= ( load_upimm_w(2) and load_upimm_w(1)) or ( load_upimm_w(2) and load_upimm_w(0)) or ( load_upimm_w(1) and load_upimm_w(0));
|
||||
corr_auipc_w <= ( auipc_w(2) and auipc_w(1)) or ( auipc_w(2) and auipc_w(0)) or ( auipc_w(1) and auipc_w(0));
|
||||
corr_csr_enable_w <= ( csr_enable_w(2) and csr_enable_w(1)) or ( csr_enable_w(2) and csr_enable_w(0)) or ( csr_enable_w(1) and csr_enable_w(0));
|
||||
corr_csr_source_imm_w <= ( csr_source_imm_w(2) and csr_source_imm_w(1)) or ( csr_source_imm_w(2) and csr_source_imm_w(0)) or ( csr_source_imm_w(1) and csr_source_imm_w(0));
|
||||
corr_csr_maskop_w <= ( csr_maskop_w(2) and csr_maskop_w(1)) or ( csr_maskop_w(2) and csr_maskop_w(0)) or ( csr_maskop_w(1) and csr_maskop_w(0));
|
||||
corr_csr_clearop_w <= ( csr_clearop_w(2) and csr_clearop_w(1)) or ( csr_clearop_w(2) and csr_clearop_w(0)) or ( csr_clearop_w(1) and csr_clearop_w(0));
|
||||
|
||||
error_imem_req_w <= ( imem_req_w(2) xor imem_req_w(1)) or ( imem_req_w(2) xor imem_req_w(0)) or ( imem_req_w(1) xor imem_req_w(0));
|
||||
error_dmem_req_w <= ( dmem_req_w(2) xor dmem_req_w(1)) or ( dmem_req_w(2) xor dmem_req_w(0)) or ( dmem_req_w(1) xor dmem_req_w(0));
|
||||
error_update_pc_w <= ( update_pc_w(2) xor update_pc_w(1)) or ( update_pc_w(2) xor update_pc_w(0)) or ( update_pc_w(1) xor update_pc_w(0));
|
||||
error_trap_w <= ( trap_w(2) xor trap_w(1)) or ( trap_w(2) xor trap_w(0)) or ( trap_w(1) xor trap_w(0));
|
||||
error_aluop_w <= or_reduce(( aluop_w(2) xor aluop_w(1)) or ( aluop_w(2) xor aluop_w(0)) or ( aluop_w(1) xor aluop_w(0)));
|
||||
error_alusrc_imm_w <= ( alusrc_imm_w(2) xor alusrc_imm_w(1)) or ( alusrc_imm_w(2) xor alusrc_imm_w(0)) or ( alusrc_imm_w(1) xor alusrc_imm_w(0));
|
||||
error_imm_shamt_w <= ( imm_shamt_w(2) xor imm_shamt_w(1)) or ( imm_shamt_w(2) xor imm_shamt_w(0)) or ( imm_shamt_w(1) xor imm_shamt_w(0));
|
||||
error_imm_up_w <= ( imm_up_w(2) xor imm_up_w(1)) or ( imm_up_w(2) xor imm_up_w(0)) or ( imm_up_w(1) xor imm_up_w(0));
|
||||
error_regwr_w <= ( regwr_w(2) xor regwr_w(1)) or ( regwr_w(2) xor regwr_w(0)) or ( regwr_w(1) xor regwr_w(0));
|
||||
error_inv_branch_w <= ( inv_branch_w(2) xor inv_branch_w(1)) or ( inv_branch_w(2) xor inv_branch_w(0)) or ( inv_branch_w(1) xor inv_branch_w(0));
|
||||
error_branch_w <= ( branch_w(2) xor branch_w(1)) or ( branch_w(2) xor branch_w(0)) or ( branch_w(1) xor branch_w(0));
|
||||
error_jump_w <= ( jump_w(2) xor jump_w(1)) or ( jump_w(2) xor jump_w(0)) or ( jump_w(1) xor jump_w(0));
|
||||
error_jalr_w <= ( jalr_w(2) xor jalr_w(1)) or ( jalr_w(2) xor jalr_w(0)) or ( jalr_w(1) xor jalr_w(0));
|
||||
error_ecall_w <= ( ecall_w(2) xor ecall_w(1)) or ( ecall_w(2) xor ecall_w(0)) or ( ecall_w(1) xor ecall_w(0));
|
||||
error_memrd_w <= ( memrd_w(2) xor memrd_w(1)) or ( memrd_w(2) xor memrd_w(0)) or ( memrd_w(1) xor memrd_w(0));
|
||||
error_memwr_w <= ( memwr_w(2) xor memwr_w(1)) or ( memwr_w(2) xor memwr_w(0)) or ( memwr_w(1) xor memwr_w(0));
|
||||
error_byte_en_w <= or_reduce(( byte_en_w(2) xor byte_en_w(1)) or ( byte_en_w(2) xor byte_en_w(0)) or ( byte_en_w(1) xor byte_en_w(0)));
|
||||
error_mem_usgn_w <= ( mem_usgn_w(2) xor mem_usgn_w(1)) or ( mem_usgn_w(2) xor mem_usgn_w(0)) or ( mem_usgn_w(1) xor mem_usgn_w(0));
|
||||
error_load_upimm_w <= ( load_upimm_w(2) xor load_upimm_w(1)) or ( load_upimm_w(2) xor load_upimm_w(0)) or ( load_upimm_w(1) xor load_upimm_w(0));
|
||||
error_auipc_w <= ( auipc_w(2) xor auipc_w(1)) or ( auipc_w(2) xor auipc_w(0)) or ( auipc_w(1) xor auipc_w(0));
|
||||
error_csr_enable_w <= ( csr_enable_w(2) xor csr_enable_w(1)) or ( csr_enable_w(2) xor csr_enable_w(0)) or ( csr_enable_w(1) xor csr_enable_w(0));
|
||||
error_csr_source_imm_w <= ( csr_source_imm_w(2) xor csr_source_imm_w(1)) or ( csr_source_imm_w(2) xor csr_source_imm_w(0)) or ( csr_source_imm_w(1) xor csr_source_imm_w(0));
|
||||
error_csr_maskop_w <= ( csr_maskop_w(2) xor csr_maskop_w(1)) or ( csr_maskop_w(2) xor csr_maskop_w(0)) or ( csr_maskop_w(1) xor csr_maskop_w(0));
|
||||
error_csr_clearop_w <= ( csr_clearop_w(2) xor csr_clearop_w(1)) or ( csr_clearop_w(2) xor csr_clearop_w(0)) or ( csr_clearop_w(1) xor csr_clearop_w(0));
|
||||
|
||||
|
||||
error_o <= error_imem_req_w or error_dmem_req_w or error_update_pc_w or
|
||||
error_trap_w or error_aluop_w or error_alusrc_imm_w or
|
||||
error_imm_shamt_w or error_imm_up_w or error_regwr_w or
|
||||
error_inv_branch_w or error_branch_w or error_jump_w or
|
||||
error_jalr_w or error_ecall_w or error_memrd_w or
|
||||
error_memwr_w or error_byte_en_w or error_mem_usgn_w or
|
||||
error_load_upimm_w or error_auipc_w or error_csr_enable_w or
|
||||
error_csr_source_imm_w or error_csr_maskop_w or error_csr_clearop_w;
|
||||
|
||||
|
||||
imem_req_o <= corr_imem_req_w when correct_error_i = '1' else imem_req_w (0);
|
||||
dmem_req_o <= corr_dmem_req_w when correct_error_i = '1' else dmem_req_w (0);
|
||||
update_pc_o <= corr_update_pc_w when correct_error_i = '1' else update_pc_w (0);
|
||||
trap_o <= corr_trap_w when correct_error_i = '1' else trap_w (0);
|
||||
aluop_o <= corr_aluop_w when correct_error_i = '1' else aluop_w (0);
|
||||
alusrc_imm_o <= corr_alusrc_imm_w when correct_error_i = '1' else alusrc_imm_w (0);
|
||||
imm_shamt_o <= corr_imm_shamt_w when correct_error_i = '1' else imm_shamt_w (0);
|
||||
imm_up_o <= corr_imm_up_w when correct_error_i = '1' else imm_up_w (0);
|
||||
regwr_o <= corr_regwr_w when correct_error_i = '1' else regwr_w (0);
|
||||
inv_branch_o <= corr_inv_branch_w when correct_error_i = '1' else inv_branch_w (0);
|
||||
branch_o <= corr_branch_w when correct_error_i = '1' else branch_w (0);
|
||||
jump_o <= corr_jump_w when correct_error_i = '1' else jump_w (0);
|
||||
jalr_o <= corr_jalr_w when correct_error_i = '1' else jalr_w (0);
|
||||
ecall_o <= corr_ecall_w when correct_error_i = '1' else ecall_w (0);
|
||||
memrd_o <= corr_memrd_w when correct_error_i = '1' else memrd_w (0);
|
||||
memwr_o <= corr_memwr_w when correct_error_i = '1' else memwr_w (0);
|
||||
byte_en_o <= corr_byte_en_w when correct_error_i = '1' else byte_en_w (0);
|
||||
mem_usgn_o <= corr_mem_usgn_w when correct_error_i = '1' else mem_usgn_w (0);
|
||||
load_upimm_o <= corr_load_upimm_w when correct_error_i = '1' else load_upimm_w (0);
|
||||
auipc_o <= corr_auipc_w when correct_error_i = '1' else auipc_w (0);
|
||||
csr_enable_o <= corr_csr_enable_w when correct_error_i = '1' else csr_enable_w (0);
|
||||
csr_source_imm_o <= corr_csr_source_imm_w when correct_error_i = '1' else csr_source_imm_w(0);
|
||||
csr_maskop_o <= corr_csr_maskop_w when correct_error_i = '1' else csr_maskop_w (0);
|
||||
csr_clearop_o <= corr_csr_clearop_w when correct_error_i = '1' else csr_clearop_w (0);
|
||||
|
||||
end architecture;
|
80
hdl/ft_components/hamming_decoder.vhd
Normal file
80
hdl/ft_components/hamming_decoder.vhd
Normal file
|
@ -0,0 +1,80 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
library work;
|
||||
use work.hamming_pkg.all;
|
||||
|
||||
entity hamming_decoder is
|
||||
generic (
|
||||
DATA_SIZE : integer := 32; -- 64(7), 32(6), 16(5), 8(4), 4(3)
|
||||
DETECT_DOUBLE : boolean
|
||||
);
|
||||
port (
|
||||
encoded_i : in std_logic_vector(DATA_SIZE+get_ecc_size(DATA_SIZE, DETECT_DOUBLE)-1 downto 0);
|
||||
correct_error_i : in std_logic;
|
||||
single_err_o : out std_logic;
|
||||
double_err_o : out std_logic;
|
||||
data_o : out std_logic_vector(DATA_SIZE-1 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of hamming_decoder is
|
||||
constant HAMM_PARITY_SIZE : integer := get_ecc_size(DATA_SIZE, FALSE);
|
||||
constant TOTAL_PARITY_SIZE : integer := get_ecc_size(DATA_SIZE, DETECT_DOUBLE);
|
||||
signal parity_data_w : std_logic_vector(HAMM_PARITY_SIZE-1 downto 0);
|
||||
signal parity_diff_w : std_logic_vector(HAMM_PARITY_SIZE-1 downto 0);
|
||||
signal corr_mask_w : std_logic_vector(DATA_SIZE-1 downto 0);
|
||||
signal corr_data_w : std_logic_vector(DATA_SIZE-1 downto 0);
|
||||
|
||||
signal single_err_w : std_logic;
|
||||
signal double_err_w : std_logic;
|
||||
begin
|
||||
|
||||
gen_ENCODE : for i in HAMM_PARITY_SIZE-1 downto 0 generate
|
||||
constant BITS_QT : integer := get_parity_qt(DATA_SIZE, i);
|
||||
signal ecc_data_w : std_logic_vector(BITS_QT-1 downto 0);
|
||||
begin
|
||||
gen_DATA : for j in ecc_data_w'range generate
|
||||
ecc_data_w(j) <= encoded_i(PARITY_POS(i, j));
|
||||
end generate;
|
||||
parity_data_w(i) <= xor_reduce(ecc_data_w);
|
||||
end generate;
|
||||
|
||||
parity_diff_w <= parity_data_w xor encoded_i(DATA_SIZE+HAMM_PARITY_SIZE-1 downto DATA_SIZE);
|
||||
|
||||
gen_CORRECTION_MASK : for i in corr_mask_w'range generate
|
||||
corr_mask_w(i) <= nor_reduce(ERROR_BIT(i)(HAMM_PARITY_SIZE-1 downto 0) xor parity_diff_w);
|
||||
end generate;
|
||||
|
||||
corr_data_w <= (encoded_i(DATA_SIZE-1 downto 0) xor corr_mask_w) when correct_error_i = '1' else encoded_i(DATA_SIZE-1 downto 0);
|
||||
|
||||
gen_DOUBLE_DETECT : if DETECT_DOUBLE generate
|
||||
signal addit_parity_w : std_logic;
|
||||
signal hamm_err_w : std_logic;
|
||||
begin
|
||||
-- calculate additional parity
|
||||
addit_parity_w <= xor_reduce(encoded_i);
|
||||
-- get 1 if hamming has detected an error
|
||||
hamm_err_w <= or_reduce(parity_diff_w);
|
||||
-- check double error
|
||||
double_err_w <= (not addit_parity_w) and hamm_err_w;
|
||||
-- set single error only when dont have double error
|
||||
single_err_w <= hamm_err_w and not double_err_w;
|
||||
end generate;
|
||||
gen_NOT_DOUBLE_DETECT : if not DETECT_DOUBLE generate
|
||||
-- set single error when hamming detects one
|
||||
single_err_w <= or_reduce(parity_diff_w);
|
||||
-- never detects two errors
|
||||
double_err_w <= '0';
|
||||
end generate;
|
||||
|
||||
-- assign error wires to output
|
||||
single_err_o <= single_err_w;
|
||||
double_err_o <= double_err_w;
|
||||
|
||||
-- output corrected data only when has corrected single error. If not, output not-modified data
|
||||
data_o <= corr_data_w when single_err_w = '1' else encoded_i(DATA_SIZE-1 downto 0);
|
||||
|
||||
end architecture;
|
45
hdl/ft_components/hamming_encoder.vhd
Normal file
45
hdl/ft_components/hamming_encoder.vhd
Normal file
|
@ -0,0 +1,45 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
library work;
|
||||
use work.hamming_pkg.all;
|
||||
|
||||
entity hamming_encoder is
|
||||
generic (
|
||||
DATA_SIZE : integer := 32; -- 64(7), 32(6), 16(5), 8(4), 4(3)
|
||||
DETECT_DOUBLE : boolean
|
||||
);
|
||||
port (
|
||||
data_i : in std_logic_vector(DATA_SIZE-1 downto 0);
|
||||
encoded_o : out std_logic_vector(DATA_SIZE+get_ecc_size(DATA_SIZE, DETECT_DOUBLE)-1 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of hamming_encoder is
|
||||
constant HAMM_PARITY_SIZE : integer := get_ecc_size(DATA_SIZE, FALSE);
|
||||
constant TOTAL_PARITY_SIZE : integer := get_ecc_size(DATA_SIZE, DETECT_DOUBLE);
|
||||
signal parity_data_w : std_logic_vector(TOTAL_PARITY_SIZE-1 downto 0);
|
||||
signal encoded_w : std_logic_vector(DATA_SIZE+TOTAL_PARITY_SIZE-1 downto 0);
|
||||
begin
|
||||
|
||||
gen_ENCODE : for i in HAMM_PARITY_SIZE-1 downto 0 generate
|
||||
constant BITS_QT : integer := get_parity_qt(DATA_SIZE, i);
|
||||
signal ecc_data_w : std_logic_vector(BITS_QT-1 downto 0);
|
||||
begin
|
||||
gen_DATA : for j in ecc_data_w'range generate
|
||||
ecc_data_w(j) <= data_i(PARITY_POS(i, j));
|
||||
end generate;
|
||||
parity_data_w(i) <= xor_reduce(ecc_data_w);
|
||||
end generate;
|
||||
|
||||
gen_ADDITIONAL_PARITY : if DETECT_DOUBLE generate
|
||||
signal hamm_encoded_w : std_logic_vector(DATA_SIZE+HAMM_PARITY_SIZE-1 downto 0);
|
||||
begin
|
||||
hamm_encoded_w <= parity_data_w(HAMM_PARITY_SIZE-1 downto 0) & data_i;
|
||||
parity_data_w(TOTAL_PARITY_SIZE-1) <= xor_reduce(hamm_encoded_w);
|
||||
end generate;
|
||||
|
||||
encoded_w <= parity_data_w & data_i;
|
||||
encoded_o <= encoded_w;
|
||||
end architecture;
|
129
hdl/ft_components/hamming_pkg.vhd
Normal file
129
hdl/ft_components/hamming_pkg.vhd
Normal file
|
@ -0,0 +1,129 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
package hamming_pkg is
|
||||
|
||||
-- TYPES
|
||||
type parity_pos_t is array (natural range <>, natural range <>) of integer;
|
||||
type err_bit_t is array(natural range <>) of std_logic_vector(6 downto 0);
|
||||
|
||||
-- CONSTANTS
|
||||
constant PARITY_POS : parity_pos_t := (
|
||||
0 => ( 0, 1, 3, 4, 6, 8, 10, 11, 13, 15, 17, 19, 21, 23, 25, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 57, 59, 61, 63),
|
||||
1 => ( 0, 2, 3, 5, 6, 9, 10, 12, 13, 16, 17, 20, 21, 24, 25, 27, 28, 31, 32, 35, 36, 39, 40, 43, 44, 47, 48, 51, 52, 55, 56, 58, 59, 62, 63),
|
||||
2 => ( 1, 2, 3, 7, 8, 9, 10, 14, 15, 16, 17, 22, 23, 24, 25, 29, 30, 31, 32, 37, 38, 39, 40, 45, 46, 47, 48, 53, 54, 55, 56, 60, 61, 62, 63),
|
||||
3 => ( 4, 5, 6, 7, 8, 9, 10, 18, 19, 20, 21, 22, 23, 24, 25, 33, 34, 35, 36, 37, 38, 39, 40, 49, 50, 51, 52, 53, 54, 55, 56, 64, -1, -1, -1),
|
||||
4 => (11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, -1, -1, -1),
|
||||
5 => (26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, -1, -1, -1, -1),
|
||||
6 => (57, 58, 59, 60, 61, 62, 63, 64, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1)
|
||||
);
|
||||
|
||||
constant ERROR_BIT : err_bit_t := (
|
||||
0 => "0000011", 1 => "0000101", 2 => "0000110", 3 => "0000111", 4 => "0001001", 5 => "0001010",
|
||||
6 => "0001011", 7 => "0001100", 8 => "0001101", 9 => "0001110", 10 => "0001111", 11 => "0010001",
|
||||
12 => "0010010", 13 => "0010011", 14 => "0010100", 15 => "0010101", 16 => "0010110", 17 => "0010111",
|
||||
18 => "0011000", 19 => "0011001", 20 => "0011010", 21 => "0011011", 22 => "0011100", 23 => "0011101",
|
||||
24 => "0011110", 25 => "0011111", 26 => "0100001", 27 => "0100010", 28 => "0100011", 29 => "0100100",
|
||||
30 => "0100101", 31 => "0100110", 32 => "0100111", 33 => "0101000", 34 => "0101001", 35 => "0101010",
|
||||
36 => "0101011", 37 => "0101100", 38 => "0101101", 39 => "0101110", 40 => "0101111", 41 => "0110000",
|
||||
42 => "0110001", 43 => "0110010", 44 => "0110011", 45 => "0110100", 46 => "0110101", 47 => "0110110",
|
||||
48 => "0110111", 49 => "0111000", 50 => "0111001", 51 => "0111010", 52 => "0111011", 53 => "0111100",
|
||||
54 => "0111101", 55 => "0111110", 56 => "0111111", 57 => "1000001", 58 => "1000010", 59 => "1000011",
|
||||
60 => "1000100", 61 => "1000101", 62 => "1000110", 63 => "1000111", 64 => "1001000"
|
||||
);
|
||||
|
||||
-- FUNCTIONS -- runs only at synthesis
|
||||
function get_parity_qt (data_size : in integer; pos : in integer) return integer;
|
||||
function get_ecc_size (data_size : in integer; detect_double : in boolean) return integer;
|
||||
function get_parity_data_result (data : in std_logic_vector; detect_double : in boolean) return std_logic_vector;
|
||||
|
||||
-- COMPONENTS
|
||||
component hamming_encoder
|
||||
generic (
|
||||
DATA_SIZE : integer;
|
||||
DETECT_DOUBLE : boolean
|
||||
);
|
||||
port (
|
||||
data_i : in std_logic_vector(DATA_SIZE-1 downto 0);
|
||||
encoded_o : out std_logic_vector(DATA_SIZE+get_ecc_size(DATA_SIZE, DETECT_DOUBLE)-1 downto 0)
|
||||
);
|
||||
end component hamming_encoder;
|
||||
|
||||
component hamming_decoder
|
||||
generic (
|
||||
DATA_SIZE : integer := 32;
|
||||
DETECT_DOUBLE : boolean
|
||||
);
|
||||
port (
|
||||
encoded_i : in std_logic_vector(DATA_SIZE+get_ecc_size(DATA_SIZE, DETECT_DOUBLE)-1 downto 0);
|
||||
correct_error_i : in std_logic;
|
||||
single_err_o : out std_logic;
|
||||
double_err_o : out std_logic;
|
||||
data_o : out std_logic_vector(DATA_SIZE-1 downto 0)
|
||||
);
|
||||
end component hamming_decoder;
|
||||
|
||||
component hamming_register
|
||||
generic (
|
||||
HAMMING_ENABLE : boolean;
|
||||
RESET_VALUE : std_logic_vector
|
||||
);
|
||||
port (
|
||||
correct_en_i : in std_logic;
|
||||
write_en_i : in std_logic;
|
||||
data_i : in std_logic_vector(31 downto 0);
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
single_err_o : out std_logic;
|
||||
double_err_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component hamming_register;
|
||||
|
||||
end package;
|
||||
|
||||
package body hamming_pkg is
|
||||
|
||||
function get_parity_qt (data_size : in integer; pos : in integer) return integer is
|
||||
begin
|
||||
for j in 0 to PARITY_POS'length(2)-1 loop
|
||||
if PARITY_POS(pos, j) >= data_size or PARITY_POS(pos, j) = -1 then
|
||||
return j;
|
||||
end if;
|
||||
end loop;
|
||||
return PARITY_POS'length(2);
|
||||
end function;
|
||||
|
||||
function get_ecc_size (data_size : in integer; detect_double : in boolean) return integer is
|
||||
begin
|
||||
if detect_double then
|
||||
return 1 + get_ecc_size(data_size, FALSE);
|
||||
end if;
|
||||
for j in 0 to PARITY_POS'length(1)-1 loop
|
||||
if data_size < PARITY_POS(j, 0) then
|
||||
return j;
|
||||
end if;
|
||||
end loop;
|
||||
return PARITY_POS'length(1);
|
||||
end function;
|
||||
|
||||
function get_parity_data_result (data : in std_logic_vector; detect_double : in boolean) return std_logic_vector is
|
||||
constant HAMM_PARITY_SIZE : integer := get_ecc_size(data'length, FALSE);
|
||||
constant TOTAL_PARITY_SIZE : integer := get_ecc_size(data'length, detect_double);
|
||||
variable par_data : std_logic_vector(HAMM_PARITY_SIZE-1 downto 0) := (others => '0');
|
||||
begin
|
||||
for i in 0 to HAMM_PARITY_SIZE-1 loop
|
||||
for j in 0 to get_parity_qt(data'length, i)-1 loop
|
||||
if PARITY_POS(i, j) < data'length and PARITY_POS(i, j) /= -1 then
|
||||
par_data(i) := par_data(i) xor data(PARITY_POS(i, j));
|
||||
end if;
|
||||
end loop;
|
||||
end loop;
|
||||
if detect_double then
|
||||
return xor_reduce(par_data) & par_data;
|
||||
end if;
|
||||
return par_data;
|
||||
end function;
|
||||
|
||||
end hamming_pkg;
|
101
hdl/ft_components/hamming_register.vhd
Normal file
101
hdl/ft_components/hamming_register.vhd
Normal file
|
@ -0,0 +1,101 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
|
||||
library work;
|
||||
use work.hamming_pkg.hamming_encoder;
|
||||
use work.hamming_pkg.hamming_decoder;
|
||||
use work.hamming_pkg.get_parity_data_result;
|
||||
use work.hamming_pkg.get_ecc_size;
|
||||
|
||||
entity hamming_register is
|
||||
generic (
|
||||
HAMMING_ENABLE : boolean;
|
||||
RESET_VALUE : std_logic_vector(31 downto 0) := x"00000000"
|
||||
);
|
||||
port (
|
||||
correct_en_i : in std_logic;
|
||||
write_en_i : in std_logic;
|
||||
data_i : in std_logic_vector(31 downto 0);
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
single_err_o : out std_logic;
|
||||
double_err_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of hamming_register is
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
------------------------------------- HAMMING DISABLED ----------------------------------------
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
g_NORMAL_REG : if not HAMMING_ENABLE generate
|
||||
signal reg_r : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
p_REG : process(clk_i, rstn_i)
|
||||
begin
|
||||
if rstn_i = '0' then
|
||||
reg_r <= RESET_VALUE;
|
||||
elsif rising_edge(clk_i) then
|
||||
if write_en_i = '1' then
|
||||
reg_r <= data_i;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
single_err_o <= '0';
|
||||
double_err_o <= '0';
|
||||
data_o <= reg_r;
|
||||
end generate;
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-------------------------------------- HAMMING ENABLED ----------------------------------------
|
||||
-----------------------------------------------------------------------------------------------
|
||||
g_HAMMING_REG : if HAMMING_ENABLE generate
|
||||
constant DETECT_DOUBLE : boolean := TRUE;
|
||||
constant REG_DATA_WIDTH : integer := 32 + get_ecc_size(32, DETECT_DOUBLE);
|
||||
constant RESET_VALUE_HAMMING : std_logic_vector(REG_DATA_WIDTH+31 downto 0) := get_parity_data_result(RESET_VALUE, DETECT_DOUBLE) & RESET_VALUE;
|
||||
signal enc_w : std_logic_vector(REG_DATA_WIDTH-1 downto 0);
|
||||
signal reg_r : std_logic_vector(REG_DATA_WIDTH-1 downto 0);
|
||||
begin
|
||||
|
||||
-- encode next register data
|
||||
hamming_encoder_i : hamming_encoder
|
||||
generic map (
|
||||
DATA_SIZE => 32,
|
||||
DETECT_DOUBLE => DETECT_DOUBLE
|
||||
)
|
||||
port map (
|
||||
data_i => data_i,
|
||||
encoded_o => enc_w
|
||||
);
|
||||
|
||||
-- create register
|
||||
p_REG : process(clk_i, rstn_i)
|
||||
begin
|
||||
if rstn_i = '0' then
|
||||
reg_r <= RESET_VALUE_HAMMING;
|
||||
elsif rising_edge(clk_i) then
|
||||
if write_en_i = '1' then
|
||||
reg_r <= enc_w;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- decode the data
|
||||
hamming_decoder_i : hamming_decoder
|
||||
generic map (
|
||||
DATA_SIZE => 32,
|
||||
DETECT_DOUBLE => DETECT_DOUBLE
|
||||
)
|
||||
port map (
|
||||
encoded_i => reg_r,
|
||||
correct_error_i => correct_en_i,
|
||||
single_err_o => single_err_o,
|
||||
double_err_o => double_err_o,
|
||||
data_o => data_o
|
||||
);
|
||||
end generate;
|
||||
|
||||
end architecture;
|
396
hdl/harv.vhd
Normal file
396
hdl/harv.vhd
Normal file
|
@ -0,0 +1,396 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.all;
|
||||
|
||||
entity harv is
|
||||
generic (
|
||||
PROGRAM_START_ADDR : std_logic_vector(31 downto 0) := x"00000000";
|
||||
TRAP_HANDLER_ADDR : std_logic_vector(31 downto 0) := x"00000000";
|
||||
TMR_CONTROL : boolean := FALSE;
|
||||
TMR_ALU : boolean := FALSE;
|
||||
HAMMING_REGFILE : boolean := FALSE;
|
||||
HAMMING_PC : boolean := FALSE
|
||||
);
|
||||
port (
|
||||
-- syncronization
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
-- reset cause
|
||||
poweron_rstn_i : in std_logic;
|
||||
wdt_rstn_i : in std_logic;
|
||||
-- INSTRUCTION MEMORY
|
||||
imem_instr_i : in std_logic_vector(31 downto 0);
|
||||
imem_pc_o : out std_logic_vector(31 downto 0);
|
||||
imem_req_o : out std_logic;
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
-- DATA MEMORY
|
||||
hard_dmem_o : out std_logic;
|
||||
dmem_data_i : in std_logic_vector(31 downto 0);
|
||||
dmem_req_o : out std_logic;
|
||||
dmem_wren_o : out std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
dmem_byte_en_o : out std_logic_vector(1 downto 0);
|
||||
dmem_usgn_dat_o : out std_logic;
|
||||
dmem_data_o : out std_logic_vector(31 downto 0);
|
||||
dmem_addr_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of harv is
|
||||
signal clk_w : std_logic;
|
||||
---------Instruction Fetch ---------
|
||||
signal if_pc_w : std_logic_vector(31 downto 0);
|
||||
signal if_pc_4_w : std_logic_vector(31 downto 0);
|
||||
signal update_pc_w : std_logic;
|
||||
signal trap_w : std_logic;
|
||||
|
||||
--------- Instruction Decode --------
|
||||
signal opcode_w : std_logic_vector( 6 downto 0);
|
||||
signal funct3_w : std_logic_vector( 2 downto 0);
|
||||
signal funct7_w : std_logic_vector( 6 downto 0);
|
||||
signal funct12_w : std_logic_vector(11 downto 0);
|
||||
signal rd_w : std_logic_vector( 4 downto 0);
|
||||
signal rs1_w : std_logic_vector( 4 downto 0);
|
||||
signal rs2_w : std_logic_vector( 4 downto 0);
|
||||
signal imm_shamt_w : std_logic_vector( 4 downto 0);
|
||||
signal imm_up_w : std_logic_vector(19 downto 0);
|
||||
signal imm_upj_w : std_logic_vector(20 downto 0);
|
||||
signal imm_branch_w : std_logic_vector(12 downto 0);
|
||||
signal imm_store_w : std_logic_vector(11 downto 0);
|
||||
signal imm_i_w : std_logic_vector(11 downto 0);
|
||||
-- Immediate value
|
||||
signal imm_sel_w : std_logic_vector(3 downto 0);
|
||||
signal imm_w : std_logic_vector(31 downto 0);
|
||||
-------------- CONTROL -------------
|
||||
signal ctl_aluop_w : std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
signal ctl_alusrc_imm_w : std_logic;
|
||||
signal ctl_imm_shamt_w : std_logic;
|
||||
signal ctl_imm_up_w : std_logic;
|
||||
signal ctl_regwr_w : std_logic;
|
||||
signal ctl_inv_branch_w : std_logic;
|
||||
signal ctl_branch_w : std_logic;
|
||||
signal ctl_jump_w : std_logic;
|
||||
signal ctl_jalr_w : std_logic;
|
||||
signal ctl_ecall_w : std_logic;
|
||||
signal ctl_memrd_w : std_logic;
|
||||
signal ctl_memwr_w : std_logic;
|
||||
signal ctl_byte_en_w : std_logic_vector(1 downto 0);
|
||||
signal ctl_mem_usgn_w : std_logic;
|
||||
signal ctl_load_upimm_w : std_logic;
|
||||
signal ctl_auipc_w : std_logic;
|
||||
signal ctl_csr_enable_w : std_logic;
|
||||
signal ctl_csr_source_imm_w : std_logic;
|
||||
signal ctl_csr_maskop_w : std_logic;
|
||||
signal ctl_csr_clearop_w : std_logic;
|
||||
signal instr_w : std_logic_vector(31 downto 0);
|
||||
------------- REGFILE -------------
|
||||
signal data_wr_w : std_logic_vector(31 downto 0);
|
||||
signal reg_data1_w : std_logic_vector(31 downto 0);
|
||||
signal reg_data2_w : std_logic_vector(31 downto 0);
|
||||
-------------- ALU -----------------
|
||||
signal alu_data1_w : std_logic_vector(31 downto 0);
|
||||
signal alu_data2_w : std_logic_vector(31 downto 0);
|
||||
signal alu_zero_w : std_logic;
|
||||
signal alu_data_w : std_logic_vector(31 downto 0);
|
||||
--------------- CSR -----------------
|
||||
signal csr_rdata_w : std_logic_vector(31 downto 0);
|
||||
signal csr_ucause_w : std_logic_vector(31 downto 0);
|
||||
signal hard_pc_w : std_logic;
|
||||
signal hard_regfile_w : std_logic;
|
||||
signal hard_control_w : std_logic;
|
||||
signal hard_alu_w : std_logic;
|
||||
----------- ERROR wires -------------
|
||||
-- signal reg1_cen_w : std_logic;
|
||||
signal reg1_sbu_w : std_logic;
|
||||
signal reg1_dbu_w : std_logic;
|
||||
-- signal reg2_cen_w : std_logic;
|
||||
signal reg2_sbu_w : std_logic;
|
||||
signal reg2_dbu_w : std_logic;
|
||||
-- signal pc_cen_w : std_logic;
|
||||
signal pc_sbu_w : std_logic;
|
||||
signal pc_dbu_w : std_logic;
|
||||
|
||||
signal control_err_w : std_logic;
|
||||
signal alu_err_w : std_logic;
|
||||
begin
|
||||
|
||||
clk_w <= clk_i;
|
||||
|
||||
instr_fetch_i : instr_fetch
|
||||
generic map (
|
||||
PROGRAM_START_ADDR => PROGRAM_START_ADDR,
|
||||
TRAP_HANDLER_ADDR => TRAP_HANDLER_ADDR,
|
||||
HAMMING_PC => HAMMING_PC
|
||||
)
|
||||
port map (
|
||||
branch_imm_i => imm_branch_w,
|
||||
jump_imm_i => alu_data_w,
|
||||
inv_branch_i => ctl_inv_branch_w,
|
||||
branch_i => ctl_branch_w,
|
||||
zero_i => alu_zero_w,
|
||||
jump_i => ctl_jump_w,
|
||||
ecall_i => ctl_ecall_w,
|
||||
correct_error_i => hard_pc_w,
|
||||
instr_gnt_i => imem_gnt_i,
|
||||
instr_i => imem_instr_i,
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_w,
|
||||
update_pc_i => update_pc_w,
|
||||
trap_i => trap_w,
|
||||
instr_o => instr_w,
|
||||
sbu_o => pc_sbu_w,
|
||||
dbu_o => pc_dbu_w,
|
||||
pc_o => if_pc_w,
|
||||
pc_4_o => if_pc_4_w
|
||||
);
|
||||
imem_pc_o <= if_pc_w;
|
||||
|
||||
opcode_w <= instr_w( 6 downto 0);
|
||||
funct3_w <= instr_w(14 downto 12);
|
||||
funct7_w <= instr_w(31 downto 25);
|
||||
funct12_w <= instr_w(31 downto 20);
|
||||
rd_w <= instr_w(11 downto 7);
|
||||
rs1_w <= instr_w(19 downto 15);
|
||||
rs2_w <= instr_w(24 downto 20);
|
||||
imm_shamt_w <= instr_w(24 downto 20);
|
||||
imm_up_w <= instr_w(31 downto 12);
|
||||
imm_upj_w <= instr_w(31) & instr_w(19 downto 12) & instr_w(20) & instr_w(30 downto 21) & '0';
|
||||
imm_branch_w <= instr_w(31) & instr_w(7) & instr_w(30 downto 25) & instr_w(11 downto 8) & '0';
|
||||
imm_store_w <= instr_w(31 downto 25) & instr_w(11 downto 7);
|
||||
imm_i_w <= instr_w(31 downto 20);
|
||||
|
||||
gen_ft_control : if TMR_CONTROL generate
|
||||
control_i : control_tmr
|
||||
port map (
|
||||
start_i => start_i,
|
||||
imem_gnt_i => imem_gnt_i,
|
||||
imem_err_i => imem_err_i,
|
||||
dmem_gnt_i => dmem_gnt_i,
|
||||
dmem_outofrange_i => dmem_outofrange_i,
|
||||
dmem_sbu_i => dmem_sbu_i and dmem_gnt_i and not ctl_memwr_w,
|
||||
dmem_dbu_i => dmem_dbu_i and dmem_gnt_i and not ctl_memwr_w,
|
||||
opcode_i => opcode_w,
|
||||
funct3_i => funct3_w,
|
||||
funct7_i => funct7_w,
|
||||
funct12_i => funct12_w,
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
imem_req_o => imem_req_o,
|
||||
dmem_req_o => dmem_req_o,
|
||||
update_pc_o => update_pc_w,
|
||||
trap_o => trap_w,
|
||||
aluop_o => ctl_aluop_w,
|
||||
alusrc_imm_o => ctl_alusrc_imm_w,
|
||||
imm_shamt_o => ctl_imm_shamt_w,
|
||||
imm_up_o => ctl_imm_up_w,
|
||||
regwr_o => ctl_regwr_w,
|
||||
inv_branch_o => ctl_inv_branch_w,
|
||||
branch_o => ctl_branch_w,
|
||||
jump_o => ctl_jump_w,
|
||||
jalr_o => ctl_jalr_w,
|
||||
ecall_o => ctl_ecall_w,
|
||||
memrd_o => ctl_memrd_w,
|
||||
memwr_o => ctl_memwr_w,
|
||||
byte_en_o => ctl_byte_en_w,
|
||||
mem_usgn_o => ctl_mem_usgn_w,
|
||||
load_upimm_o => ctl_load_upimm_w,
|
||||
auipc_o => ctl_auipc_w,
|
||||
csr_enable_o => ctl_csr_enable_w,
|
||||
csr_source_imm_o => ctl_csr_source_imm_w,
|
||||
csr_maskop_o => ctl_csr_maskop_w,
|
||||
csr_clearop_o => ctl_csr_clearop_w,
|
||||
correct_error_i => hard_control_w,
|
||||
error_o => control_err_w
|
||||
);
|
||||
end generate;
|
||||
gen_normal_control : if not TMR_CONTROL generate
|
||||
control_i : control
|
||||
port map (
|
||||
-- processor status
|
||||
start_i => start_i,
|
||||
imem_gnt_i => imem_gnt_i,
|
||||
imem_err_i => imem_err_i,
|
||||
dmem_gnt_i => dmem_gnt_i,
|
||||
dmem_outofrange_i => dmem_outofrange_i,
|
||||
dmem_sbu_i => dmem_sbu_i,
|
||||
dmem_dbu_i => dmem_dbu_i,
|
||||
|
||||
-- instruction decode
|
||||
opcode_i => opcode_w,
|
||||
funct3_i => funct3_w,
|
||||
funct7_i => funct7_w,
|
||||
funct12_i => funct12_w,
|
||||
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
|
||||
-- processor status
|
||||
imem_req_o => imem_req_o,
|
||||
dmem_req_o => dmem_req_o,
|
||||
update_pc_o => update_pc_w,
|
||||
trap_o => trap_w,
|
||||
|
||||
-- instruction decode
|
||||
aluop_o => ctl_aluop_w,
|
||||
alusrc_imm_o => ctl_alusrc_imm_w,
|
||||
imm_shamt_o => ctl_imm_shamt_w,
|
||||
imm_up_o => ctl_imm_up_w,
|
||||
regwr_o => ctl_regwr_w,
|
||||
inv_branch_o => ctl_inv_branch_w,
|
||||
branch_o => ctl_branch_w,
|
||||
jump_o => ctl_jump_w,
|
||||
jalr_o => ctl_jalr_w,
|
||||
ecall_o => ctl_ecall_w,
|
||||
memrd_o => ctl_memrd_w,
|
||||
memwr_o => ctl_memwr_w,
|
||||
byte_en_o => ctl_byte_en_w,
|
||||
mem_usgn_o => ctl_mem_usgn_w,
|
||||
load_upimm_o => ctl_load_upimm_w,
|
||||
auipc_o => ctl_auipc_w,
|
||||
csr_enable_o => ctl_csr_enable_w,
|
||||
csr_source_imm_o => ctl_csr_source_imm_w,
|
||||
csr_maskop_o => ctl_csr_maskop_w,
|
||||
csr_clearop_o => ctl_csr_clearop_w
|
||||
);
|
||||
end generate;
|
||||
|
||||
data_wr_w <= dmem_data_i when ctl_memrd_w = '1' else
|
||||
imm_w when ctl_load_upimm_w = '1' else
|
||||
if_pc_4_w when ctl_jump_w = '1' else
|
||||
csr_rdata_w when ctl_csr_enable_w = '1' else
|
||||
alu_data_w;
|
||||
|
||||
regfile_i : regfile
|
||||
generic map (
|
||||
HAMMING_ENABLE => HAMMING_REGFILE
|
||||
)
|
||||
port map (
|
||||
data_i => data_wr_w,
|
||||
wren_i => ctl_regwr_w,
|
||||
rd_i => rd_w,
|
||||
rs1_i => rs1_w,
|
||||
rs2_i => rs2_w,
|
||||
correct_en_i => hard_regfile_w,
|
||||
clk_i => clk_w,
|
||||
sbu1_o => reg1_sbu_w,
|
||||
dbu1_o => reg1_dbu_w,
|
||||
data1_o => reg_data1_w,
|
||||
sbu2_o => reg2_sbu_w,
|
||||
dbu2_o => reg2_dbu_w,
|
||||
data2_o => reg_data2_w
|
||||
);
|
||||
|
||||
imm_sel_w <= ctl_imm_shamt_w & ctl_imm_up_w & ctl_memwr_w & (ctl_jump_w and not ctl_jalr_w);
|
||||
|
||||
with imm_sel_w select imm_w <=
|
||||
std_logic_vector(resize(unsigned(imm_shamt_w), 32)) when "1000", -- ctl_imm_shamt_w = '1' else
|
||||
std_logic_vector(shift_left(resize(signed(imm_up_w), 32), 12)) when "0100", -- ctl_imm_up_w = '1' else
|
||||
std_logic_vector(resize(signed(imm_store_w), 32)) when "0010", -- ctl_memwr_w = '1' else
|
||||
std_logic_vector(resize(signed(imm_upj_w), 32)) when "0001", -- (ctl_jump_w and not ctl_jalr_w) = '1' else
|
||||
std_logic_vector(resize(signed(imm_i_w), 32)) when others;
|
||||
|
||||
alu_data1_w <= if_pc_w when (ctl_auipc_w or (ctl_jump_w and not ctl_jalr_w)) = '1' else
|
||||
reg_data1_w;
|
||||
alu_data2_w <= imm_w when ctl_alusrc_imm_w = '1' else reg_data2_w;
|
||||
|
||||
gen_ft_alu : if TMR_ALU generate
|
||||
alu_i : alu_tmr
|
||||
port map (
|
||||
data1_i => alu_data1_w,
|
||||
data2_i => alu_data2_w,
|
||||
operation_i => ctl_aluop_w,
|
||||
zero_o => alu_zero_w,
|
||||
data_o => alu_data_w,
|
||||
correct_error_i => hard_alu_w,
|
||||
error_o => alu_err_w
|
||||
);
|
||||
end generate;
|
||||
gen_normal_alu : if not TMR_ALU generate
|
||||
alu_i : alu
|
||||
port map (
|
||||
data1_i => alu_data1_w,
|
||||
data2_i => alu_data2_w,
|
||||
operation_i => ctl_aluop_w,
|
||||
zero_o => alu_zero_w,
|
||||
data_o => alu_data_w
|
||||
);
|
||||
end generate;
|
||||
|
||||
---------- CSR registers ---------
|
||||
csr_ucause_w <= x"00000010" when dmem_sbu_i = '1' else -- SBU
|
||||
x"00000020" when dmem_dbu_i = '1' else -- DBU
|
||||
x"00000007" when ctl_memwr_w = '1' else -- store address fault
|
||||
x"00000005"; -- load address fault
|
||||
csr_i : csr
|
||||
generic map (
|
||||
TMR_CONTROL => TMR_CONTROL,
|
||||
TMR_ALU => TMR_ALU,
|
||||
HAMMING_REGFILE => HAMMING_REGFILE,
|
||||
HAMMING_PC => HAMMING_PC
|
||||
)
|
||||
port map (
|
||||
-- sync
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
-- access interface
|
||||
addr_i => imm_i_w,
|
||||
data_o => csr_rdata_w,
|
||||
rs1_data_i => reg_data1_w,
|
||||
imm_data_i => rs1_w,
|
||||
wren_i => ctl_csr_enable_w,
|
||||
source_imm_i => ctl_csr_source_imm_w,
|
||||
csr_maskop_i => ctl_csr_maskop_w,
|
||||
csr_clearop_i => ctl_csr_clearop_w,
|
||||
-- trap handling
|
||||
trap_i => trap_w,
|
||||
uscratch_i => alu_data_w,
|
||||
uepc_i => if_pc_w,
|
||||
ucause_i => csr_ucause_w,
|
||||
utval_i => reg_data2_w,
|
||||
uip_i => x"00000000",
|
||||
-- errors
|
||||
reg1_cen_i => update_pc_w,
|
||||
reg1_sbu_i => reg1_sbu_w,
|
||||
reg1_dbu_i => reg1_dbu_w,
|
||||
reg2_cen_i => update_pc_w,
|
||||
reg2_sbu_i => reg2_sbu_w,
|
||||
reg2_dbu_i => reg2_dbu_w,
|
||||
pc_cen_i => update_pc_w,
|
||||
pc_sbu_i => pc_sbu_w,
|
||||
pc_dbu_i => pc_dbu_w,
|
||||
dmem_cen_i => dmem_gnt_i and not ctl_memwr_w,
|
||||
dmem_sbu_i => dmem_sbu_i,
|
||||
dmem_dbu_i => dmem_dbu_i,
|
||||
control_cen_i => '1',
|
||||
control_err_i => control_err_w,
|
||||
alu_cen_i => dmem_gnt_i or update_pc_w or ctl_regwr_w,
|
||||
alu_err_i => alu_err_w,
|
||||
-- hardening
|
||||
hard_pc_o => hard_pc_w,
|
||||
hard_regfile_o => hard_regfile_w,
|
||||
hard_dmem_o => hard_dmem_o,
|
||||
hard_control_o => hard_control_w,
|
||||
hard_alu_o => hard_alu_w,
|
||||
-- resets
|
||||
poweron_rstn_i => poweron_rstn_i,
|
||||
wdt_rstn_i => wdt_rstn_i
|
||||
);
|
||||
|
||||
-------- DATA MEMORY --------
|
||||
-- output signals
|
||||
-- dmem_req_o is set by the control unit
|
||||
dmem_wren_o <= ctl_memwr_w;
|
||||
dmem_byte_en_o <= ctl_byte_en_w;
|
||||
dmem_usgn_dat_o <= ctl_mem_usgn_w;
|
||||
dmem_data_o <= reg_data2_w;
|
||||
dmem_addr_o <= alu_data_w;
|
||||
|
||||
end architecture;
|
265
hdl/harv_pkg.vhd
Normal file
265
hdl/harv_pkg.vhd
Normal file
|
@ -0,0 +1,265 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
package harv_pkg is
|
||||
|
||||
----- CONSTANTS -------
|
||||
constant ALUOP_SIZE : integer := 4;
|
||||
constant ALU_ADD_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0000";
|
||||
constant ALU_SUB_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "1000";
|
||||
constant ALU_SLL_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0001";
|
||||
constant ALU_SLT_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0010";
|
||||
constant ALU_SLTU_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0011";
|
||||
constant ALU_XOR_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0100";
|
||||
constant ALU_SRL_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0101";
|
||||
constant ALU_SRA_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "1101";
|
||||
constant ALU_OR_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0110";
|
||||
constant ALU_AND_OP : std_logic_vector(ALUOP_SIZE-1 downto 0) := "0111";
|
||||
|
||||
------- COMPONENTS -----
|
||||
component harv
|
||||
generic (
|
||||
PROGRAM_START_ADDR : std_logic_vector(31 downto 0);
|
||||
TRAP_HANDLER_ADDR : std_logic_vector(31 downto 0);
|
||||
TMR_CONTROL : boolean;
|
||||
TMR_ALU : boolean;
|
||||
HAMMING_REGFILE : boolean;
|
||||
HAMMING_PC : boolean
|
||||
);
|
||||
port (
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
poweron_rstn_i : in std_logic;
|
||||
wdt_rstn_i : in std_logic;
|
||||
imem_instr_i : in std_logic_vector(31 downto 0);
|
||||
imem_pc_o : out std_logic_vector(31 downto 0);
|
||||
imem_req_o : out std_logic;
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
hard_dmem_o : out std_logic;
|
||||
dmem_data_i : in std_logic_vector(31 downto 0);
|
||||
dmem_req_o : out std_logic;
|
||||
dmem_wren_o : out std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
dmem_byte_en_o : out std_logic_vector(1 downto 0);
|
||||
dmem_usgn_dat_o : out std_logic;
|
||||
dmem_data_o : out std_logic_vector(31 downto 0);
|
||||
dmem_addr_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component harv;
|
||||
|
||||
component control
|
||||
port (
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
opcode_i : in std_logic_vector(6 downto 0);
|
||||
funct3_i : in std_logic_vector(2 downto 0);
|
||||
funct7_i : in std_logic_vector(6 downto 0);
|
||||
funct12_i : in std_logic_vector(11 downto 0);
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
imem_req_o : out std_logic;
|
||||
dmem_req_o : out std_logic;
|
||||
update_pc_o : out std_logic;
|
||||
trap_o : out std_logic;
|
||||
aluop_o : out std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
alusrc_imm_o : out std_logic;
|
||||
imm_shamt_o : out std_logic;
|
||||
imm_up_o : out std_logic;
|
||||
regwr_o : out std_logic;
|
||||
inv_branch_o : out std_logic;
|
||||
branch_o : out std_logic;
|
||||
jump_o : out std_logic;
|
||||
jalr_o : out std_logic;
|
||||
ecall_o : out std_logic;
|
||||
memrd_o : out std_logic;
|
||||
memwr_o : out std_logic;
|
||||
byte_en_o : out std_logic_vector(1 downto 0);
|
||||
mem_usgn_o : out std_logic;
|
||||
load_upimm_o : out std_logic;
|
||||
auipc_o : out std_logic;
|
||||
csr_enable_o : out std_logic;
|
||||
csr_source_imm_o : out std_logic;
|
||||
csr_maskop_o : out std_logic;
|
||||
csr_clearop_o : out std_logic
|
||||
);
|
||||
end component control;
|
||||
|
||||
component instr_fetch
|
||||
generic (
|
||||
PROGRAM_START_ADDR : std_logic_vector;
|
||||
TRAP_HANDLER_ADDR : std_logic_vector;
|
||||
HAMMING_PC : boolean
|
||||
);
|
||||
port (
|
||||
branch_imm_i : in std_logic_vector(12 downto 0);
|
||||
jump_imm_i : in std_logic_vector(31 downto 0);
|
||||
inv_branch_i : in std_logic;
|
||||
branch_i : in std_logic;
|
||||
zero_i : in std_logic;
|
||||
jump_i : in std_logic;
|
||||
ecall_i : in std_logic;
|
||||
correct_error_i : in std_logic;
|
||||
instr_gnt_i : in std_logic;
|
||||
instr_i : in std_logic_vector(31 downto 0);
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
update_pc_i : in std_logic;
|
||||
trap_i : in std_logic;
|
||||
instr_o : out std_logic_vector(31 downto 0);
|
||||
sbu_o : out std_logic;
|
||||
dbu_o : out std_logic;
|
||||
pc_o : out std_logic_vector(31 downto 0);
|
||||
pc_4_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component instr_fetch;
|
||||
|
||||
component regfile
|
||||
generic (
|
||||
HAMMING_ENABLE : boolean
|
||||
);
|
||||
port (
|
||||
data_i : in std_logic_vector(31 downto 0);
|
||||
wren_i : in std_logic;
|
||||
rd_i : in std_logic_vector(4 downto 0);
|
||||
rs1_i : in std_logic_vector(4 downto 0);
|
||||
rs2_i : in std_logic_vector(4 downto 0);
|
||||
correct_en_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
sbu1_o : out std_logic;
|
||||
dbu1_o : out std_logic;
|
||||
data1_o : out std_logic_vector(31 downto 0);
|
||||
sbu2_o : out std_logic;
|
||||
dbu2_o : out std_logic;
|
||||
data2_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component regfile;
|
||||
|
||||
component alu
|
||||
port (
|
||||
data1_i : in std_logic_vector(31 downto 0);
|
||||
data2_i : in std_logic_vector(31 downto 0);
|
||||
operation_i : in std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
zero_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component alu;
|
||||
|
||||
component csr
|
||||
generic (
|
||||
TMR_CONTROL : boolean;
|
||||
TMR_ALU : boolean;
|
||||
HAMMING_REGFILE : boolean;
|
||||
HAMMING_PC : boolean
|
||||
);
|
||||
port (
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
addr_i : in std_logic_vector(11 downto 0);
|
||||
data_o : out std_logic_vector(31 downto 0);
|
||||
rs1_data_i : in std_logic_vector(31 downto 0);
|
||||
imm_data_i : in std_logic_vector(4 downto 0);
|
||||
wren_i : in std_logic;
|
||||
source_imm_i : in std_logic;
|
||||
csr_maskop_i : in std_logic;
|
||||
csr_clearop_i : in std_logic;
|
||||
trap_i : in std_logic;
|
||||
uscratch_i : in std_logic_vector(31 downto 0);
|
||||
uepc_i : in std_logic_vector(31 downto 0);
|
||||
ucause_i : in std_logic_vector(31 downto 0);
|
||||
utval_i : in std_logic_vector(31 downto 0);
|
||||
uip_i : in std_logic_vector(31 downto 0);
|
||||
reg1_cen_i : in std_logic;
|
||||
reg1_sbu_i : in std_logic;
|
||||
reg1_dbu_i : in std_logic;
|
||||
reg2_cen_i : in std_logic;
|
||||
reg2_sbu_i : in std_logic;
|
||||
reg2_dbu_i : in std_logic;
|
||||
pc_cen_i : in std_logic;
|
||||
pc_sbu_i : in std_logic;
|
||||
pc_dbu_i : in std_logic;
|
||||
dmem_cen_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
control_cen_i : in std_logic;
|
||||
control_err_i : in std_logic;
|
||||
alu_cen_i : in std_logic;
|
||||
alu_err_i : in std_logic;
|
||||
hard_pc_o : out std_logic;
|
||||
hard_regfile_o : out std_logic;
|
||||
hard_dmem_o : out std_logic;
|
||||
hard_control_o : out std_logic;
|
||||
hard_alu_o : out std_logic;
|
||||
poweron_rstn_i : in std_logic;
|
||||
wdt_rstn_i : in std_logic
|
||||
);
|
||||
end component csr;
|
||||
|
||||
------------- FAULT TOLERANT COMPONENTS --------------------
|
||||
component control_tmr
|
||||
port (
|
||||
imem_gnt_i : in std_logic;
|
||||
imem_err_i : in std_logic;
|
||||
dmem_gnt_i : in std_logic;
|
||||
dmem_outofrange_i : in std_logic;
|
||||
dmem_sbu_i : in std_logic;
|
||||
dmem_dbu_i : in std_logic;
|
||||
opcode_i : in std_logic_vector(6 downto 0);
|
||||
funct3_i : in std_logic_vector(2 downto 0);
|
||||
funct7_i : in std_logic_vector(6 downto 0);
|
||||
funct12_i : in std_logic_vector(11 downto 0);
|
||||
correct_error_i : in std_logic;
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
start_i : in std_logic;
|
||||
imem_req_o : out std_logic;
|
||||
dmem_req_o : out std_logic;
|
||||
update_pc_o : out std_logic;
|
||||
trap_o : out std_logic;
|
||||
error_o : out std_logic;
|
||||
aluop_o : out std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
alusrc_imm_o : out std_logic;
|
||||
imm_shamt_o : out std_logic;
|
||||
imm_up_o : out std_logic;
|
||||
regwr_o : out std_logic;
|
||||
inv_branch_o : out std_logic;
|
||||
branch_o : out std_logic;
|
||||
jump_o : out std_logic;
|
||||
jalr_o : out std_logic;
|
||||
ecall_o : out std_logic;
|
||||
memrd_o : out std_logic;
|
||||
memwr_o : out std_logic;
|
||||
byte_en_o : out std_logic_vector(1 downto 0);
|
||||
mem_usgn_o : out std_logic;
|
||||
load_upimm_o : out std_logic;
|
||||
auipc_o : out std_logic;
|
||||
csr_enable_o : out std_logic;
|
||||
csr_source_imm_o : out std_logic;
|
||||
csr_maskop_o : out std_logic;
|
||||
csr_clearop_o : out std_logic
|
||||
);
|
||||
end component control_tmr;
|
||||
|
||||
component alu_tmr
|
||||
port (
|
||||
data1_i : in std_logic_vector(31 downto 0);
|
||||
data2_i : in std_logic_vector(31 downto 0);
|
||||
operation_i : in std_logic_vector(ALUOP_SIZE-1 downto 0);
|
||||
correct_error_i : in std_logic;
|
||||
error_o : out std_logic;
|
||||
zero_o : out std_logic;
|
||||
data_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end component alu_tmr;
|
||||
|
||||
end package;
|
91
hdl/instr_fetch.vhd
Normal file
91
hdl/instr_fetch.vhd
Normal file
|
@ -0,0 +1,91 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
library work;
|
||||
use work.hamming_pkg.hamming_register;
|
||||
|
||||
entity instr_fetch is
|
||||
generic (
|
||||
PROGRAM_START_ADDR : std_logic_vector(31 downto 0);
|
||||
TRAP_HANDLER_ADDR : std_logic_vector(31 downto 0);
|
||||
HAMMING_PC : boolean
|
||||
);
|
||||
port (
|
||||
-- input ports
|
||||
branch_imm_i : in std_logic_vector(12 downto 0);
|
||||
jump_imm_i : in std_logic_vector(31 downto 0);
|
||||
inv_branch_i : in std_logic;
|
||||
branch_i : in std_logic;
|
||||
zero_i : in std_logic;
|
||||
jump_i : in std_logic;
|
||||
ecall_i : in std_logic;
|
||||
correct_error_i : in std_logic;
|
||||
-- instruction data
|
||||
instr_gnt_i : in std_logic;
|
||||
instr_i : in std_logic_vector(31 downto 0);
|
||||
-- sync
|
||||
rstn_i : in std_logic;
|
||||
clk_i : in std_logic;
|
||||
update_pc_i : in std_logic;
|
||||
trap_i : in std_logic;
|
||||
-- output ports
|
||||
instr_o : out std_logic_vector(31 downto 0);
|
||||
sbu_o : out std_logic;
|
||||
dbu_o : out std_logic;
|
||||
pc_o : out std_logic_vector(31 downto 0);
|
||||
pc_4_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of instr_fetch is
|
||||
signal pc_par_w : std_logic_vector(31 downto 0);
|
||||
signal pc_adder_w : std_logic_vector(31 downto 0);
|
||||
signal next_pc_w : std_logic_vector(31 downto 0);
|
||||
signal pc_w : std_logic_vector(31 downto 0);
|
||||
begin
|
||||
-- calculate (PC + 4) or (PC + branch_eq)
|
||||
pc_par_w <= std_logic_vector(resize(signed(branch_imm_i), 32)) when (branch_i and (zero_i xor inv_branch_i)) = '1' else x"00000004";
|
||||
pc_adder_w <= std_logic_vector(signed(pc_w) + signed(pc_par_w));
|
||||
pc_4_o <= pc_adder_w;
|
||||
|
||||
-- define the next PC address
|
||||
next_pc_w <= TRAP_HANDLER_ADDR when trap_i = '1' else
|
||||
jump_imm_i when jump_i = '1' else
|
||||
pc_adder_w;
|
||||
-- set PC output
|
||||
pc_o <= pc_w;
|
||||
|
||||
register_pc_i : hamming_register
|
||||
generic map (
|
||||
HAMMING_ENABLE => HAMMING_PC,
|
||||
RESET_VALUE => PROGRAM_START_ADDR
|
||||
)
|
||||
port map (
|
||||
correct_en_i => correct_error_i,
|
||||
write_en_i => update_pc_i,
|
||||
data_i => next_pc_w,
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
single_err_o => sbu_o,
|
||||
double_err_o => dbu_o,
|
||||
data_o => pc_w
|
||||
);
|
||||
|
||||
register_instr_i : hamming_register
|
||||
generic map (
|
||||
HAMMING_ENABLE => HAMMING_PC,
|
||||
RESET_VALUE => (31 downto 0 => '0')
|
||||
)
|
||||
port map (
|
||||
correct_en_i => correct_error_i,
|
||||
write_en_i => instr_gnt_i,
|
||||
data_i => instr_i,
|
||||
rstn_i => rstn_i,
|
||||
clk_i => clk_i,
|
||||
single_err_o => open,
|
||||
double_err_o => open,
|
||||
data_o => instr_o
|
||||
);
|
||||
|
||||
end architecture;
|
142
hdl/regfile.vhd
Normal file
142
hdl/regfile.vhd
Normal file
|
@ -0,0 +1,142 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
use ieee.std_logic_misc.all;
|
||||
|
||||
library work;
|
||||
use work.hamming_pkg.all;
|
||||
|
||||
entity regfile is
|
||||
generic (
|
||||
HAMMING_ENABLE : boolean
|
||||
);
|
||||
port (
|
||||
-- input ports
|
||||
data_i : in std_logic_vector(31 downto 0);
|
||||
wren_i : in std_logic;
|
||||
rd_i : in std_logic_vector(4 downto 0);
|
||||
rs1_i : in std_logic_vector(4 downto 0);
|
||||
rs2_i : in std_logic_vector(4 downto 0);
|
||||
correct_en_i : in std_logic;
|
||||
-- synchronization
|
||||
clk_i : in std_logic;
|
||||
-- output ports
|
||||
sbu1_o : out std_logic;
|
||||
dbu1_o : out std_logic;
|
||||
data1_o : out std_logic_vector(31 downto 0);
|
||||
sbu2_o : out std_logic;
|
||||
dbu2_o : out std_logic;
|
||||
data2_o : out std_logic_vector(31 downto 0)
|
||||
);
|
||||
end entity;
|
||||
|
||||
architecture arch of regfile is
|
||||
begin
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
------------------------------------- HAMMING DISABLED ----------------------------------------
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
g_NORMAL : if not HAMMING_ENABLE generate
|
||||
type regfile_t is array(natural range <>) of std_logic_vector(31 downto 0);
|
||||
signal regfile_r : regfile_t(31 downto 1);
|
||||
signal regfile_w : regfile_t(31 downto 0);
|
||||
|
||||
signal rs1_w : std_logic_vector(4 downto 0);
|
||||
signal rs2_w : std_logic_vector(4 downto 0);
|
||||
begin
|
||||
-- WRITE REGISTERS
|
||||
p_WR : process(clk_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if wren_i = '1' and rd_i /= "00000" and rd_i /= "UUUUU" then
|
||||
regfile_r(to_integer(unsigned(rd_i))) <= data_i;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
regfile_w(31 downto 1) <= regfile_r;
|
||||
regfile_w(0) <= (others => '0');
|
||||
|
||||
-- READ REGISTERS
|
||||
sbu1_o <= '0';
|
||||
dbu1_o <= '0';
|
||||
data1_o <= regfile_w(to_integer(unsigned(rs1_i)));
|
||||
|
||||
sbu2_o <= '0';
|
||||
dbu2_o <= '0';
|
||||
data2_o <= regfile_w(to_integer(unsigned(rs2_i)));
|
||||
end generate;
|
||||
|
||||
-----------------------------------------------------------------------------------------------
|
||||
-------------------------------------- HAMMING ENABLED ----------------------------------------
|
||||
-----------------------------------------------------------------------------------------------
|
||||
|
||||
g_HAMMING : if HAMMING_ENABLE generate
|
||||
constant DETECT_DOUBLE : boolean := TRUE;
|
||||
constant PARITY_BITS_QT : integer := get_ecc_size(32, DETECT_DOUBLE);
|
||||
type regfile_hamming_t is array(natural range <>) of std_logic_vector(31+PARITY_BITS_QT downto 0);
|
||||
|
||||
signal regfile_r : regfile_hamming_t(31 downto 1);
|
||||
signal regfile_w : regfile_hamming_t(31 downto 0);
|
||||
|
||||
signal data_wr_enc_w : std_logic_vector(PARITY_BITS_QT+31 downto 0);
|
||||
signal data_s1_enc_w : std_logic_vector(PARITY_BITS_QT+31 downto 0);
|
||||
signal data_s2_enc_w : std_logic_vector(PARITY_BITS_QT+31 downto 0);
|
||||
begin
|
||||
hamming_encoder_i : hamming_encoder
|
||||
generic map (
|
||||
DATA_SIZE => 32,
|
||||
DETECT_DOUBLE => DETECT_DOUBLE
|
||||
)
|
||||
port map (
|
||||
data_i => data_i,
|
||||
encoded_o => data_wr_enc_w
|
||||
);
|
||||
|
||||
-- WRITE REGISTER
|
||||
p_WR : process(clk_i, wren_i)
|
||||
begin
|
||||
if rising_edge(clk_i) then
|
||||
if wren_i = '1' and rd_i /= "00000" then
|
||||
regfile_r(to_integer(unsigned(rd_i))) <= data_wr_enc_w;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- READ REGISTERS
|
||||
regfile_w(31 downto 1) <= regfile_r;
|
||||
regfile_w(0) <= (others => '0');
|
||||
|
||||
data_s1_enc_w <= regfile_w(to_integer(unsigned(rs1_i)));
|
||||
data_s2_enc_w <= regfile_w(to_integer(unsigned(rs2_i)));
|
||||
|
||||
hamming_decoder_data1_i : hamming_decoder
|
||||
generic map (
|
||||
DATA_SIZE => 32,
|
||||
DETECT_DOUBLE => DETECT_DOUBLE
|
||||
)
|
||||
port map (
|
||||
encoded_i => data_s1_enc_w,
|
||||
correct_error_i => correct_en_i,
|
||||
single_err_o => sbu1_o,
|
||||
double_err_o => dbu1_o,
|
||||
data_o => data1_o
|
||||
);
|
||||
|
||||
hamming_decoder_data2_i : hamming_decoder
|
||||
generic map (
|
||||
DATA_SIZE => 32,
|
||||
DETECT_DOUBLE => DETECT_DOUBLE
|
||||
)
|
||||
port map (
|
||||
encoded_i => data_s2_enc_w,
|
||||
correct_error_i => correct_en_i,
|
||||
single_err_o => sbu2_o,
|
||||
double_err_o => dbu2_o,
|
||||
data_o => data2_o
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
end architecture;
|
BIN
images/rars-data-export.png
Normal file
BIN
images/rars-data-export.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 9.1 KiB |
BIN
images/rars-memory-configuration.png
Normal file
BIN
images/rars-memory-configuration.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
images/rars-text-export.png
Normal file
BIN
images/rars-text-export.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.7 KiB |
311
script/project.tcl
Normal file
311
script/project.tcl
Normal file
|
@ -0,0 +1,311 @@
|
|||
#*****************************************************************************************
|
||||
# Vivado (TM) v2020.2 (64-bit)
|
||||
#
|
||||
# project.tcl: Tcl script for re-creating project 'harv'
|
||||
#
|
||||
# Generated by Vivado on Tue Jun 15 18:52:54 CEST 2021
|
||||
# IP Build 3064653 on Wed Nov 18 14:17:31 MST 2020
|
||||
#
|
||||
# This file contains the Vivado Tcl commands for re-creating the project to the state*
|
||||
# when this script was generated. In order to re-create the project, please source this
|
||||
# file in the Vivado Tcl Shell.
|
||||
#
|
||||
# * Note that the runs in the created project will be configured the same way as the
|
||||
# original project, however they will not be launched automatically. To regenerate the
|
||||
# run results please launch the synthesis/implementation runs as needed.
|
||||
#
|
||||
#*****************************************************************************************
|
||||
# NOTE: In order to use this script for source control purposes, please make sure that the
|
||||
# following files are added to the source control system:-
|
||||
#
|
||||
# 1. This project restoration tcl script (project.tcl) that was generated.
|
||||
#
|
||||
# 2. The following source(s) files that were local or imported into the original project.
|
||||
# (Please see the '$orig_proj_dir' and '$origin_dir' variable setting below at the start of the script)
|
||||
#
|
||||
# "xilinx/sim_from_dump_behav.wcfg"
|
||||
#
|
||||
# 3. The following remote source files that were added to the original project:-
|
||||
#
|
||||
# "hdl/harv_pkg.vhd"
|
||||
# "hdl/alu.vhd"
|
||||
# "hdl/ft_components/alu_tmr.vhd"
|
||||
# "hdl/control.vhd"
|
||||
# "hdl/ft_components/control_tmr.vhd"
|
||||
# "hdl/csr.vhd"
|
||||
# "hdl/ft_components/hamming_pkg.vhd"
|
||||
# "hdl/ft_components/hamming_decoder.vhd"
|
||||
# "hdl/ft_components/hamming_encoder.vhd"
|
||||
# "hdl/ft_components/hamming_register.vhd"
|
||||
# "hdl/instr_fetch.vhd"
|
||||
# "hdl/regfile.vhd"
|
||||
# "hdl/harv.vhd"
|
||||
# "sim/sim_from_dump.vhd"
|
||||
#
|
||||
#*****************************************************************************************
|
||||
|
||||
# Check file required for this script exists
|
||||
proc checkRequiredFiles { origin_dir} {
|
||||
set status true
|
||||
set files [list \
|
||||
"xilinx/sim_from_dump_behav.wcfg" \
|
||||
]
|
||||
foreach ifile $files {
|
||||
if { ![file isfile $ifile] } {
|
||||
puts " Could not find local file $ifile "
|
||||
set status false
|
||||
}
|
||||
}
|
||||
|
||||
set files [list \
|
||||
"hdl/harv_pkg.vhd" \
|
||||
"hdl/alu.vhd" \
|
||||
"hdl/ft_components/alu_tmr.vhd" \
|
||||
"hdl/control.vhd" \
|
||||
"hdl/ft_components/control_tmr.vhd" \
|
||||
"hdl/csr.vhd" \
|
||||
"hdl/ft_components/hamming_pkg.vhd" \
|
||||
"hdl/ft_components/hamming_decoder.vhd" \
|
||||
"hdl/ft_components/hamming_encoder.vhd" \
|
||||
"hdl/ft_components/hamming_register.vhd" \
|
||||
"hdl/instr_fetch.vhd" \
|
||||
"hdl/regfile.vhd" \
|
||||
"hdl/harv.vhd" \
|
||||
"sim/sim_from_dump.vhd" \
|
||||
]
|
||||
foreach ifile $files {
|
||||
if { ![file isfile $ifile] } {
|
||||
puts " Could not find remote file $ifile "
|
||||
set status false
|
||||
}
|
||||
}
|
||||
|
||||
return $status
|
||||
}
|
||||
# Set the reference directory for source file relative paths (by default the value is script directory path)
|
||||
set origin_dir "."
|
||||
|
||||
# Use origin directory path location variable, if specified in the tcl shell
|
||||
if { [info exists ::origin_dir_loc] } {
|
||||
set origin_dir $::origin_dir_loc
|
||||
}
|
||||
|
||||
# Set the project name
|
||||
set _xil_proj_name_ "harv"
|
||||
|
||||
# Use project name variable, if specified in the tcl shell
|
||||
if { [info exists ::user_project_name] } {
|
||||
set _xil_proj_name_ $::user_project_name
|
||||
}
|
||||
|
||||
variable script_file
|
||||
set script_file "project.tcl"
|
||||
|
||||
# Help information for this script
|
||||
proc print_help {} {
|
||||
variable script_file
|
||||
puts "\nDescription:"
|
||||
puts "Recreate a Vivado project from this script. The created project will be"
|
||||
puts "functionally equivalent to the original project for which this script was"
|
||||
puts "generated. The script contains commands for creating a project, filesets,"
|
||||
puts "runs, adding/importing sources and setting properties on various objects.\n"
|
||||
puts "Syntax:"
|
||||
puts "$script_file"
|
||||
puts "$script_file -tclargs \[--origin_dir <path>\]"
|
||||
puts "$script_file -tclargs \[--project_name <name>\]"
|
||||
puts "$script_file -tclargs \[--help\]\n"
|
||||
puts "Usage:"
|
||||
puts "Name Description"
|
||||
puts "-------------------------------------------------------------------------"
|
||||
puts "\[--origin_dir <path>\] Determine source file paths wrt this path. Default"
|
||||
puts " origin_dir path value is \".\", otherwise, the value"
|
||||
puts " that was set with the \"-paths_relative_to\" switch"
|
||||
puts " when this script was generated.\n"
|
||||
puts "\[--project_name <name>\] Create project with the specified name. Default"
|
||||
puts " name is the name of the project from where this"
|
||||
puts " script was generated.\n"
|
||||
puts "\[--help\] Print help information for this script"
|
||||
puts "-------------------------------------------------------------------------\n"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if { $::argc > 0 } {
|
||||
for {set i 0} {$i < $::argc} {incr i} {
|
||||
set option [string trim [lindex $::argv $i]]
|
||||
switch -regexp -- $option {
|
||||
"--origin_dir" { incr i; set origin_dir [lindex $::argv $i] }
|
||||
"--project_name" { incr i; set _xil_proj_name_ [lindex $::argv $i] }
|
||||
"--help" { print_help }
|
||||
default {
|
||||
if { [regexp {^-} $option] } {
|
||||
puts "ERROR: Unknown option '$option' specified, please type '$script_file -tclargs --help' for usage info.\n"
|
||||
return 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Set the directory path for the original project from where this script was exported
|
||||
set orig_proj_dir "[file normalize "$origin_dir/xilinx"]"
|
||||
|
||||
# Check for paths and files needed for project creation
|
||||
set validate_required 0
|
||||
if { $validate_required } {
|
||||
if { [checkRequiredFiles $origin_dir] } {
|
||||
puts "Tcl file $script_file is valid. All files required for project creation is accesable. "
|
||||
} else {
|
||||
puts "Tcl file $script_file is not valid. Not all files required for project creation is accesable. "
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Create project
|
||||
create_project ${_xil_proj_name_} "xilinx/" -part xc7z020clg484-1
|
||||
|
||||
# Set the directory path for the new project
|
||||
set proj_dir [get_property directory [current_project]]
|
||||
|
||||
# Set project properties
|
||||
set obj [current_project]
|
||||
set_property -name "board_part" -value "em.avnet.com:zed:part0:1.4" -objects $obj
|
||||
set_property -name "default_lib" -value "xil_defaultlib" -objects $obj
|
||||
set_property -name "enable_vhdl_2008" -value "1" -objects $obj
|
||||
set_property -name "ip_cache_permissions" -value "read write" -objects $obj
|
||||
set_property -name "ip_output_repo" -value "$proj_dir/${_xil_proj_name_}.cache/ip" -objects $obj
|
||||
set_property -name "mem.enable_memory_map_generation" -value "1" -objects $obj
|
||||
set_property -name "platform.board_id" -value "zed" -objects $obj
|
||||
set_property -name "sim.central_dir" -value "$proj_dir/${_xil_proj_name_}.ip_user_files" -objects $obj
|
||||
set_property -name "sim.ip.auto_export_scripts" -value "1" -objects $obj
|
||||
set_property -name "simulator_language" -value "VHDL" -objects $obj
|
||||
set_property -name "target_language" -value "VHDL" -objects $obj
|
||||
set_property -name "webtalk.xsim_launch_sim" -value "30" -objects $obj
|
||||
|
||||
# Create 'sources_1' fileset (if not found)
|
||||
if {[string equal [get_filesets -quiet sources_1] ""]} {
|
||||
create_fileset -srcset sources_1
|
||||
}
|
||||
|
||||
# Set 'sources_1' fileset object
|
||||
set obj [get_filesets sources_1]
|
||||
set files [list \
|
||||
[file normalize "${origin_dir}/hdl/harv_pkg.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/alu.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/alu_tmr.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/control.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/control_tmr.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/csr.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/hamming_pkg.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/hamming_decoder.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/hamming_encoder.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/ft_components/hamming_register.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/instr_fetch.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/regfile.vhd"] \
|
||||
[file normalize "${origin_dir}/hdl/harv.vhd"] \
|
||||
]
|
||||
add_files -norecurse -fileset $obj $files
|
||||
|
||||
# Set 'sources_1' fileset file properties for remote files
|
||||
set file "$origin_dir/hdl/harv_pkg.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/alu.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/alu_tmr.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/control.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/control_tmr.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/csr.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/hamming_pkg.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/hamming_decoder.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/hamming_encoder.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/ft_components/hamming_register.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/instr_fetch.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/regfile.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
set file "$origin_dir/hdl/harv.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sources_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
# Set 'sources_1' fileset properties
|
||||
set obj [get_filesets sources_1]
|
||||
set_property -name "top" -value "harv" -objects $obj
|
||||
|
||||
# Create 'sim_1' fileset (if not found)
|
||||
if {[string equal [get_filesets -quiet sim_1] ""]} {
|
||||
create_fileset -simset sim_1
|
||||
}
|
||||
|
||||
# Set 'sim_1' fileset object
|
||||
set obj [get_filesets sim_1]
|
||||
set files [list \
|
||||
[file normalize "${origin_dir}/sim/sim_from_dump.vhd"] \
|
||||
]
|
||||
add_files -norecurse -fileset $obj $files
|
||||
|
||||
# Import local files from the original project
|
||||
set files [list \
|
||||
[file normalize "${origin_dir}/xilinx/sim_from_dump_behav.wcfg" ]\
|
||||
]
|
||||
add_files -norecurse -fileset sim_1 $files
|
||||
|
||||
# Set 'sim_1' fileset file properties for remote files
|
||||
set file "$origin_dir/sim/sim_from_dump.vhd"
|
||||
set file [file normalize $file]
|
||||
set file_obj [get_files -of_objects [get_filesets sim_1] [list "*$file"]]
|
||||
set_property -name "file_type" -value "VHDL 2008" -objects $file_obj
|
||||
|
||||
# Set 'sim_1' fileset properties
|
||||
set obj [get_filesets sim_1]
|
||||
set_property -name "hbs.configure_design_for_hier_access" -value "1" -objects $obj
|
||||
set_property -name "top" -value "sim_from_dump" -objects $obj
|
||||
set_property -name "top_lib" -value "xil_defaultlib" -objects $obj
|
||||
|
||||
puts "INFO: Project created: ${_xil_proj_name_}"
|
||||
|
||||
|
||||
exit
|
240
sim/sim_from_dump.vhd
Normal file
240
sim/sim_from_dump.vhd
Normal file
|
@ -0,0 +1,240 @@
|
|||
library ieee;
|
||||
use ieee.std_logic_1164.all;
|
||||
use ieee.numeric_std.all;
|
||||
|
||||
use std.textio.all;
|
||||
use ieee.std_logic_textio.all;
|
||||
|
||||
library work;
|
||||
use work.harv_pkg.harv;
|
||||
|
||||
entity sim_from_dump is
|
||||
end entity;
|
||||
|
||||
architecture arch of sim_from_dump is
|
||||
constant period : time := 100 ns;
|
||||
signal rstn : std_logic := '0';
|
||||
signal clk : std_logic := '0';
|
||||
signal start : std_logic := '0';
|
||||
|
||||
constant INST_BASE_ADDR : integer := 0;
|
||||
constant INST_SIZE : integer := 4096;
|
||||
constant DATA_BASE_ADDR : integer := 8192;
|
||||
constant DATA_SIZE : integer := 4096;
|
||||
|
||||
type mem_t is array(natural range <>) of std_logic_vector(7 downto 0);
|
||||
signal inst_mem : mem_t(INST_SIZE + INST_BASE_ADDR - 1 downto INST_BASE_ADDR);
|
||||
signal data_mem : mem_t(DATA_SIZE + DATA_BASE_ADDR - 1 downto DATA_BASE_ADDR);
|
||||
|
||||
-- instruction memory interface
|
||||
signal imem_instr_i : std_logic_vector(31 downto 0);
|
||||
signal imem_pc_o : std_logic_vector(31 downto 0);
|
||||
signal imem_req_o : std_logic;
|
||||
signal imem_gnt_i : std_logic;
|
||||
|
||||
-- data memory interface
|
||||
signal dmem_data_i : std_logic_vector(31 downto 0);
|
||||
signal dmem_req_o : std_logic;
|
||||
signal dmem_wren_o : std_logic;
|
||||
signal dmem_gnt_i : std_logic;
|
||||
signal dmem_outofrange_i : std_logic;
|
||||
signal dmem_byte_en_o : std_logic_vector(1 downto 0);
|
||||
signal dmem_usgn_dat_o : std_logic;
|
||||
signal dmem_data_o : std_logic_vector(31 downto 0);
|
||||
signal dmem_addr_o : std_logic_vector(31 downto 0);
|
||||
|
||||
constant INST_DUMP_FILE_PATH : string := "../../../../../src/test_text.dump";
|
||||
constant DATA_DUMP_FILE_PATH : string := "../../../../../src/test_data.dump";
|
||||
|
||||
procedure load_memory (
|
||||
constant FILE_PATH : in string;
|
||||
constant BASE_ADDR : in integer;
|
||||
signal mem : out mem_t
|
||||
) is
|
||||
file file_v : text;
|
||||
variable line_v : line;
|
||||
variable addr_v : integer;
|
||||
variable byte_v : std_logic_vector(7 downto 0);
|
||||
variable error_v : boolean;
|
||||
begin
|
||||
-- read data dump file
|
||||
file_open(file_v, FILE_PATH, READ_MODE);
|
||||
-- initialize instructions address counter
|
||||
addr_v := BASE_ADDR;
|
||||
-- iterate through all lines in the file
|
||||
while not endfile(file_v) loop
|
||||
-- read line from file_v
|
||||
readline(file_v, line_v);
|
||||
-- ensure that the line is not empty
|
||||
if line_v'length > 0 then
|
||||
-- iterate in each byte of the data
|
||||
for i in 3 downto 0 loop
|
||||
-- read hex byte from line
|
||||
hread(line_v, byte_v, error_v);
|
||||
-- assert if the hread had an error
|
||||
assert (error_v) report "Text I/O read error" severity FAILURE;
|
||||
-- write byte to memory
|
||||
mem(addr_v + i) <= byte_v;
|
||||
end loop;
|
||||
-- increment address
|
||||
addr_v := addr_v + 4;
|
||||
end if;
|
||||
end loop;
|
||||
file_close(file_v);
|
||||
end procedure;
|
||||
begin
|
||||
rstn <= '1' after period;
|
||||
clk <= not clk after period/2;
|
||||
start <= '1' after period * 2; -- set start signal after 2 clock cycles
|
||||
|
||||
harv_i : harv
|
||||
generic map (
|
||||
PROGRAM_START_ADDR => x"00000000",
|
||||
TRAP_HANDLER_ADDR => x"00000000",
|
||||
TMR_CONTROL => FALSE,
|
||||
TMR_ALU => FALSE,
|
||||
HAMMING_REGFILE => FALSE,
|
||||
HAMMING_PC => FALSE
|
||||
)
|
||||
port map (
|
||||
rstn_i => rstn,
|
||||
clk_i => clk,
|
||||
start_i => start,
|
||||
poweron_rstn_i => rstn,
|
||||
wdt_rstn_i => '1',
|
||||
imem_instr_i => imem_instr_i,
|
||||
imem_pc_o => imem_pc_o,
|
||||
imem_req_o => imem_req_o,
|
||||
imem_gnt_i => imem_gnt_i,
|
||||
imem_err_i => '0',
|
||||
hard_dmem_o => open,
|
||||
dmem_data_i => dmem_data_i,
|
||||
dmem_req_o => dmem_req_o,
|
||||
dmem_wren_o => dmem_wren_o,
|
||||
dmem_gnt_i => dmem_gnt_i,
|
||||
dmem_outofrange_i => dmem_outofrange_i,
|
||||
dmem_sbu_i => '0',
|
||||
dmem_dbu_i => '0',
|
||||
dmem_byte_en_o => dmem_byte_en_o,
|
||||
dmem_usgn_dat_o => dmem_usgn_dat_o,
|
||||
dmem_data_o => dmem_data_o,
|
||||
dmem_addr_o => dmem_addr_o
|
||||
);
|
||||
|
||||
-- INSTRUCTION MEMORY ACCESS
|
||||
process
|
||||
variable addr_v : integer;
|
||||
begin
|
||||
-- load instruction memory
|
||||
report "Loading instruction memory from " & INST_DUMP_FILE_PATH severity NOTE;
|
||||
load_memory(INST_DUMP_FILE_PATH, INST_BASE_ADDR, inst_mem);
|
||||
-- infinite loop to provide instruction memory access
|
||||
loop
|
||||
-- disable grant signal
|
||||
imem_gnt_i <= '0';
|
||||
imem_instr_i <= (others => 'X');
|
||||
-- wait memory request
|
||||
wait until rising_edge(clk) and imem_req_o = '1';
|
||||
-- wait 1 cycle to give response
|
||||
wait for period;
|
||||
-- grant response
|
||||
imem_gnt_i <= '1';
|
||||
addr_v := to_integer(unsigned(imem_pc_o));
|
||||
imem_instr_i <= inst_mem(addr_v+3) &
|
||||
inst_mem(addr_v+2) &
|
||||
inst_mem(addr_v+1) &
|
||||
inst_mem(addr_v);
|
||||
-- grant response for 1 cycle
|
||||
wait for period;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
-- DATA MEMORY ACCESS
|
||||
process
|
||||
variable addr_v : integer;
|
||||
begin
|
||||
-- if there is no data dump file
|
||||
if DATA_DUMP_FILE_PATH = "" then
|
||||
report "No data memory to load" severity NOTE;
|
||||
else -- if data dump file is defined
|
||||
-- load data memory from file
|
||||
report "Loading data memory from " & DATA_DUMP_FILE_PATH severity NOTE;
|
||||
load_memory (DATA_DUMP_FILE_PATH, DATA_BASE_ADDR, data_mem);
|
||||
end if;
|
||||
-- infinite loop to provide data memory access
|
||||
loop
|
||||
-- disable grant signal
|
||||
dmem_gnt_i <= '0';
|
||||
dmem_data_i <= (others => 'X');
|
||||
dmem_outofrange_i <= '0';
|
||||
-- wait memory request
|
||||
wait until rising_edge(clk) and dmem_req_o = '1';
|
||||
-- wait 1 cycle to give response
|
||||
wait for period;
|
||||
-- convert address to integer
|
||||
addr_v := to_integer(unsigned(dmem_addr_o));
|
||||
-- check if range is ok
|
||||
if addr_v < DATA_BASE_ADDR or addr_v > (DATA_BASE_ADDR + DATA_SIZE) then
|
||||
dmem_outofrange_i <= '1';
|
||||
else
|
||||
-- grant response
|
||||
dmem_gnt_i <= '1';
|
||||
-- if it will perform a write
|
||||
if dmem_wren_o = '1' then
|
||||
-- write the first byte
|
||||
data_mem(addr_v) <= dmem_data_o(7 downto 0);
|
||||
-- write the second byte for half-word and word
|
||||
if dmem_byte_en_o(0) = '1' then
|
||||
data_mem(addr_v+1) <= dmem_data_o(15 downto 8);
|
||||
end if;
|
||||
-- write the upper 16 bits, only for full word
|
||||
if dmem_byte_en_o(1) = '1' then
|
||||
data_mem(addr_v+2) <= dmem_data_o(23 downto 16);
|
||||
data_mem(addr_v+3) <= dmem_data_o(31 downto 24);
|
||||
end if;
|
||||
|
||||
-- read data memory
|
||||
else
|
||||
-- case between all acess possibilities
|
||||
case dmem_byte_en_o is
|
||||
-- byte read with and without sign-extension
|
||||
when "00" =>
|
||||
if dmem_usgn_dat_o = '1' then
|
||||
dmem_data_i <= x"000000" & data_mem(addr_v);
|
||||
else
|
||||
dmem_data_i <= (
|
||||
31 downto 8 => data_mem(addr_v)(7),
|
||||
7 downto 0 => data_mem(0)
|
||||
);
|
||||
end if;
|
||||
|
||||
-- half-word read with and without sign-extension
|
||||
when "01" =>
|
||||
if dmem_usgn_dat_o = '1' then
|
||||
dmem_data_i <= (
|
||||
31 downto 16 => data_mem(addr_v + 1)(7),
|
||||
15 downto 8 => data_mem(addr_v + 1),
|
||||
7 downto 0 => data_mem(addr_v)
|
||||
);
|
||||
else
|
||||
dmem_data_i <= x"000000" & data_mem(addr_v);
|
||||
end if;
|
||||
|
||||
-- word read - concatanate bytes
|
||||
when "11" =>
|
||||
dmem_data_i <= data_mem(addr_v + 3) &
|
||||
data_mem(addr_v + 2) &
|
||||
data_mem(addr_v + 1) &
|
||||
data_mem(addr_v);
|
||||
when others =>
|
||||
report "Wrong parameters to data memory" severity ERROR;
|
||||
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
-- response for 1 cycle
|
||||
wait for period;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
end architecture;
|
20
src/test.asm
Normal file
20
src/test.asm
Normal file
|
@ -0,0 +1,20 @@
|
|||
.data
|
||||
var0: 100
|
||||
var1: 200
|
||||
var3:
|
||||
.text
|
||||
lw t0, var0
|
||||
lw t1, var1
|
||||
|
||||
sub t2, t1, t0
|
||||
|
||||
add t3, t1, t2
|
||||
add t3, t3, t3
|
||||
|
||||
la t4, var3
|
||||
sw t3, 0(t4)
|
||||
lw t4, 0(t4)
|
||||
|
||||
end_loop:
|
||||
j end_loop
|
||||
|
210
xilinx/sim_from_dump_behav.wcfg
Normal file
210
xilinx/sim_from_dump_behav.wcfg
Normal file
|
@ -0,0 +1,210 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<wave_config>
|
||||
<wave_state>
|
||||
</wave_state>
|
||||
<db_ref_list>
|
||||
<db_ref path="sim_from_dump_behav.wdb" id="1">
|
||||
<top_modules>
|
||||
<top_module name="hamming_pkg" />
|
||||
<top_module name="harv_pkg" />
|
||||
<top_module name="sim_from_dump" />
|
||||
</top_modules>
|
||||
</db_ref>
|
||||
</db_ref_list>
|
||||
<zoom_setting>
|
||||
<ZoomStartTime time="0fs"></ZoomStartTime>
|
||||
<ZoomEndTime time="4890001fs"></ZoomEndTime>
|
||||
<Cursor1Time time="2070000fs"></Cursor1Time>
|
||||
</zoom_setting>
|
||||
<column_width_setting>
|
||||
<NameColumnWidth column_width="204"></NameColumnWidth>
|
||||
<ValueColumnWidth column_width="66"></ValueColumnWidth>
|
||||
</column_width_setting>
|
||||
<WVObjectSize size="28" />
|
||||
<wvobject type="array" fp_name="/sim_from_dump/INST_DUMP_FILE_PATH">
|
||||
<obj_property name="ElementShortName">INST_DUMP_FILE_PATH[1:33]</obj_property>
|
||||
<obj_property name="ObjectShortName">INST_DUMP_FILE_PATH[1:33]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/DATA_DUMP_FILE_PATH">
|
||||
<obj_property name="ElementShortName">DATA_DUMP_FILE_PATH[1:33]</obj_property>
|
||||
<obj_property name="ObjectShortName">DATA_DUMP_FILE_PATH[1:33]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/period">
|
||||
<obj_property name="ElementShortName">period</obj_property>
|
||||
<obj_property name="ObjectShortName">period</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/rstn">
|
||||
<obj_property name="ElementShortName">rstn</obj_property>
|
||||
<obj_property name="ObjectShortName">rstn</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/clk">
|
||||
<obj_property name="ElementShortName">clk</obj_property>
|
||||
<obj_property name="ObjectShortName">clk</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/start">
|
||||
<obj_property name="ElementShortName">start</obj_property>
|
||||
<obj_property name="ObjectShortName">start</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/imem_gnt_i">
|
||||
<obj_property name="ElementShortName">imem_gnt_i</obj_property>
|
||||
<obj_property name="ObjectShortName">imem_gnt_i</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/if_pc_w">
|
||||
<obj_property name="ElementShortName">if_pc_w[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">if_pc_w[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/instr_fetch_i/instr_o">
|
||||
<obj_property name="ElementShortName">instr_o[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">instr_o[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w[29]">
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="ElementShortName">[29][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">[29][31:0]</obj_property>
|
||||
<obj_property name="label">reg_t4</obj_property>
|
||||
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w[28]">
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="ElementShortName">[28][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">[28][31:0]</obj_property>
|
||||
<obj_property name="label">reg_t3</obj_property>
|
||||
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w[7]">
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="ElementShortName">[7][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">[7][31:0]</obj_property>
|
||||
<obj_property name="label">reg_t2</obj_property>
|
||||
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w[6]">
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="ElementShortName">[6][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">[6][31:0]</obj_property>
|
||||
<obj_property name="label">reg_t1</obj_property>
|
||||
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w[5]">
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="ElementShortName">[5][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">[5][31:0]</obj_property>
|
||||
<obj_property name="label">reg_t0</obj_property>
|
||||
<obj_property name="Radix">SIGNEDDECRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/g_normal/regfile_w">
|
||||
<obj_property name="ElementShortName">regfile_w[31:0][31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">regfile_w[31:0][31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider12650" type="divider">
|
||||
<obj_property name="label">CORE</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/gen_normal_control/control_i/proc_status_r">
|
||||
<obj_property name="ElementShortName">proc_status_r[2:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">proc_status_r[2:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/harv_i/regfile_i/data_i">
|
||||
<obj_property name="ElementShortName">data_i[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">data_i[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/harv_i/regfile_i/wren_i">
|
||||
<obj_property name="ElementShortName">wren_i</obj_property>
|
||||
<obj_property name="ObjectShortName">wren_i</obj_property>
|
||||
</wvobject>
|
||||
<wvobject fp_name="divider12648" type="divider">
|
||||
<obj_property name="label">MEMORIES</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="group" fp_name="group177">
|
||||
<obj_property name="label">imem</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/DATA_SIZE">
|
||||
<obj_property name="ElementShortName">DATA_SIZE</obj_property>
|
||||
<obj_property name="ObjectShortName">DATA_SIZE</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/imem_instr_i">
|
||||
<obj_property name="ElementShortName">imem_instr_i[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">imem_instr_i[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/imem_pc_o">
|
||||
<obj_property name="ElementShortName">imem_pc_o[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">imem_pc_o[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/imem_req_o">
|
||||
<obj_property name="ElementShortName">imem_req_o</obj_property>
|
||||
<obj_property name="ObjectShortName">imem_req_o</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/imem_gnt_i">
|
||||
<obj_property name="ElementShortName">imem_gnt_i</obj_property>
|
||||
<obj_property name="ObjectShortName">imem_gnt_i</obj_property>
|
||||
</wvobject>
|
||||
</wvobject>
|
||||
<wvobject type="group" fp_name="group4275">
|
||||
<obj_property name="label">dmem</obj_property>
|
||||
<obj_property name="DisplayName">label</obj_property>
|
||||
<obj_property name="isExpanded"></obj_property>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/dmem_data_i">
|
||||
<obj_property name="ElementShortName">dmem_data_i[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_data_i[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/dmem_req_o">
|
||||
<obj_property name="ElementShortName">dmem_req_o</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_req_o</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/dmem_wren_o">
|
||||
<obj_property name="ElementShortName">dmem_wren_o</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_wren_o</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/dmem_gnt_i">
|
||||
<obj_property name="ElementShortName">dmem_gnt_i</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_gnt_i</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/dmem_outofrange_i">
|
||||
<obj_property name="ElementShortName">dmem_outofrange_i</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_outofrange_i</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/dmem_byte_en_o">
|
||||
<obj_property name="ElementShortName">dmem_byte_en_o[1:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_byte_en_o[1:0]</obj_property>
|
||||
<obj_property name="Radix">BINARYRADIX</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="logic" fp_name="/sim_from_dump/dmem_usgn_dat_o">
|
||||
<obj_property name="ElementShortName">dmem_usgn_dat_o</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_usgn_dat_o</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/dmem_data_o">
|
||||
<obj_property name="ElementShortName">dmem_data_o[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_data_o[31:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/dmem_addr_o">
|
||||
<obj_property name="ElementShortName">dmem_addr_o[31:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">dmem_addr_o[31:0]</obj_property>
|
||||
<obj_property name="Radix">HEXRADIX</obj_property>
|
||||
</wvobject>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/data_mem">
|
||||
<obj_property name="ElementShortName">data_mem[12287:8192][7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">data_mem[12287:8192][7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="array" fp_name="/sim_from_dump/inst_mem">
|
||||
<obj_property name="ElementShortName">inst_mem[4095:0][7:0]</obj_property>
|
||||
<obj_property name="ObjectShortName">inst_mem[4095:0][7:0]</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/INST_BASE_ADDR">
|
||||
<obj_property name="ElementShortName">INST_BASE_ADDR</obj_property>
|
||||
<obj_property name="ObjectShortName">INST_BASE_ADDR</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/INST_SIZE">
|
||||
<obj_property name="ElementShortName">INST_SIZE</obj_property>
|
||||
<obj_property name="ObjectShortName">INST_SIZE</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/DATA_BASE_ADDR">
|
||||
<obj_property name="ElementShortName">DATA_BASE_ADDR</obj_property>
|
||||
<obj_property name="ObjectShortName">DATA_BASE_ADDR</obj_property>
|
||||
</wvobject>
|
||||
<wvobject type="other" fp_name="/sim_from_dump/DATA_SIZE">
|
||||
<obj_property name="ElementShortName">DATA_SIZE</obj_property>
|
||||
<obj_property name="ObjectShortName">DATA_SIZE</obj_property>
|
||||
</wvobject>
|
||||
</wave_config>
|
Loading…
Add table
Reference in a new issue