Compare commits
24
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d94de761b | ||
|
|
13513060ce | ||
|
|
5277a86a38 | ||
|
|
f8a1b31a04 | ||
|
|
d811f79d76 | ||
|
|
777fb14cef | ||
|
|
d9609c9c86 | ||
|
|
aef8406ae8 | ||
|
|
c2ce21f67c | ||
|
|
103e04d35f | ||
|
|
e75e17f72e | ||
|
|
63edf40cdc | ||
|
|
1f52aee5d9 | ||
|
|
cac6fc9540 | ||
|
|
cf6a2905a2 | ||
|
|
e7f8b05383 | ||
|
|
c80258eefe | ||
|
|
11c980bc09 | ||
|
|
b8c4d9699a | ||
|
|
ff11b70169 | ||
|
|
ae6738c0bd | ||
|
|
1966db95f1 | ||
|
|
ec06838c3e | ||
|
|
96280bb78a |
+8
-7
@@ -11,13 +11,14 @@ LANG_STD ?= 93c
|
||||
IEEE_STD ?= standard
|
||||
RUN_TIME ?= 1000ns
|
||||
WAVE_FORMAT ?= fst
|
||||
EXTRA_OPTS ?=
|
||||
|
||||
# Build path
|
||||
BUILD_DIR ?= build/$(TARGET)
|
||||
WORK_DIR ?= $(BUILD_DIR)/$(WORK_LIB)
|
||||
|
||||
# Can be pre-initialized by user
|
||||
RUN_OPTS += --stop-time=$(RUN_TIME)
|
||||
RUN_OPTS += --stop-time=$(RUN_TIME) $(EXTRA_OPTS)
|
||||
GHDL_OPTS += --work=$(WORK_LIB) --workdir=$(WORK_DIR) --std=$(LANG_STD) --ieee=$(IEEE_STD)
|
||||
|
||||
# -------------------------------------------------
|
||||
@@ -93,12 +94,6 @@ run_wave: analyze
|
||||
synth: analyze
|
||||
$(GHDL) --synth $(GHDL_OPTS) $(ENTITY)
|
||||
|
||||
wave: run_wave
|
||||
exec gtkwave -f $(SIM_FILE) -a $(TARGET).gtkw &
|
||||
|
||||
result:
|
||||
exec gtkwave -f $(SIM_FILE) -a $(TARGET).gtkw &
|
||||
|
||||
tree: analyze
|
||||
$(GHDL) -r $(GHDL_OPTS) $(ENTITY) $(RUN_OPTS) --no-run --disp-tree=inst
|
||||
|
||||
@@ -106,6 +101,12 @@ genwopt: analyze
|
||||
rm -rf $(TARGET).wopt.templ
|
||||
$(GHDL) -r $(GHDL_OPTS) $(ENTITY) --stop-time=0ps --write-wave-opt=$(TARGET).wopt.templ --wave=$(BUILD_DIR)/$(TARGET).ghw
|
||||
|
||||
wave: run_wave
|
||||
exec gtkwave -f $(SIM_FILE) -a $(TARGET).gtkw &
|
||||
|
||||
result:
|
||||
exec gtkwave -f $(SIM_FILE) -a $(TARGET).gtkw &
|
||||
|
||||
|
||||
.PHONY: list
|
||||
INSTR = $(foreach number,$(SRCS),echo $(number);)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -----------------------------------------------------------
|
||||
include $(VHDL_HOME)/make/defs.mk
|
||||
include $(VHDL_HOME)/defs.mk
|
||||
# -----------------------------------------------------------
|
||||
include package_other.inc
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# -----------------------------------------------------------
|
||||
include $(VHDL_HOME)/make/defs.mk
|
||||
include $(VHDL_HOME)/defs.mk
|
||||
# -----------------------------------------------------------
|
||||
include package1.inc
|
||||
include package2.inc
|
||||
|
||||
@@ -1,3 +1,2 @@
|
||||
LIB_PATH := $(VHDL_HOME)/lib
|
||||
VHDL_MAKE_HOME := $(VHDL_HOME)/Common/make
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
.gitignore
|
||||
build/
|
||||
.gitignore
|
||||
build/
|
||||
*.wopt
|
||||
|
||||
|
||||
@@ -1,31 +1,37 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||
[*] Sat Jul 2 11:01:23 2022
|
||||
[*] Mon Sep 12 21:25:14 2022
|
||||
[*]
|
||||
[dumpfile] "/home/jens/work/projects/vhdl/lib/CPUs/JCpu/ghdl/build/tb_cpu_embedded/tb_cpu_embedded.fst"
|
||||
[dumpfile_mtime] "Sat Jul 2 11:00:48 2022"
|
||||
[dumpfile_size] 3297
|
||||
[dumpfile] "/home/jens/work/projects/vhdl/lib/CPUs/JCpu/ghdl/build/tb_cpu_embedded/tb_cpu_embedded.ghw"
|
||||
[dumpfile_mtime] "Mon Sep 12 21:24:27 2022"
|
||||
[dumpfile_size] 23396
|
||||
[savefile] "/home/jens/work/projects/vhdl/lib/CPUs/JCpu/ghdl/tb_cpu_embedded.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1854 1136
|
||||
[pos] -51 -51
|
||||
[pos] -1 -1
|
||||
*-28.221537 367000000 -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
|
||||
[treeopen] top.
|
||||
[treeopen] top.tb_cpu_embedded.
|
||||
[treeopen] top.tb_cpu_embedded.uut.
|
||||
[sst_width] 233
|
||||
[signals_width] 242
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 330
|
||||
@28
|
||||
uut.clk
|
||||
uut.rst
|
||||
top.tb_cpu_embedded.uut.rst
|
||||
top.tb_cpu_embedded.uut.clk
|
||||
@22
|
||||
uut.irom_addr[11:0]
|
||||
uut.irom_data[17:0]
|
||||
uut.xmem_addr[7:0]
|
||||
uut.xmem_din[7:0]
|
||||
uut.xmem_dout[7:0]
|
||||
#{top.tb_cpu_embedded.uut.irom_data[17:0]} top.tb_cpu_embedded.uut.irom_data[17] top.tb_cpu_embedded.uut.irom_data[16] top.tb_cpu_embedded.uut.irom_data[15] top.tb_cpu_embedded.uut.irom_data[14] top.tb_cpu_embedded.uut.irom_data[13] top.tb_cpu_embedded.uut.irom_data[12] top.tb_cpu_embedded.uut.irom_data[11] top.tb_cpu_embedded.uut.irom_data[10] top.tb_cpu_embedded.uut.irom_data[9] top.tb_cpu_embedded.uut.irom_data[8] top.tb_cpu_embedded.uut.irom_data[7] top.tb_cpu_embedded.uut.irom_data[6] top.tb_cpu_embedded.uut.irom_data[5] top.tb_cpu_embedded.uut.irom_data[4] top.tb_cpu_embedded.uut.irom_data[3] top.tb_cpu_embedded.uut.irom_data[2] top.tb_cpu_embedded.uut.irom_data[1] top.tb_cpu_embedded.uut.irom_data[0]
|
||||
#{top.tb_cpu_embedded.uut.irom_addr[11:0]} top.tb_cpu_embedded.uut.irom_addr[11] top.tb_cpu_embedded.uut.irom_addr[10] top.tb_cpu_embedded.uut.irom_addr[9] top.tb_cpu_embedded.uut.irom_addr[8] top.tb_cpu_embedded.uut.irom_addr[7] top.tb_cpu_embedded.uut.irom_addr[6] top.tb_cpu_embedded.uut.irom_addr[5] top.tb_cpu_embedded.uut.irom_addr[4] top.tb_cpu_embedded.uut.irom_addr[3] top.tb_cpu_embedded.uut.irom_addr[2] top.tb_cpu_embedded.uut.irom_addr[1] top.tb_cpu_embedded.uut.irom_addr[0]
|
||||
#{top.tb_cpu_embedded.uut.xmem_addr[7:0]} top.tb_cpu_embedded.uut.xmem_addr[7] top.tb_cpu_embedded.uut.xmem_addr[6] top.tb_cpu_embedded.uut.xmem_addr[5] top.tb_cpu_embedded.uut.xmem_addr[4] top.tb_cpu_embedded.uut.xmem_addr[3] top.tb_cpu_embedded.uut.xmem_addr[2] top.tb_cpu_embedded.uut.xmem_addr[1] top.tb_cpu_embedded.uut.xmem_addr[0]
|
||||
#{top.tb_cpu_embedded.uut.xmem_dout[7:0]} top.tb_cpu_embedded.uut.xmem_dout[7] top.tb_cpu_embedded.uut.xmem_dout[6] top.tb_cpu_embedded.uut.xmem_dout[5] top.tb_cpu_embedded.uut.xmem_dout[4] top.tb_cpu_embedded.uut.xmem_dout[3] top.tb_cpu_embedded.uut.xmem_dout[2] top.tb_cpu_embedded.uut.xmem_dout[1] top.tb_cpu_embedded.uut.xmem_dout[0]
|
||||
#{top.tb_cpu_embedded.uut.xmem_din[7:0]} top.tb_cpu_embedded.uut.xmem_din[7] top.tb_cpu_embedded.uut.xmem_din[6] top.tb_cpu_embedded.uut.xmem_din[5] top.tb_cpu_embedded.uut.xmem_din[4] top.tb_cpu_embedded.uut.xmem_din[3] top.tb_cpu_embedded.uut.xmem_din[2] top.tb_cpu_embedded.uut.xmem_din[1] top.tb_cpu_embedded.uut.xmem_din[0]
|
||||
@28
|
||||
uut.xmem_we
|
||||
top.tb_cpu_embedded.uut.xmem_re
|
||||
top.tb_cpu_embedded.uut.xmem_we
|
||||
top.tb_cpu_embedded.uut.io_sel
|
||||
top.tb_cpu_embedded.uut.int_ack
|
||||
@29
|
||||
uut.xmem_re
|
||||
top.tb_cpu_embedded.uut.int_in
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
|
||||
@@ -11,6 +11,7 @@ SRCS += ../src/tb_cpu_embedded.vhd
|
||||
# Compile
|
||||
TARGET := tb_cpu_embedded
|
||||
ENTITY := tb_cpu_embedded
|
||||
WAVE_FORMAT := ghw
|
||||
|
||||
include $(VHDL_MAKE_HOME)/ghdl.mk
|
||||
|
||||
|
||||
@@ -0,0 +1,199 @@
|
||||
$ version 1.1
|
||||
|
||||
# Signals in packages :
|
||||
|
||||
# Signals in entities :
|
||||
/tb_cpu_embedded/rst
|
||||
/tb_cpu_embedded/clk
|
||||
/tb_cpu_embedded/ce
|
||||
/tb_cpu_embedded/int_in
|
||||
/tb_cpu_embedded/int_ack
|
||||
/tb_cpu_embedded/xmem_din
|
||||
/tb_cpu_embedded/xmem_dout
|
||||
/tb_cpu_embedded/xmem_addr
|
||||
/tb_cpu_embedded/xmem_we
|
||||
/tb_cpu_embedded/xmem_re
|
||||
/tb_cpu_embedded/io_sel
|
||||
/tb_cpu_embedded/sram
|
||||
/tb_cpu_embedded/uut/rst
|
||||
/tb_cpu_embedded/uut/clk
|
||||
/tb_cpu_embedded/uut/ce
|
||||
/tb_cpu_embedded/uut/int_in
|
||||
/tb_cpu_embedded/uut/int_ack
|
||||
/tb_cpu_embedded/uut/xmem_we
|
||||
/tb_cpu_embedded/uut/xmem_re
|
||||
/tb_cpu_embedded/uut/xmem_din
|
||||
/tb_cpu_embedded/uut/xmem_dout
|
||||
/tb_cpu_embedded/uut/xmem_addr
|
||||
/tb_cpu_embedded/uut/io_sel
|
||||
/tb_cpu_embedded/uut/irom_data
|
||||
/tb_cpu_embedded/uut/irom_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/ce
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_ack
|
||||
/tb_cpu_embedded/uut/inst_cpu/xmem_we
|
||||
/tb_cpu_embedded/uut/inst_cpu/xmem_re
|
||||
/tb_cpu_embedded/uut/inst_cpu/instr_din
|
||||
/tb_cpu_embedded/uut/inst_cpu/instr_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/xmem_din
|
||||
/tb_cpu_embedded/uut/inst_cpu/xmem_dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/xmem_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/io_sel
|
||||
/tb_cpu_embedded/uut/inst_cpu/cpu_status
|
||||
/tb_cpu_embedded/uut/inst_cpu/status_reg
|
||||
/tb_cpu_embedded/uut/inst_cpu/ctrl
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_reg
|
||||
/tb_cpu_embedded/uut/inst_cpu/pc_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/pc_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/pc_next
|
||||
/tb_cpu_embedded/uut/inst_cpu/idata
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_pc_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/iphase
|
||||
/tb_cpu_embedded/uut/inst_cpu/const_data
|
||||
/tb_cpu_embedded/uut/inst_cpu/reg_a_dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/reg_b_dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/reg_din
|
||||
/tb_cpu_embedded/uut/inst_cpu/alu_op1
|
||||
/tb_cpu_embedded/uut/inst_cpu/alu_op2
|
||||
/tb_cpu_embedded/uut/inst_cpu/alu_result
|
||||
/tb_cpu_embedded/uut/inst_cpu/alu_status
|
||||
/tb_cpu_embedded/uut/inst_cpu/pc_inc
|
||||
/tb_cpu_embedded/uut/inst_cpu/pc_load
|
||||
/tb_cpu_embedded/uut/inst_cpu/cpu_active
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_we
|
||||
/tb_cpu_embedded/uut/inst_cpu/cmem_we
|
||||
/tb_cpu_embedded/uut/inst_cpu/creg_we
|
||||
/tb_cpu_embedded/uut/inst_cpu/ctrl_inst
|
||||
/tb_cpu_embedded/uut/inst_cpu/ctrl_iphase
|
||||
/tb_cpu_embedded/uut/inst_cpu/was_pcld
|
||||
/tb_cpu_embedded/uut/inst_cpu/was_pop2pc
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_pc_load
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_stk_push
|
||||
/tb_cpu_embedded/uut/inst_cpu/int_stk_pop
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_push
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_pop
|
||||
/tb_cpu_embedded/uut/inst_cpu/status_save
|
||||
/tb_cpu_embedded/uut/inst_cpu/status_restore
|
||||
/tb_cpu_embedded/uut/inst_cpu/creg_dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/cmem_din
|
||||
/tb_cpu_embedded/uut/inst_cpu/cmem_dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/cmem_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/stk_ptr
|
||||
/tb_cpu_embedded/uut/inst_cpu/creg_ctrl_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/creg_ctrl_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/xio_sel
|
||||
/tb_cpu_embedded/uut/inst_cpu/cio_sel
|
||||
/tb_cpu_embedded/uut/inst_cpu/mem_data
|
||||
/tb_cpu_embedded/uut/inst_cpu/mem_addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/push
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/pop
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/ptr_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/din
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/mem_we
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_stack_ctrl/ptr
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/inc
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/load
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/pc_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/pc_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_pc/pc_next
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/inst_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/iphase_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/status_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/ctrl_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/idout
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/ddout
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/opcode
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/ctrl_lines
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_dpath_ctrl/dbg_iname
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/ctrl_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_exit
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/iphase_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/pc_addr_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_ack_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stat_save_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stat_rest_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/pc_load_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stk_push_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stk_pop_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_state
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_state_next
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/pc_load
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_ack
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stk_push
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/stk_pop
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_int_ctrl/int_request
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/we_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/ptr_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/ptr_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/din_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/dout_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/dout_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/addr_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/addr_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_reg_ab/mem
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/clka
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/clkb
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/en_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/en_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/we_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/we_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/addr_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/addr_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/din_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/din_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/dout_a
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipram/dout_b
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/we
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/addr
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/din
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/dout
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/ctrl_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/ctrl_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/reg_bank_sel
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/reg_int_ctrl
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/reg_stk_high
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_chipreg/reg_cmem_high
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/rst
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/clk
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/op_en
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/cy_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/op1_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/op2_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/opsel
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/res_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/stat_load
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/stat_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/stat_out
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sum_cy
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sh_cy
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sum_cy_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sh_cy_in
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/left_shift
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/add_subn
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/result
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sum_res
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/lf_res
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/sh_res
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/res_reg
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/status
|
||||
/tb_cpu_embedded/uut/inst_cpu/inst_alu/stat_reg
|
||||
/tb_cpu_embedded/uut/inst_irom/clk
|
||||
/tb_cpu_embedded/uut/inst_irom/ce
|
||||
/tb_cpu_embedded/uut/inst_irom/addr
|
||||
/tb_cpu_embedded/uut/inst_irom/dout
|
||||
@@ -0,0 +1 @@
|
||||
<mxfile host="app.diagrams.net" modified="2022-09-11T17:00:05.394Z" agent="5.0 (X11)" etag="ULt_GwP94m2c2vBAbY-Z" version="20.3.0" type="device"><diagram id="XI_-d3d4CUWLWsZJCx82" name="Seite-1">7VxNj9owEP01HLsidkLCcZfttmpVqRKHtqcqIl6w1sTImAL99XWITWIbmizN1ya9IDzEjjPvjT0znjCCs/XhAws3qy80QmQExtFhBB9HAEyhJz4TwTEVeME0FSwZjlKRkwnm+DeSwrGU7nCEttqFnFLC8UYXLmgcowXXZCFjdK9f9kyJftdNuESWYL4IiS39hiO+SqUB8DP5R4SXK3VnZyKfbx2qi+WTbFdhRPc5EXw/gjNGKU+/rQ8zRBLdKb2k/Z6u/HqeGEMxL9PhZffpeYp/ftzsHZ89LcE8+EzeyVF+hWQnH1hOlh+VBhjdxRFKBhmP4MN+hTmab8JF8uteQC5kK74mouWIr3I4xDg6XJ2nc356wRpE14izo7hEdXCkBiVjHKXAfaZ/V4pWedVPpDCUkC/PQ2daEV+kYl6hJLd7SoKdU5JfrCQxijBb0XgQtrBJhAtCd1EjCgOmwlyvlMJgXfoKSugrju6TJeykqHC7xQtdLTrphCLY8XvSuPMcXwl+nASO6yrB4yF//eMx3/qKGBZPh5gUpjNCkbVEGloXa3LIlogX0cNGJ6d974L2lYwhEnL8S5/GJUjkHb5SLCaYgQ918AMD1C3dsQWSnfJLqDEOnOjjWOxI1WANdCLI+alv58y0Ps7ofAFeEV0OmKdcC3xPttOuqpV1TBr5frezLMWpeBEqZKPbKht9g0XurXQExpo2bZaOykerZQ1zJjolvbKUdDQ6ggI+/tuyV0jIt7E8TlydR35VhDQHqpuQtjs754mDD8ZiIuMZZ8QiqHApuE7JLWf0Bc0ooQkhYhonHsszJsQQhQQv44TXghUJdx4SBwWL0OFe/rDGUZTc5qJ7oxO/Cg9nrCvfsz3CSZMOjgNKgDHGcX8RcTzDHGDbkMAh20fn0CgRV+a2T6nVq3tn2V2rrV3GjOtv9sIdw5sHZkxb9y7jDQu3InWXxs0rIEDduE0GhZuZIro96m3b3sqklnqEW1X2Btu2txpTXHps6BfFhmUxLxGptcqNqjIHjhErnOfXFDXsTJZwRE/9xhZHeuOBmvaoNqS2HFB1ZvCGDPTt5+zMXdkcqGbLAxdTJKd+jgV+byyve6ZnJ0f+ZnpFPs1WsIari6kYVMmeMNEP0bprYmacAUFV8WHDfg+wsyxDxxbC4C6oBl17qMbxHVbexq/ILL1pwUB1w2anbWbkpb97nrnlqcPB1ra8MumXFitE3K5ViIDX5T06VSJSGEYrNnRmmXMrqhHxWq4RAY1lXbpQJFJ4AN89nlUVSXrmetVwWlad9Q+k+uPtrWhm/tciSGmmtVzWoVbQC8fWQik9P7Z2O1bWAa/X2GRg9Lqsw7KrtgsJoJ1MGpB9dA6NEumfpl8XsHyF1l8XgMNKopgA3B5etHwYD4dV/FKo7tK4tXwYD6stfulDUtqrLiltD9U4vjUmi3p2lmua4u1x0bTdCBzaqR5ORVs5fzYDeuP1WRhe8PqCRr2+yrMhXTcjvyIrst73bdiKlN+bQ+6Z0XXOjtRbPH00JDO1c8GOpk3akVvijfT/+1gasNWVSW66Jsm9mL849evxFmYmLmqsSRLN7H8mUtSyP+uA7/8A</diagram></mxfile>
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -2,7 +2,6 @@
|
||||
include $(VHDL_HOME)/defs.mk
|
||||
include $(LIB_PATH)/FIFO/ghdl/fifo_sync.inc
|
||||
include $(LIB_PATH)/FIFO/ghdl/fifo_async.inc
|
||||
include $(LIB_PATH)/JBUS/busmaster/ghdl/busmaster_async.inc
|
||||
|
||||
# -----------------------------------------------------------
|
||||
PKG_NAME := MIPS_CORE
|
||||
@@ -11,24 +10,20 @@ PKG_NAME := MIPS_CORE
|
||||
MOD_PATH := $(LIB_PATH)/CPUs/MIPS/src/core
|
||||
$(PKG_NAME)_SRCS += $(FIFO_SYNC_SRCS)
|
||||
$(PKG_NAME)_SRCS += $(FIFO_ASYNC_SRCS)
|
||||
$(PKG_NAME)_SRCS += $(BUSMASTER_ASYNC_SRCS)
|
||||
|
||||
$(PKG_NAME)_SRCS += $(LIB_PATH)/rams/sim/src/dpram_2w2r2c_ra.vhd
|
||||
$(PKG_NAME)_SRCS += $(LIB_PATH)/rams/sim/src/dpram_1w1r2c_ra.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_util_pkg.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_types.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_func_pkg.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_instr.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_alu.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_bcu.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_reg.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_cam.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_tlb.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_dcache.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_icache.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_biu.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_cop.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_dcache.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_icache.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_muldiv.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_pipeline.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_reg.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_shifter.vhd
|
||||
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_top.vhd
|
||||
|
||||
|
||||
@@ -1,29 +1,35 @@
|
||||
[*]
|
||||
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
|
||||
[*] Thu Sep 8 14:06:03 2022
|
||||
[*] Tue Sep 13 09:25:38 2022
|
||||
[*]
|
||||
[dumpfile] "/home/jens/work/projects/vhdl-BRANCH_MIPS_R14/lib/CPUs/MIPS/ghdl/build/tb_mips_top/tb_mips_top.ghw"
|
||||
[dumpfile_mtime] "Thu Sep 8 09:48:46 2022"
|
||||
[dumpfile_size] 16383435
|
||||
[savefile] "/home/jens/work/projects/vhdl-BRANCH_MIPS_R14/lib/CPUs/MIPS/ghdl/tb_mips_top.gtkw"
|
||||
[timestart] 0
|
||||
[size] 1854 1136
|
||||
[pos] -1 -1
|
||||
*-34.382011 10815000000 -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
|
||||
[dumpfile] "/home/jens/work/projects/vhdl/lib/CPUs/MIPS/ghdl/build/tb_mips_top/tb_mips_top.ghw"
|
||||
[dumpfile_mtime] "Tue Sep 13 05:37:30 2022"
|
||||
[dumpfile_size] 284165098
|
||||
[savefile] "/home/jens/work/projects/vhdl/lib/CPUs/MIPS/ghdl/tb_mips_top.gtkw"
|
||||
[timestart] 1624938400000
|
||||
[size] 1920 1163
|
||||
[pos] -1987 -28
|
||||
*-24.584558 1625004800000 1624975000000 -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
|
||||
[treeopen] top.
|
||||
[treeopen] top.tb_mips_top.
|
||||
[treeopen] top.tb_mips_top.uut.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.
|
||||
[treeopen] top.tb_mips_top.uut.inst_biu.inst_icache.
|
||||
[treeopen] top.tb_mips_top.uut.inst_cop.
|
||||
[treeopen] top.tb_mips_top.uut.inst_cop.ctrl_in.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.c0_ctrl_in.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.c0_ctrl_out.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.ex_stage.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.id_stage.
|
||||
[sst_width] 233
|
||||
[signals_width] 228
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.mem_stage.
|
||||
[treeopen] top.tb_mips_top.uut.inst_pipeline.wb_stage.
|
||||
[sst_width] 358
|
||||
[signals_width] 296
|
||||
[sst_expanded] 1
|
||||
[sst_vpaned_height] 488
|
||||
[sst_vpaned_height] 667
|
||||
@200
|
||||
-MIPS_R14
|
||||
-MIPS_R13
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.clk_1
|
||||
top.tb_mips_top.uut.inst_pipeline.clk_2
|
||||
top.tb_mips_top.uut.cpu_clk
|
||||
top.tb_mips_top.uut.clk_i
|
||||
top.tb_mips_top.uut.stb_o
|
||||
@22
|
||||
@@ -33,8 +39,6 @@ top.tb_mips_top.uut.stb_o
|
||||
@200
|
||||
-PC
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.branch_ce
|
||||
top.tb_mips_top.uut.inst_pipeline.pc.branch_not_taken
|
||||
top.tb_mips_top.uut.inst_pipeline.pc.branch_take
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[31:0]} top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[31] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[30] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[29] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[28] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[27] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[26] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[25] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[24] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[23] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[22] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[21] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[20] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[19] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[18] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[17] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[16] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[15] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[14] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[13] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[12] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[11] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[10] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[9] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[8] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[7] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[6] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[5] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[4] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[3] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[2] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[1] top.tb_mips_top.uut.inst_pipeline.pc.pc_branch[0]
|
||||
@@ -48,18 +52,19 @@ top.tb_mips_top.uut.inst_pipeline.pc.branch_take
|
||||
#{top.tb_mips_top.uut.inst_pipeline.reg_b[31:0]} top.tb_mips_top.uut.inst_pipeline.reg_b[31] top.tb_mips_top.uut.inst_pipeline.reg_b[30] top.tb_mips_top.uut.inst_pipeline.reg_b[29] top.tb_mips_top.uut.inst_pipeline.reg_b[28] top.tb_mips_top.uut.inst_pipeline.reg_b[27] top.tb_mips_top.uut.inst_pipeline.reg_b[26] top.tb_mips_top.uut.inst_pipeline.reg_b[25] top.tb_mips_top.uut.inst_pipeline.reg_b[24] top.tb_mips_top.uut.inst_pipeline.reg_b[23] top.tb_mips_top.uut.inst_pipeline.reg_b[22] top.tb_mips_top.uut.inst_pipeline.reg_b[21] top.tb_mips_top.uut.inst_pipeline.reg_b[20] top.tb_mips_top.uut.inst_pipeline.reg_b[19] top.tb_mips_top.uut.inst_pipeline.reg_b[18] top.tb_mips_top.uut.inst_pipeline.reg_b[17] top.tb_mips_top.uut.inst_pipeline.reg_b[16] top.tb_mips_top.uut.inst_pipeline.reg_b[15] top.tb_mips_top.uut.inst_pipeline.reg_b[14] top.tb_mips_top.uut.inst_pipeline.reg_b[13] top.tb_mips_top.uut.inst_pipeline.reg_b[12] top.tb_mips_top.uut.inst_pipeline.reg_b[11] top.tb_mips_top.uut.inst_pipeline.reg_b[10] top.tb_mips_top.uut.inst_pipeline.reg_b[9] top.tb_mips_top.uut.inst_pipeline.reg_b[8] top.tb_mips_top.uut.inst_pipeline.reg_b[7] top.tb_mips_top.uut.inst_pipeline.reg_b[6] top.tb_mips_top.uut.inst_pipeline.reg_b[5] top.tb_mips_top.uut.inst_pipeline.reg_b[4] top.tb_mips_top.uut.inst_pipeline.reg_b[3] top.tb_mips_top.uut.inst_pipeline.reg_b[2] top.tb_mips_top.uut.inst_pipeline.reg_b[1] top.tb_mips_top.uut.inst_pipeline.reg_b[0]
|
||||
@200
|
||||
-ID
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.sdu.dmem_dep
|
||||
@29
|
||||
top.tb_mips_top.uut.inst_pipeline.sdu.imem_dep
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.id_stage.epc[31:0]} top.tb_mips_top.uut.inst_pipeline.id_stage.epc[31] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[30] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[29] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[28] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[27] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[26] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[25] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[24] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[23] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[22] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[21] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[20] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[19] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[18] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[17] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[16] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[15] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[14] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[13] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[12] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[11] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[10] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[9] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[8] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[7] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[6] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[5] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[4] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[3] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[2] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[1] top.tb_mips_top.uut.inst_pipeline.id_stage.epc[0]
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.id_stage.nop
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.id_stage.ir[31:0]} top.tb_mips_top.uut.inst_pipeline.id_stage.ir[31] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[30] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[29] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[28] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[27] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[26] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[25] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[24] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[23] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[22] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[21] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[20] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[19] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[18] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[17] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[16] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[15] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[14] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[13] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[12] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[11] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[10] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[9] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[8] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[7] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[6] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[5] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[4] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[3] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[2] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[1] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[0]
|
||||
@420
|
||||
top.tb_mips_top.uut.inst_pipeline.id_stage.op
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.id_stage.exc
|
||||
top.tb_mips_top.uut.inst_pipeline.sdu.dmem_dep
|
||||
top.tb_mips_top.uut.inst_pipeline.sdu.imem_dep
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.id_stage.ir[31:0]} top.tb_mips_top.uut.inst_pipeline.id_stage.ir[31] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[30] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[29] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[28] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[27] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[26] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[25] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[24] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[23] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[22] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[21] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[20] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[19] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[18] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[17] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[16] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[15] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[14] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[13] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[12] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[11] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[10] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[9] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[8] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[7] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[6] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[5] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[4] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[3] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[2] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[1] top.tb_mips_top.uut.inst_pipeline.id_stage.ir[0]
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.id_stage.reg_write
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[31:0]} top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[31] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[30] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[29] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[28] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[27] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[26] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[25] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[24] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[23] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[22] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[21] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[20] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[19] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[18] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[17] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[16] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[15] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[14] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[13] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[12] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[11] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[10] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[9] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[8] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[7] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[6] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[5] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[4] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[3] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[2] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[1] top.tb_mips_top.uut.inst_pipeline.id_stage.pcn[0]
|
||||
@@ -70,5 +75,62 @@ top.tb_mips_top.uut.inst_pipeline.id_stage.reg_write
|
||||
#{top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[31:0]} top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[31] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[30] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[29] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[28] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[27] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[26] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[25] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[24] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[23] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[22] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[21] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[20] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[19] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[18] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[17] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[16] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[15] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[14] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[13] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[12] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[11] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[10] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[9] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[8] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[7] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[6] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[5] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[4] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[3] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[2] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[1] top.tb_mips_top.uut.inst_pipeline.id_stage.reg_b[0]
|
||||
@200
|
||||
-EX
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[31:0]} top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[31] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[30] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[29] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[28] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[27] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[26] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[25] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[24] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[23] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[22] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[21] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[20] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[19] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[18] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[17] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[16] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[15] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[14] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[13] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[12] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[11] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[10] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[9] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[8] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[7] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[6] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[5] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[4] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[3] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[2] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[1] top.tb_mips_top.uut.inst_pipeline.ex_stage.epc[0]
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.ex_stage.nop
|
||||
@420
|
||||
top.tb_mips_top.uut.inst_pipeline.ex_stage.op
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.ex_stage.exc
|
||||
top.tb_mips_top.uut.inst_pipeline.ex_stage.reg_write
|
||||
top.tb_mips_top.uut.inst_pipeline.ex_stage.wreg_we
|
||||
@200
|
||||
-MEM
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[31:0]} top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[31] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[30] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[29] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[28] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[27] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[26] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[25] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[24] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[23] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[22] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[21] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[20] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[19] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[18] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[17] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[16] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[15] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[14] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[13] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[12] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[11] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[10] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[9] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[8] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[7] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[6] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[5] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[4] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[3] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[2] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[1] top.tb_mips_top.uut.inst_pipeline.mem_stage.epc[0]
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.mem_stage.nop
|
||||
@420
|
||||
top.tb_mips_top.uut.inst_pipeline.mem_stage.op
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.mem_stage.exc
|
||||
top.tb_mips_top.uut.inst_pipeline.mem_stage.events.int
|
||||
@200
|
||||
-WB
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.nop
|
||||
@420
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.op
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.exc
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.events.int
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.bd
|
||||
top.tb_mips_top.uut.inst_pipeline.wb_stage.events.int
|
||||
@200
|
||||
-COP
|
||||
@421
|
||||
top.tb_mips_top.uut.inst_cop.exc_state
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_cop.epc[31:0]} top.tb_mips_top.uut.inst_cop.epc[31] top.tb_mips_top.uut.inst_cop.epc[30] top.tb_mips_top.uut.inst_cop.epc[29] top.tb_mips_top.uut.inst_cop.epc[28] top.tb_mips_top.uut.inst_cop.epc[27] top.tb_mips_top.uut.inst_cop.epc[26] top.tb_mips_top.uut.inst_cop.epc[25] top.tb_mips_top.uut.inst_cop.epc[24] top.tb_mips_top.uut.inst_cop.epc[23] top.tb_mips_top.uut.inst_cop.epc[22] top.tb_mips_top.uut.inst_cop.epc[21] top.tb_mips_top.uut.inst_cop.epc[20] top.tb_mips_top.uut.inst_cop.epc[19] top.tb_mips_top.uut.inst_cop.epc[18] top.tb_mips_top.uut.inst_cop.epc[17] top.tb_mips_top.uut.inst_cop.epc[16] top.tb_mips_top.uut.inst_cop.epc[15] top.tb_mips_top.uut.inst_cop.epc[14] top.tb_mips_top.uut.inst_cop.epc[13] top.tb_mips_top.uut.inst_cop.epc[12] top.tb_mips_top.uut.inst_cop.epc[11] top.tb_mips_top.uut.inst_cop.epc[10] top.tb_mips_top.uut.inst_cop.epc[9] top.tb_mips_top.uut.inst_cop.epc[8] top.tb_mips_top.uut.inst_cop.epc[7] top.tb_mips_top.uut.inst_cop.epc[6] top.tb_mips_top.uut.inst_cop.epc[5] top.tb_mips_top.uut.inst_cop.epc[4] top.tb_mips_top.uut.inst_cop.epc[3] top.tb_mips_top.uut.inst_cop.epc[2] top.tb_mips_top.uut.inst_cop.epc[1] top.tb_mips_top.uut.inst_cop.epc[0]
|
||||
#{top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31:0]} top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[30] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[29] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[28] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[27] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[26] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[25] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[24] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[23] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[22] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[21] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[20] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[19] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[18] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[17] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[16] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[15] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[14] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[13] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[12] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[11] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[10] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[9] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[8] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[7] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[6] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[5] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[4] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[3] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[2] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[1] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[0]
|
||||
#{top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[31:0]} top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[31] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[30] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[29] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[28] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[27] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[26] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[25] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[24] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[23] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[22] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[21] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[20] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[19] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[18] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[17] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[16] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[15] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[14] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[13] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[12] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[11] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[10] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[9] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[8] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[7] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[6] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[5] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[4] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[3] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[2] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[1] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_wb[0]
|
||||
@200
|
||||
-I-Cache
|
||||
@420
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.s
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[31:0]} top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[31] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[30] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[29] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[28] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[27] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[26] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[25] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[24] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[23] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[22] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[21] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[20] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[19] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[18] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[17] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[16] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[15] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[14] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[13] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[12] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[11] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[10] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[9] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[8] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[7] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[6] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[5] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[4] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[3] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[2] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[1] top.tb_mips_top.uut.inst_biu.inst_icache.cpu_addr[0]
|
||||
@28
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cpu_busy
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cpu_en
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.tag_match
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cache_hit
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cache_busy
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cache_ack
|
||||
top.tb_mips_top.uut.inst_biu.inst_icache.cache_req
|
||||
@22
|
||||
#{top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31:0]} top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[30] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[29] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[28] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[27] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[26] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[25] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[24] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[23] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[22] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[21] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[20] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[19] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[18] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[17] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[16] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[15] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[14] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[13] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[12] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[11] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[10] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[9] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[8] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[7] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[6] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[5] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[4] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[3] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[2] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[1] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[0]
|
||||
#{top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31:0]} top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[31] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[30] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[29] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[28] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[27] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[26] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[25] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[24] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[23] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[22] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[21] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[20] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[19] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[18] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[17] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[16] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[15] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[14] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[13] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[12] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[11] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[10] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[9] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[8] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[7] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[6] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[5] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[4] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[3] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[2] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[1] top.tb_mips_top.uut.inst_cop.ctrl_in.epc_mem[0]
|
||||
[pattern_trace] 1
|
||||
[pattern_trace] 0
|
||||
|
||||
@@ -32,8 +32,8 @@ SRCS += ../src/tb_mips_top.vhd
|
||||
# Compile
|
||||
TARGET := tb_mips_top
|
||||
ENTITY := tb_mips_top
|
||||
RUN_TIME := 150us
|
||||
WAVE_FORMAT := ghw
|
||||
RUN_TIME ?= 250us
|
||||
WAVE_FORMAT ?= ghw
|
||||
|
||||
include $(VHDL_MAKE_HOME)/ghdl.mk
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
+399
-245
@@ -27,282 +27,426 @@ use IEEE.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
entity biu is
|
||||
Generic
|
||||
(
|
||||
ICACHE_SIZE : natural := 2048; -- words
|
||||
ICACHE_LINE : natural := 8; -- words
|
||||
DCACHE_SIZE : natural := 2048; -- words
|
||||
DCACHE_LINE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4; -- words
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
icache_size : natural := 2048; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 2048; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
busy : out STD_LOGIC;
|
||||
|
||||
imem_err : out STD_LOGIC;
|
||||
dmem_err : out STD_LOGIC;
|
||||
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out unsigned(31 downto 0);
|
||||
MDAT_I : in unsigned(31 downto 0);
|
||||
MDAT_O : out unsigned(31 downto 0);
|
||||
DAT_I : in unsigned(31 downto 0);
|
||||
DAT_O : out unsigned(31 downto 0);
|
||||
WE_O : out STD_LOGIC;
|
||||
SEL_O : out unsigned(3 downto 0);
|
||||
CYC_O : out STD_LOGIC;
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
|
||||
ctrl_in : in biu_ctrl_in_t;
|
||||
ctrl_out : out biu_ctrl_out_t
|
||||
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
cpu_imem_addr : in word_t;
|
||||
cpu_imem_din : out word_t;
|
||||
cpu_dmem_err : out STD_LOGIC;
|
||||
cpu_dmem_rdy : out STD_LOGIC;
|
||||
cpu_dmem_en : in STD_LOGIC;
|
||||
cpu_dmem_we : in STD_LOGIC;
|
||||
cpu_dmem_be : in unsigned(3 downto 0);
|
||||
cpu_dmem_dout : in word_t;
|
||||
cpu_dmem_din : out word_t;
|
||||
cpu_dmem_addr : in word_t
|
||||
);
|
||||
end biu;
|
||||
|
||||
architecture behavior of biu is
|
||||
|
||||
COMPONENT icache
|
||||
GENERIC
|
||||
(
|
||||
cache_size : natural; -- words
|
||||
line_size : natural -- words
|
||||
);
|
||||
PORT
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_addr : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT dcache
|
||||
GENERIC
|
||||
(
|
||||
cache_size : natural; -- words
|
||||
line_size : natural -- words
|
||||
);
|
||||
PORT
|
||||
(
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_we : in STD_LOGIC;
|
||||
cpu_be : in unsigned(3 downto 0);
|
||||
cpu_addr : in word_t;
|
||||
cpu_din : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
type bus_state_t is (init, ready, icache_bus_access, dcache_bus_access, write_bus, read_bus, read_finish);
|
||||
|
||||
signal s, sn : bus_state_t;
|
||||
signal bus_idle : std_logic;
|
||||
signal busy : std_logic;
|
||||
signal dmem_be : unsigned(3 downto 0);
|
||||
signal dcache_dout : word_t;
|
||||
signal dcache_mem_gnt : std_logic;
|
||||
signal icache_mem_gnt : std_logic;
|
||||
signal dmem_mem_wr_gnt : std_logic;
|
||||
signal dmem_mem_rd_gnt : std_logic;
|
||||
signal dcache_busy : std_logic;
|
||||
signal icache_busy : std_logic;
|
||||
signal CYC_O_icache : std_logic;
|
||||
signal CYC_O_dcache : std_logic;
|
||||
signal CYC_O_dmem_rd : std_logic;
|
||||
signal CYC_O_dmem_wr : std_logic;
|
||||
signal SRDY_I_icache : std_logic;
|
||||
signal SRDY_I_dcache : std_logic;
|
||||
signal MRDY_O_icache : std_logic;
|
||||
signal MRDY_O_dcache : std_logic;
|
||||
signal ADDR_O_icache : word_t;
|
||||
signal ADDR_O_dcache : word_t;
|
||||
signal ADDR_O_dmem_rd : word_t;
|
||||
signal ADDR_O_dmem_wr : word_t;
|
||||
signal STB_O_icache : std_logic;
|
||||
signal STB_O_dcache : std_logic;
|
||||
signal STB_O_dmem_rd : std_logic;
|
||||
signal STB_O_dmem_wr : std_logic;
|
||||
signal DAT_I_dmem_rd : word_t;
|
||||
signal DAT_O_dmem_wr : word_t;
|
||||
signal SEL_O_dmem_wr : unsigned(3 downto 0);
|
||||
signal SEL_O_dmem_rd : unsigned(3 downto 0);
|
||||
signal dcached : std_logic;
|
||||
signal dcache_en2 : std_logic;
|
||||
signal dcache_en : std_logic;
|
||||
signal uncached_access : std_logic;
|
||||
signal ACK : std_logic;
|
||||
signal DAT : unsigned(31 downto 0);
|
||||
|
||||
type timeout_cnt_t is range 0 to 1E5-1;
|
||||
signal bus_timeout_cnt : timeout_cnt_t;
|
||||
signal bus_timeout : std_logic;
|
||||
|
||||
-------------------------------------------------
|
||||
signal RST : std_logic;
|
||||
signal CPU_CLK : std_logic;
|
||||
signal bout_fifo_din : unsigned(68 downto 0);
|
||||
signal bout_fifo_dout : unsigned(68 downto 0);
|
||||
signal bout_fifo_re : std_logic;
|
||||
signal bout_fifo_we : std_logic;
|
||||
signal bout_fifo_full : std_logic;
|
||||
signal bout_fifo_empty : std_logic;
|
||||
signal bout_rdy : std_logic;
|
||||
|
||||
-- busmaster signals
|
||||
signal bus_din : word_t;
|
||||
signal bus_din_rdy : std_logic;
|
||||
signal bus_din_we : std_logic;
|
||||
signal bin_fifo_din : unsigned(31 downto 0);
|
||||
signal bin_fifo_dout : unsigned(31 downto 0);
|
||||
signal bin_fifo_re : std_logic;
|
||||
signal bin_fifo_we : std_logic;
|
||||
signal bin_fifo_full : std_logic;
|
||||
signal bin_fifo_empty : std_logic;
|
||||
|
||||
signal bus_dout : word_t;
|
||||
signal bus_dout_vld : std_logic;
|
||||
signal bus_dout_re : std_logic;
|
||||
alias bout_fifo_addr_in is bout_fifo_din(31 downto 0);
|
||||
alias bout_fifo_data_in is bout_fifo_din(63 downto 32);
|
||||
alias bout_fifo_sel_in is bout_fifo_din(67 downto 64);
|
||||
alias bout_fifo_we_in is bout_fifo_din(68);
|
||||
alias bout_fifo_addr_out is bout_fifo_dout(31 downto 0);
|
||||
alias bout_fifo_data_out is bout_fifo_dout(63 downto 32);
|
||||
alias bout_fifo_sel_out is bout_fifo_dout(67 downto 64);
|
||||
alias bout_fifo_we_out is bout_fifo_dout(68);
|
||||
|
||||
signal bus_cmd_rdy : std_logic;
|
||||
signal bus_cmd_we : std_logic;
|
||||
signal bus_cmd_cycle_en : std_logic;
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic;
|
||||
signal write_fifo_din : unsigned(67 downto 0);
|
||||
signal write_fifo_dout : unsigned(67 downto 0);
|
||||
signal write_fifo_re : std_logic;
|
||||
signal write_fifo_we : std_logic;
|
||||
signal write_fifo_full : std_logic;
|
||||
signal write_fifo_empty : std_logic;
|
||||
|
||||
signal i_bus_din_rdy : std_logic;
|
||||
signal i_bus_cmd_rdy : std_logic;
|
||||
signal i_bus_cmd_we : std_logic;
|
||||
signal i_bus_cmd_cycle_en : std_logic;
|
||||
signal i_bus_cmd : bm_cmd_t;
|
||||
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
||||
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
||||
alias write_fifo_sel_in is write_fifo_din(67 downto 64);
|
||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
||||
|
||||
signal i_tlb_rdy : std_logic;
|
||||
signal i_cache_rdy : std_logic;
|
||||
|
||||
signal d_bus_din_rdy : std_logic;
|
||||
signal d_bus_cmd_rdy : std_logic;
|
||||
signal d_bus_cmd_we : std_logic;
|
||||
signal d_bus_cmd_cycle_en : std_logic;
|
||||
signal d_bus_cmd : bm_cmd_t;
|
||||
|
||||
signal d_tlb_rdy : std_logic;
|
||||
signal d_cache_rdy : std_logic;
|
||||
|
||||
signal icache_bus_gnt : std_logic;
|
||||
signal dcache_bus_gnt : std_logic;
|
||||
signal read_cycle : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
CPU_CLK <= clk;
|
||||
RST <= RST_I;
|
||||
|
||||
biu_busy_state:
|
||||
process(clk)
|
||||
read_cyc_register:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
busy <= '1';
|
||||
elsif (i_tlb_rdy and i_cache_rdy and d_cache_rdy and d_tlb_rdy) = '1' then
|
||||
busy <= '0';
|
||||
read_cycle <= '0';
|
||||
else
|
||||
read_cycle <= (dmem_mem_rd_gnt and CYC_O_dmem_rd)
|
||||
or (dcache_mem_gnt and CYC_O_dcache)
|
||||
or (icache_mem_gnt and CYC_O_icache);
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MRDY_O <= not bin_fifo_full;
|
||||
CYC_O <= not bout_fifo_empty or read_cycle;
|
||||
STB_O <= not bout_fifo_empty;
|
||||
ADDR_O <= bout_fifo_addr_out;
|
||||
DAT_O <= bout_fifo_data_out;
|
||||
SEL_O <= bout_fifo_sel_out;
|
||||
WE_O <= bout_fifo_we_out;
|
||||
|
||||
inst_busmaster : entity work.busmaster_async
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => 32,
|
||||
FIFO_DEPTH => 16
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
|
||||
cmd_cycle_finished => bus_cyc_complete,
|
||||
cmd_cycle_en => bus_cmd_cycle_en,
|
||||
|
||||
cmd_rdy => bus_cmd_rdy,
|
||||
cmd_we => bus_cmd_we,
|
||||
cmd_in => bus_cmd,
|
||||
|
||||
din_rdy => bus_din_rdy,
|
||||
din_we => bus_din_we,
|
||||
din => bus_din,
|
||||
|
||||
dout => bus_dout,
|
||||
dout_vld => bus_dout_vld,
|
||||
dout_re => bus_dout_re,
|
||||
|
||||
-- JBUS Master signals
|
||||
RST_I => RST_I,
|
||||
CLK_I => CLK_I,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_i_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => i_tlb_rdy,
|
||||
|
||||
ctrl_in => ctrl_in.itlb_ctrl,
|
||||
ctrl_out => ctrl_out.itlb_ctrl,
|
||||
|
||||
query_in => ctrl_in.itlb_qry,
|
||||
query_out => ctrl_out.itlb_qry
|
||||
|
||||
);
|
||||
|
||||
inst_icache: entity work.icache
|
||||
GENERIC MAP
|
||||
(
|
||||
CACHE_SIZE => ICACHE_SIZE,
|
||||
LINE_SIZE => ICACHE_LINE
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
rdy => i_cache_rdy,
|
||||
|
||||
-- CPU control/data
|
||||
query_in => ctrl_in.icache_qry,
|
||||
query_out => ctrl_out.icache_qry,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => ctrl_in.icache,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_dout,
|
||||
bus_din_rdy => i_bus_din_rdy,
|
||||
bus_din_vld => bus_dout_vld,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => i_bus_cmd_rdy,
|
||||
bus_cmd_we => i_bus_cmd_we,
|
||||
bus_cmd_cycle_en => i_bus_cmd_cycle_en,
|
||||
bus_cmd_out => i_bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
cpu_imem_rdy <= not icache_busy;
|
||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_fifo_full);
|
||||
cpu_dmem_rdy <= not busy;
|
||||
|
||||
inst_d_tlb : entity work.tlb
|
||||
inst_icache : icache
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
cache_size => icache_size, -- words
|
||||
line_size => icache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => cpu_clk,
|
||||
RST_I => RST_I,
|
||||
STB_O => STB_O_icache,
|
||||
CYC_O => CYC_O_icache,
|
||||
ADDR_O => ADDR_O_icache,
|
||||
MRDY_O => MRDY_O_icache,
|
||||
DAT_I => DAT,
|
||||
ACK_I => ACK,
|
||||
SRDY_I => SRDY_I_icache,
|
||||
ctrl => cop0_ctrl_in.icache,
|
||||
cpu_en => cpu_imem_en,
|
||||
cpu_addr => cpu_imem_addr,
|
||||
cpu_dout => cpu_imem_din,
|
||||
cpu_busy => icache_busy
|
||||
);
|
||||
|
||||
SRDY_I_icache <= bout_rdy and icache_mem_gnt;
|
||||
|
||||
inst_dcache : dcache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => dcache_size, -- words
|
||||
line_size => dcache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => d_tlb_rdy,
|
||||
|
||||
ctrl_in => ctrl_in.dtlb_ctrl,
|
||||
ctrl_out => ctrl_out.dtlb_ctrl,
|
||||
|
||||
query_in => ctrl_in.dtlb_qry,
|
||||
query_out => ctrl_out.dtlb_qry
|
||||
|
||||
CLK_I => cpu_clk,
|
||||
RST_I => RST_I,
|
||||
CYC_O => CYC_O_dcache,
|
||||
STB_O => STB_O_dcache,
|
||||
ADDR_O => ADDR_O_dcache,
|
||||
MRDY_O => MRDY_O_dcache,
|
||||
DAT_I => DAT,
|
||||
ACK_I => ACK,
|
||||
SRDY_I => SRDY_I_dcache,
|
||||
ctrl => cop0_ctrl_in.dcache,
|
||||
cpu_en => dcache_en,
|
||||
cpu_we => cpu_dmem_we,
|
||||
cpu_be => cpu_dmem_be,
|
||||
cpu_addr => cpu_dmem_addr,
|
||||
cpu_din => cpu_dmem_dout,
|
||||
cpu_dout => dcache_dout,
|
||||
cpu_busy => dcache_busy
|
||||
);
|
||||
|
||||
inst_dcache: entity work.dcache
|
||||
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
||||
|
||||
dcached <= '1' when cpu_dmem_addr(31 downto 29) /= "101" else '0';
|
||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_fifo_full);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bin_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
CACHE_SIZE => DCACHE_SIZE,
|
||||
LINE_SIZE => DCACHE_LINE,
|
||||
WRITE_FIFO_SIZE => WRITE_FIFO_SIZE
|
||||
addr_width => 4,
|
||||
data_width => 32,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
rdy => d_cache_rdy,
|
||||
rst => RST_I,
|
||||
clk_w => CLK_I,
|
||||
clk_r => cpu_clk,
|
||||
we => bin_fifo_we,
|
||||
re => bin_fifo_re,
|
||||
fifo_full => bin_fifo_full,
|
||||
fifo_empty => bin_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => bin_fifo_din,
|
||||
data_r => bin_fifo_dout
|
||||
);
|
||||
|
||||
bin_fifo_din <= DAT_I;
|
||||
DAT <= bin_fifo_dout;
|
||||
ACK <= not bin_fifo_empty;
|
||||
bin_fifo_we <= ACK_I;
|
||||
bin_fifo_re <= dmem_mem_rd_gnt or MRDY_O_icache or MRDY_O_dcache;
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bout_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 69,
|
||||
do_last_read_update => false,
|
||||
add_extra_read_register => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => cpu_clk,
|
||||
clk_r => CLK_I,
|
||||
we => bout_fifo_we,
|
||||
re => bout_fifo_re,
|
||||
fifo_full => bout_fifo_full,
|
||||
fifo_empty => bout_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => bout_fifo_din,
|
||||
data_r => bout_fifo_dout
|
||||
);
|
||||
bout_rdy <= not bout_fifo_full;
|
||||
bout_fifo_re <= SRDY_I and not bin_fifo_full;
|
||||
|
||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
||||
|
||||
-- CPU control/data
|
||||
query_in => ctrl_in.dcache_qry,
|
||||
query_out => ctrl_out.dcache_qry,
|
||||
bout_fifo_data_in <= DAT_O_dmem_wr when dmem_mem_wr_gnt = '1' else (others => '-');
|
||||
|
||||
bout_fifo_addr_in <= ADDR_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
||||
ADDR_O_dmem_rd when dmem_mem_rd_gnt = '1' else
|
||||
ADDR_O_dcache when dcache_mem_gnt = '1' else
|
||||
ADDR_O_icache when icache_mem_gnt = '1' else (others => '-');
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => ctrl_in.dcache,
|
||||
bout_fifo_sel_in <= SEL_O_dmem_wr when dmem_mem_wr_gnt = '1' else
|
||||
SEL_O_dmem_rd when dmem_mem_rd_gnt = '1' else (others => '1');
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_dout,
|
||||
bus_din_rdy => d_bus_din_rdy,
|
||||
bus_din_vld => bus_dout_vld,
|
||||
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
|
||||
|
||||
bus_dout => bus_din,
|
||||
bus_dout_vld => bus_din_we,
|
||||
bus_dout_rdy => bus_din_rdy,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => d_bus_cmd_rdy,
|
||||
bus_cmd_we => d_bus_cmd_we,
|
||||
bus_cmd_cycle_en => d_bus_cmd_cycle_en,
|
||||
bus_cmd_out => d_bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_write_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 68,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => cpu_clk,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_fifo_full,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => write_fifo_din,
|
||||
data_r => write_fifo_dout
|
||||
);
|
||||
|
||||
CYC_O_dmem_wr <= not write_fifo_empty;
|
||||
DAT_O_dmem_wr <= write_fifo_data_out;
|
||||
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
||||
SEL_O_dmem_wr <= write_fifo_sel_out;
|
||||
|
||||
bus_state_next:
|
||||
process(clk)
|
||||
write_fifo_data_in <= cpu_dmem_dout;
|
||||
write_fifo_addr_in <= cpu_dmem_addr;
|
||||
write_fifo_sel_in <= cpu_dmem_be;
|
||||
write_fifo_re <= STB_O_dmem_wr;
|
||||
write_fifo_we <= cpu_dmem_en and not busy and cpu_dmem_we;
|
||||
|
||||
dmem_rd_flags:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(cpu_clk) then
|
||||
uncached_access <= '0';
|
||||
if RST_I = '1' then
|
||||
CYC_O_dmem_rd <= '0';
|
||||
dcache_en2 <= '1';
|
||||
else
|
||||
if ACK = '1' and dmem_mem_rd_gnt = '1' then
|
||||
uncached_access <= '1';
|
||||
CYC_O_dmem_rd <= '0';
|
||||
dcache_en2 <= '1';
|
||||
end if;
|
||||
if cpu_dmem_en = '1' and busy = '0' and cpu_dmem_we = '0' then
|
||||
if dcached = '0' then
|
||||
CYC_O_dmem_rd <= '1';
|
||||
dcache_en2 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dmem_rd_data:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
DAT_I_dmem_rd <= (others => '0');
|
||||
elsif ACK = '1' and CYC_O_dmem_rd = '1' then
|
||||
DAT_I_dmem_rd <= DAT;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dmem_rd_regs:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if cpu_dmem_en = '1' and busy = '0' then
|
||||
ADDR_O_dmem_rd <= cpu_dmem_addr;
|
||||
SEL_O_dmem_rd <= cpu_dmem_be;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state_next:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
@@ -312,51 +456,61 @@ bus_state_next:
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, i_bus_cmd_cycle_en, d_bus_cmd_cycle_en, i_bus_cmd_we, i_bus_cmd, d_bus_cmd_we, d_bus_cmd, bus_cyc_complete, i_bus_din_rdy, d_bus_din_rdy, bus_cmd_rdy)
|
||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
|
||||
begin
|
||||
|
||||
icache_bus_gnt <= '0';
|
||||
dcache_bus_gnt <= '0';
|
||||
|
||||
i_bus_cmd_rdy <= '0';
|
||||
d_bus_cmd_rdy <= '0';
|
||||
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
bus_cmd <= i_bus_cmd;
|
||||
bus_dout_re <= '0';
|
||||
icache_mem_gnt <= '0';
|
||||
dcache_mem_gnt <= '0';
|
||||
dmem_mem_rd_gnt <= '0';
|
||||
dmem_mem_wr_gnt <= '0';
|
||||
STB_O_dmem_rd <= '0';
|
||||
STB_O_dmem_wr <= '0';
|
||||
bus_idle <= '0';
|
||||
|
||||
sn <= s;
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
bus_idle <= '1';
|
||||
if i_bus_cmd_cycle_en = '1' then
|
||||
if CYC_O_dmem_wr = '1' then
|
||||
sn <= write_bus;
|
||||
elsif CYC_O_dmem_rd = '1' then
|
||||
sn <= read_bus;
|
||||
elsif CYC_O_icache = '1' then
|
||||
sn <= icache_bus_access;
|
||||
elsif d_bus_cmd_cycle_en = '1' then
|
||||
elsif CYC_O_dcache = '1' then
|
||||
sn <= dcache_bus_access;
|
||||
end if;
|
||||
when icache_bus_access =>
|
||||
icache_bus_gnt <= '1';
|
||||
i_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= i_bus_cmd_cycle_en;
|
||||
bus_cmd_we <= i_bus_cmd_we;
|
||||
bus_dout_re <= i_bus_din_rdy;
|
||||
if i_bus_cmd_cycle_en = '0' then
|
||||
icache_mem_gnt <= '1';
|
||||
if CYC_O_icache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when dcache_bus_access =>
|
||||
dcache_bus_gnt <= '1';
|
||||
d_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= d_bus_cmd_cycle_en;
|
||||
bus_cmd <= d_bus_cmd;
|
||||
bus_cmd_we <= d_bus_cmd_we;
|
||||
bus_dout_re <= d_bus_din_rdy;
|
||||
if d_bus_cmd_cycle_en = '0' then
|
||||
dcache_mem_gnt <= '1';
|
||||
if CYC_O_dcache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when write_bus =>
|
||||
dmem_mem_wr_gnt <= '1';
|
||||
if CYC_O_dmem_wr = '1' then
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_wr <= '1';
|
||||
end if;
|
||||
else
|
||||
sn <= ready;
|
||||
end if;
|
||||
when read_bus =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_rd <= '1';
|
||||
sn <= read_finish;
|
||||
end if;
|
||||
when read_finish =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if ACK = '1' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
@@ -364,9 +518,9 @@ bus_state:
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(clk)
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(cpu_clk) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
@@ -381,15 +535,15 @@ bus_timeout_counter:
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(clk)
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
imem_err <= '0';
|
||||
dmem_err <= '0';
|
||||
cpu_imem_err <= '0';
|
||||
cpu_dmem_err <= '0';
|
||||
elsif bus_timeout = '1' then
|
||||
imem_err <= icache_bus_gnt;
|
||||
dmem_err <= dcache_bus_gnt;
|
||||
cpu_imem_err <= icache_mem_gnt;
|
||||
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.MATH_REAL.ALL;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
ENTITY cam IS
|
||||
Generic
|
||||
(
|
||||
NUM_ENTRIES : natural := 32;
|
||||
DATA_WIDTH : natural := 20;
|
||||
CAM_RAM_MAX_WIDTH : natural := 15
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
clk_rd : in STD_LOGIC;
|
||||
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
re : in STD_LOGIC;
|
||||
we : in STD_LOGIC;
|
||||
vld : in STD_LOGIC;
|
||||
addr : in unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||
tag_wr : in unsigned (DATA_WIDTH-1 downto 0);
|
||||
|
||||
tag_rd : in unsigned (DATA_WIDTH-1 downto 0);
|
||||
hit : out unsigned (NUM_ENTRIES-1 downto 0);
|
||||
hit_vld : out STD_LOGIC
|
||||
|
||||
);
|
||||
END cam;
|
||||
|
||||
ARCHITECTURE behavior OF cam IS
|
||||
|
||||
type debug_t is record
|
||||
num_cam_rams : integer;
|
||||
cam_ram_data_width : integer;
|
||||
cam_ram_addr_width : integer;
|
||||
end record;
|
||||
|
||||
signal debug : debug_t;
|
||||
|
||||
constant NUM_BLOCKS : integer := integer(real(DATA_WIDTH)/real(CAM_RAM_MAX_WIDTH-lg2(NUM_ENTRIES)));
|
||||
constant BLOCK_ADDR_WIDTH : integer := CAM_RAM_MAX_WIDTH - lg2(NUM_ENTRIES);
|
||||
|
||||
type state_t is (init, ready, clear);
|
||||
signal state : state_t;
|
||||
signal state_next : state_t;
|
||||
|
||||
type pipe_stage_t is record
|
||||
re : std_logic;
|
||||
we : std_logic;
|
||||
vld : std_logic;
|
||||
addr : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||
data : unsigned (DATA_WIDTH-1 downto 0);
|
||||
vld_cam : unsigned (NUM_ENTRIES-1 downto 0);
|
||||
end record;
|
||||
|
||||
signal pipe0 : pipe_stage_t;
|
||||
signal pipe1 : pipe_stage_t;
|
||||
signal pipe2 : pipe_stage_t;
|
||||
signal pipe3 : pipe_stage_t;
|
||||
signal pipe0_rd : pipe_stage_t;
|
||||
signal pipe1_rd : pipe_stage_t;
|
||||
signal pipe2_rd : pipe_stage_t;
|
||||
signal pipe3_rd : pipe_stage_t;
|
||||
signal busy : std_logic;
|
||||
signal vld_cam : unsigned (NUM_ENTRIES-1 downto 0);
|
||||
|
||||
signal cam_ram_re : std_logic;
|
||||
signal cam_ram_we : std_logic;
|
||||
|
||||
type cam_ram_array_t is array (0 to NUM_BLOCKS-1) of unsigned (NUM_ENTRIES-1 downto 0);
|
||||
signal cam_ram_din : cam_ram_array_t;
|
||||
signal cam_ram_dout : cam_ram_array_t;
|
||||
signal cam_ram_result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||
|
||||
signal cam_ram_addr_wr : unsigned (DATA_WIDTH-1 downto 0);
|
||||
signal cam_ram_addr_rd : unsigned (DATA_WIDTH-1 downto 0);
|
||||
|
||||
signal track_ram_re : std_logic;
|
||||
signal track_ram_we : std_logic;
|
||||
signal track_ram_addr_wr : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||
signal track_ram_addr_rd : unsigned (lg2(NUM_ENTRIES)-1 downto 0);
|
||||
signal track_ram_din : unsigned (DATA_WIDTH downto 0);
|
||||
signal track_ram_dout : unsigned (DATA_WIDTH downto 0);
|
||||
|
||||
signal clear_data : unsigned (DATA_WIDTH-1 downto 0);
|
||||
signal clear_addr : unsigned (BLOCK_ADDR_WIDTH-1 downto 0);
|
||||
signal clear_count_en : std_logic;
|
||||
signal clear_count_rdy : std_logic;
|
||||
signal over_write : std_logic;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
over_write <= track_ram_dout(DATA_WIDTH) and pipe1.we;
|
||||
rdy <= not busy;
|
||||
hit_vld <= pipe1.re;
|
||||
|
||||
debug.num_cam_rams <= NUM_BLOCKS;
|
||||
debug.cam_ram_addr_width <= BLOCK_ADDR_WIDTH;
|
||||
debug.cam_ram_data_width <= NUM_ENTRIES;
|
||||
|
||||
track_ram_re <= '1';
|
||||
track_ram_we <= clear_count_en or pipe1.we;
|
||||
track_ram_addr_rd <= pipe0.addr;
|
||||
track_ram_addr_wr <= clear_data(lg2(NUM_ENTRIES)-1 downto 0) when clear_count_en = '1' else pipe1.addr;
|
||||
track_ram_din <= (others => '0') when clear_count_en = '1' else (pipe1.vld & pipe1.data);
|
||||
|
||||
cam_ram_re <= re when pipe1_rd.we = '0' else not busy;
|
||||
cam_ram_we <= clear_count_en or (pipe2.we and pipe2.vld) or over_write;
|
||||
cam_ram_addr_rd <= tag_rd when pipe1_rd.we = '0' else pipe1_rd.data; -- clk_rd same edge of clk
|
||||
-- cam_ram_addr_rd <= tag_rd when pipe2_rd.we = '0' else pipe2_rd.data; -- clk_rd opposite edge of clk
|
||||
cam_ram_addr_wr <= clear_data when clear_count_en = '1' else track_ram_dout(DATA_WIDTH-1 downto 0) when over_write = '1' else pipe2.data;
|
||||
|
||||
combine_cam_ram_din:
|
||||
process(clear_count_en, over_write, pipe2, cam_ram_dout)
|
||||
begin
|
||||
for i in 0 to NUM_BLOCKS-1 loop
|
||||
if clear_count_en = '1' or over_write = '1' then
|
||||
cam_ram_din(i) <= (others => '0');
|
||||
else
|
||||
cam_ram_din(i) <= (((NUM_ENTRIES-1 downto 0 => pipe2.vld) and pipe2.vld_cam) xor cam_ram_dout(i));
|
||||
end if;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
combine_clear_addr:
|
||||
process(clear_addr)
|
||||
begin
|
||||
for i in 0 to NUM_BLOCKS-1 loop
|
||||
clear_data((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH) <= clear_addr;
|
||||
end loop;
|
||||
end process;
|
||||
|
||||
combine_cam_ram_result:
|
||||
process(cam_ram_dout)
|
||||
variable result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||
begin
|
||||
result := (others => '0');
|
||||
|
||||
for i in 0 to NUM_BLOCKS-1 loop
|
||||
result := result or cam_ram_dout(i);
|
||||
end loop;
|
||||
|
||||
cam_ram_result <= result;
|
||||
end process;
|
||||
|
||||
pipe0.re <= re and not busy;
|
||||
pipe0.vld <= vld;
|
||||
pipe0.we <= we and not busy;
|
||||
pipe0.addr <= addr;
|
||||
pipe0.data <= tag_wr;
|
||||
pipe0.vld_cam <= vld_cam;
|
||||
|
||||
pipe_line_wr:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
pipe3.we <= '0';
|
||||
pipe2.we <= '0';
|
||||
pipe1.we <= '0';
|
||||
else
|
||||
pipe3 <= pipe2;
|
||||
pipe2 <= pipe1;
|
||||
pipe1 <= pipe0;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
pipe0_rd <= pipe0;
|
||||
pipe_line_rd:
|
||||
process(clk_rd)
|
||||
begin
|
||||
if rising_edge(clk_rd) then
|
||||
if rst = '1' then
|
||||
pipe3_rd.we <= '0';
|
||||
pipe2_rd.we <= '0';
|
||||
pipe1_rd.we <= '0';
|
||||
else
|
||||
pipe3_rd <= pipe2_rd;
|
||||
pipe2_rd <= pipe1_rd;
|
||||
pipe1_rd <= pipe0_rd;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
combine_cam_hit:
|
||||
process(cam_ram_dout, clear_count_en)
|
||||
variable result : unsigned (NUM_ENTRIES-1 downto 0);
|
||||
begin
|
||||
result := (others => not clear_count_en);
|
||||
|
||||
for i in 0 to NUM_BLOCKS-1 loop
|
||||
result := result and cam_ram_dout(i);
|
||||
end loop;
|
||||
|
||||
hit <= result;
|
||||
end process;
|
||||
|
||||
vld_decode:
|
||||
process(vld, addr)
|
||||
begin
|
||||
vld_cam <= (others => '0');
|
||||
vld_cam(to_integer(addr)) <= vld;
|
||||
end process;
|
||||
|
||||
|
||||
inst_track_ram: entity work.dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(NUM_ENTRIES),
|
||||
data_width => DATA_WIDTH+1
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
we_a => track_ram_we,
|
||||
re_b => '1',
|
||||
addr_a => track_ram_addr_wr,
|
||||
addr_b => track_ram_addr_rd,
|
||||
din_a => track_ram_din,
|
||||
dout_b => track_ram_dout
|
||||
);
|
||||
|
||||
gen_cam_ram:
|
||||
for i in 0 to NUM_BLOCKS-1 generate
|
||||
|
||||
inst_cam_ram: entity work.dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => BLOCK_ADDR_WIDTH,
|
||||
data_width => NUM_ENTRIES
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk_rd,
|
||||
we_a => cam_ram_we,
|
||||
re_b => cam_ram_re,
|
||||
addr_a => cam_ram_addr_wr((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH),
|
||||
addr_b => cam_ram_addr_rd((i+1)*BLOCK_ADDR_WIDTH-1 downto i*BLOCK_ADDR_WIDTH),
|
||||
din_a => cam_ram_din(i),
|
||||
dout_b => cam_ram_dout(i)
|
||||
);
|
||||
|
||||
end generate;
|
||||
|
||||
cam_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
state <= init;
|
||||
else
|
||||
state <= state_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cam_state:
|
||||
process(state, clear_count_rdy, over_write)
|
||||
begin
|
||||
busy <= over_write;
|
||||
clear_count_en <= '0';
|
||||
|
||||
state_next <= state;
|
||||
|
||||
case state is
|
||||
|
||||
when init =>
|
||||
busy <= '1';
|
||||
state_next <= clear;
|
||||
|
||||
when clear =>
|
||||
busy <= '1';
|
||||
clear_count_en <= '1';
|
||||
if clear_count_rdy = '1' then
|
||||
state_next <= ready;
|
||||
end if;
|
||||
|
||||
when ready =>
|
||||
|
||||
when others =>
|
||||
state_next <= ready;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
clear_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if clear_count_en = '0' then
|
||||
clear_count_rdy <= '0';
|
||||
clear_addr <= (BLOCK_ADDR_WIDTH-1 downto 0 => '1');
|
||||
else
|
||||
if clear_addr /= (BLOCK_ADDR_WIDTH-1 downto 0 => '0') then
|
||||
clear_addr <= clear_addr - 1;
|
||||
else
|
||||
clear_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
end behavior;
|
||||
+282
-600
File diff suppressed because it is too large
Load Diff
@@ -26,46 +26,33 @@ USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY dcache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4
|
||||
cache_size : natural := 2048; -- words
|
||||
line_size : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in dcache_query_in_t;
|
||||
query_out : out dcache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
bus_dout : out word_t;
|
||||
bus_dout_vld : out std_logic;
|
||||
bus_dout_rdy : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_we : in STD_LOGIC;
|
||||
cpu_be : in unsigned(3 downto 0);
|
||||
cpu_addr : in word_t;
|
||||
cpu_din : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END dcache;
|
||||
|
||||
@@ -96,26 +83,27 @@ COMPONENT dpram_2w2r2c_ra is
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES)+1;
|
||||
constant word_index_width : natural := lg2(line_size);
|
||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
||||
constant tag_parity_width : natural := 3;
|
||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type dcache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
idx : unsigned(lg2(TLB_NUM_ENTRIES) downto 0);
|
||||
valid : std_logic;
|
||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
end record;
|
||||
|
||||
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
||||
variable result : dcache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.idx := x(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1);
|
||||
result.tv_p := x(3 downto 1);
|
||||
result.tag := x(tag_width+3 downto 4);
|
||||
|
||||
return result;
|
||||
end to_dcache_entry;
|
||||
@@ -123,314 +111,170 @@ END COMPONENT;
|
||||
function to_tag_ram_data(x : dcache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1) := x.idx;
|
||||
result(0) := x.valid;
|
||||
result(3 downto 1) := x.tv_p;
|
||||
result(tag_width+3 downto 4) := x.tag;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
type cache_state_t is (init, ready, invalidate_init, invalidate, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
|
||||
function to_cache_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(cache_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_cache_index;
|
||||
|
||||
function to_tag(x : word_t) return unsigned is
|
||||
variable result : unsigned(tag_width-1 downto 0);
|
||||
begin
|
||||
result := x(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_tag;
|
||||
|
||||
|
||||
type cache_busy_state_t is (init, ready, busy);
|
||||
signal cache_busy_state, cache_busy_state_next : cache_busy_state_t;
|
||||
|
||||
type cache_ctrl_state_t is (init, ready, invalidate, invalidate_post, flush, bus_request, mem_read, mem_read_single, mem_read_data, mem_read_data_single, rd_cache, upd_cache, wait_write_thru);
|
||||
signal cache_ctrl_state, cache_ctrl_state_next : cache_ctrl_state_t;
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
type debug_t is record
|
||||
ready : std_logic;
|
||||
req_strobe : std_logic;
|
||||
req_read : std_logic;
|
||||
req_write : std_logic;
|
||||
req_va : word_t;
|
||||
req_pa : word_t;
|
||||
dout_reg : word_t;
|
||||
din_reg : word_t;
|
||||
end record;
|
||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||
|
||||
signal debug : debug_t;
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal req_strobe : std_logic;
|
||||
signal cache_req : std_logic;
|
||||
signal cache_req_rd : std_logic;
|
||||
signal cache_req_wr : std_logic;
|
||||
signal cache_rdy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal read_rdy : std_logic;
|
||||
signal write_rdy : std_logic;
|
||||
signal request_va : word_t;
|
||||
signal request_pa : word_t;
|
||||
signal request_nc : std_logic;
|
||||
signal cache_entry_in : dcache_entry_t;
|
||||
signal cache_entry_out : dcache_entry_t;
|
||||
signal cache_entry_out_inv : dcache_entry_t;
|
||||
signal cpu_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal cpu_data_ram_dout : word_t;
|
||||
signal cpu_data_reg : word_t;
|
||||
signal cpu_be_reg : unsigned(3 downto 0);
|
||||
signal cpu_we_reg : std_logic;
|
||||
signal ctrl_data_ram_addr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_data_ram_we : unsigned(3 downto 0);
|
||||
signal cpu_we2 : std_logic;
|
||||
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal mem_fetch_req : std_logic;
|
||||
signal mem_fetch_ack : std_logic;
|
||||
signal single_read_en : std_logic;
|
||||
signal single_read_set : std_logic;
|
||||
signal single_read_reg_vld : std_logic;
|
||||
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_dout : tag_ram_data_t;
|
||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_din : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal cache_entry_in : dcache_entry_t;
|
||||
signal cache_entry_out : dcache_entry_t;
|
||||
signal cache_entry_out_inv : dcache_entry_t;
|
||||
signal data_ram_addr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_dout : word_t;
|
||||
signal din_reg : word_t;
|
||||
signal be_reg : unsigned(3 downto 0);
|
||||
signal ctrl_data_ram_addr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal ctrl_data_ram_we : unsigned(3 downto 0);
|
||||
signal data_ram_we : unsigned(3 downto 0);
|
||||
signal single_read_reg : word_t;
|
||||
signal cache_dout : word_t;
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_load_en : std_logic;
|
||||
signal flush_addr_preset : unsigned(cache_index_width-1 downto 0);
|
||||
signal flush_count_preset : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_addr : unsigned(cache_index_width-1 downto 0);
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_dout : tag_ram_data_t;
|
||||
signal tag_ram_dout_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_din : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
signal DAT_I_r : word_t;
|
||||
signal ACK_I_r : std_logic;
|
||||
|
||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
signal write_hit : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
signal ram_write_en : std_logic;
|
||||
signal fill_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal req_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal hit_cache_index : unsigned(cache_index_width-1 downto 0);
|
||||
|
||||
signal write_fifo_din : unsigned(67 downto 0);
|
||||
signal write_fifo_dout : unsigned(67 downto 0);
|
||||
signal write_fifo_re : std_logic;
|
||||
signal write_fifo_we : std_logic;
|
||||
signal write_fifo_full : std_logic;
|
||||
signal write_fifo_empty : std_logic;
|
||||
signal write_data_avail : std_logic;
|
||||
signal read_write_buffer : std_logic;
|
||||
|
||||
alias write_fifo_addr_in is write_fifo_din(31 downto 0);
|
||||
alias write_fifo_data_in is write_fifo_din(63 downto 32);
|
||||
alias write_fifo_sel_in is write_fifo_din(67 downto 64);
|
||||
alias write_fifo_addr_out is write_fifo_dout(31 downto 0);
|
||||
alias write_fifo_data_out is write_fifo_dout(63 downto 32);
|
||||
alias write_fifo_sel_out is write_fifo_dout(67 downto 64);
|
||||
|
||||
signal write_through_en : std_logic;
|
||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
begin
|
||||
|
||||
-- Print info
|
||||
assert false report "addr_width = " & natural'image(addr_width) & "." severity note;
|
||||
assert false report "tag_width = " & natural'image(tag_width) & "." severity note;
|
||||
assert false report "word_index_width = " & natural'image(word_index_width) & "." severity note;
|
||||
assert false report "cache_index_width = " & natural'image(cache_index_width) & "." severity note;
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
cache_index_inv <= ctrl_in.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl_in.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
bus_din_rdy <= fill_count_en or single_read_en;
|
||||
bus_cmd_out.addr <= write_fifo_addr_out when read_write_buffer = '1' else to_tag(request_pa) & to_cache_index(request_pa) & req_word_index & "00";
|
||||
bus_cmd_out.rw <= read_write_buffer;
|
||||
bus_cmd_out.sel <= write_fifo_sel_out when read_write_buffer = '1' else (others => '1');
|
||||
bus_dout <= write_fifo_data_out;
|
||||
bus_dout_vld <= read_write_buffer and write_data_avail;
|
||||
|
||||
-- tlb_query_out.vld <= cache_req;
|
||||
-- tlb_query_out.vaddr <= request_va;
|
||||
-- tlb_query_out.write <= cache_req_wr;
|
||||
-- tlb_query_out.vld <= req_strobe;
|
||||
-- tlb_query_out.vaddr <= query_in.addr;
|
||||
-- tlb_query_out.idx <= cache_entry_out.idx;
|
||||
-- tlb_query_out.write <= query_in.we;
|
||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||
|
||||
request_pa <= request_va;
|
||||
|
||||
write_hit <= cache_req_wr and cache_hit; -- and not tlb_query_in.exc;
|
||||
|
||||
debug.req_strobe <= req_strobe;
|
||||
debug.req_read <= cache_req_rd;
|
||||
debug.req_write <= cache_req_wr;
|
||||
debug.req_va <= request_va;
|
||||
debug.req_pa <= request_pa;
|
||||
debug.din_reg <= din_reg;
|
||||
debug.dout_reg <= cache_dout;
|
||||
debug.ready <= cache_rdy;
|
||||
|
||||
-------------------------------------------------
|
||||
-- ctrl
|
||||
-------------------------------------------------
|
||||
req_strobe <= cache_rdy and query_in.en;
|
||||
|
||||
request_register:
|
||||
process(clk)
|
||||
data_in_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_req_rd <= '0';
|
||||
cache_req_wr <= '0';
|
||||
elsif cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en and not query_in.we;
|
||||
cache_req_wr <= query_in.en and query_in.we;
|
||||
cache_req <= query_in.en;
|
||||
if query_in.we = '1' then
|
||||
hit_cache_index <= to_cache_index(query_in.addr);
|
||||
end if;
|
||||
if rising_edge(CLK_I) then
|
||||
ACK_I_r <= ACK_I;
|
||||
if ACK_I = '1' then
|
||||
DAT_I_r <= DAT_I;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_address_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I_r = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
din_reg <= query_in.data;
|
||||
be_reg <= query_in.be;
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cpu_we_reg <= '0';
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cpu_we2 <= cpu_we;
|
||||
cache_req <= '1';
|
||||
cpu_data_reg <= cpu_din;
|
||||
cpu_be_reg <= cpu_be;
|
||||
cpu_we_reg <= cpu_we;
|
||||
if cpu_we = '1' then
|
||||
hit_cache_index <= cpu_cache_index;
|
||||
end if;
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
cpu_we2 <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instant_raw_logic:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
instant_raw <= '0';
|
||||
if to_word_index(query_in.addr) = fill_word_index and to_cache_index(query_in.addr) = hit_cache_index then
|
||||
instant_raw <= write_hit and query_in.en and not query_in.we;
|
||||
if cpu_word_index = fill_word_index and cpu_cache_index = hit_cache_index then
|
||||
instant_raw <= cpu_hit_we and cpu_en and not cpu_we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_write_fifo: entity work.fifo_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(WRITE_FIFO_SIZE),
|
||||
data_width => 68,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_fifo_full,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => write_fifo_din,
|
||||
data_r => write_fifo_dout
|
||||
);
|
||||
|
||||
write_fifo_data_in <= din_reg;
|
||||
write_fifo_addr_in <= request_pa;
|
||||
write_fifo_sel_in <= be_reg;
|
||||
write_fifo_re <= read_write_buffer and bus_dout_rdy and bus_cmd_rdy;
|
||||
write_fifo_we <= write_through_en;
|
||||
write_data_avail <= not write_fifo_empty;
|
||||
|
||||
fill_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
fill_word_index <= to_word_index(query_in.addr);
|
||||
elsif bus_din_vld = '1' and fill_count_en = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_request_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
req_word_index <= to_word_index(query_in.addr);
|
||||
elsif request_count_en = '1' and bus_cmd_rdy = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
single_read_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
elsif single_read_en = '0' then
|
||||
if single_read_set = '1' then
|
||||
single_read_en <= '1';
|
||||
end if;
|
||||
elsif single_read_reg_vld = '1' then
|
||||
if query_in.en = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
end if;
|
||||
elsif bus_din_vld = '1' and single_read_en = '1' then
|
||||
single_read_reg <= bus_din;
|
||||
single_read_reg_vld <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
@@ -439,10 +283,10 @@ inst_tag_ram : dpram_2w2r2c_ra
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
re_a => '1',
|
||||
re_b => ram_read_en,
|
||||
re_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
@@ -460,35 +304,35 @@ gen_data_ram:
|
||||
inst_data_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
re_a => '1',
|
||||
re_b => ram_read_en,
|
||||
we_a => data_ram_we(i),
|
||||
re_b => '1',
|
||||
we_a => cpu_data_ram_we(i),
|
||||
we_b => ctrl_data_ram_we(i),
|
||||
addr_a => ctrl_data_ram_addr,
|
||||
addr_b => data_ram_addr,
|
||||
din_a => din_reg(8*(i+1)-1 downto 8*i),
|
||||
din_b => bus_din(8*(i+1)-1 downto 8*i),
|
||||
addr_b => cpu_data_ram_addr,
|
||||
din_a => cpu_data_reg(8*(i+1)-1 downto 8*i),
|
||||
din_b => DAT_I_r(8*(i+1)-1 downto 8*i),
|
||||
dout_a => open,
|
||||
dout_b => data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
dout_b => cpu_data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl_in.inv_all or rst;
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
@@ -498,144 +342,102 @@ cache_invalidate_request:
|
||||
end process;
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_rdy <= read_rdy and not instant_raw and write_rdy;
|
||||
write_rdy <= not (write_fifo_full and cache_req_wr);
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else to_mips_01(data_ram_dout);
|
||||
query_out.data <= cache_dout;
|
||||
|
||||
-- tag_match <= '1' when to_tag(request_pa) = cache_entry_out.tag else '0';
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
|
||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else to_cache_index(request_va);
|
||||
tag_ram_addr_rd <= to_cache_index(query_in.addr) when (was_miss = '0' and instant_raw = '0') else to_cache_index(request_va);
|
||||
|
||||
cache_entry_out <= to_dcache_entry(to_mips_01(tag_ram_dout));
|
||||
cache_entry_out_inv <= to_dcache_entry(to_mips_01(tag_ram_dout_inv));
|
||||
|
||||
ram_read_en <= query_in.en or was_miss or fill_count_en;
|
||||
data_ram_addr <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (to_cache_index(request_va) & fill_word_index);
|
||||
ctrl_data_ram_addr <= to_cache_index(request_va) & fill_word_index;
|
||||
ctrl_data_ram_we <= (others => ram_write_en and bus_din_vld);
|
||||
data_ram_we <= be_reg when (write_hit = '1') else (others => '0');
|
||||
|
||||
write_through_en <= cache_rdy and cache_req_wr; -- and tlb_query_in.hit and not tlb_query_in.flags.D;
|
||||
MRDY_O <= fill_count_en;
|
||||
ADDR_O <= request_addr;
|
||||
|
||||
cache_busy_state_fsm:
|
||||
process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld)
|
||||
begin
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= cpu_data_ram_dout;
|
||||
|
||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= flush_addr when invalidate_en = '1' else fill_cache_index;
|
||||
tag_ram_addr_rd <= cpu_cache_index when (was_miss = '0' and instant_raw = '0') else fill_cache_index;
|
||||
|
||||
read_rdy <= '0';
|
||||
mem_fetch_req <= '0';
|
||||
single_read_set <= '0';
|
||||
cache_busy_state_next <= cache_busy_state;
|
||||
|
||||
case cache_busy_state is
|
||||
|
||||
when init =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if single_read_en = '1' then
|
||||
read_rdy <= single_read_reg_vld;
|
||||
else
|
||||
read_rdy <= '1';
|
||||
if cache_req_rd = '1' then
|
||||
-- if tlb_query_in.exc = '0' then
|
||||
if request_nc = '1' or cache_hit = '0' then
|
||||
-- mem_fetch_req <= '1';
|
||||
read_rdy <= '0';
|
||||
cache_busy_state_next <= busy;
|
||||
end if;
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when busy =>
|
||||
mem_fetch_req <= '1';
|
||||
if mem_fetch_ack = '1' then
|
||||
single_read_set <= request_nc;
|
||||
cache_busy_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
cache_ctrl_state_fsm:
|
||||
process(cache_ctrl_state, mem_fetch_req, request_nc, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, bus_din_vld, invalidate_req, invalidate_all, write_through_en, write_data_avail)
|
||||
cache_entry_out <= to_dcache_entry(tag_ram_dout);
|
||||
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
||||
|
||||
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (fill_cache_index & fill_word_index);
|
||||
ctrl_data_ram_addr <= fill_cache_index & fill_word_index;
|
||||
ctrl_data_ram_we <= (others => fill_count_en and ACK_I_r);
|
||||
cpu_data_ram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||
|
||||
cache_state:
|
||||
process(s, cache_req, instant_raw, cache_hit, cache_hit_inv, cache_index_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
|
||||
invalidate_en <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
read_write_buffer <= '0';
|
||||
|
||||
cache_entry_in.tag <= to_tag(request_pa);
|
||||
|
||||
flush_load_en <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_addr_preset <= (others=>'0'); -- all
|
||||
flush_count_preset <= 2**cache_index_width-1;
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_ctrl_state_next <= cache_ctrl_state;
|
||||
sn <= s;
|
||||
|
||||
case cache_ctrl_state is
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' or write_data_avail = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
elsif write_through_en = '1' then
|
||||
cache_ctrl_state_next <= wait_write_thru;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
sn <= invalidate_init;
|
||||
invalidate_en <= '1';
|
||||
flush_load_en <= '1';
|
||||
if invalidate_all = '1' then
|
||||
flush_addr_preset <= (others=>'0'); -- all
|
||||
flush_count_preset <= 2**cache_index_width-1;
|
||||
else
|
||||
flush_addr_preset <= cache_index_inv; -- at
|
||||
flush_count_preset <= 0;
|
||||
end if;
|
||||
else
|
||||
if cache_req = '1' then
|
||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= instant_raw;
|
||||
cache_ack <= not instant_raw;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
|
||||
when invalidate_init =>
|
||||
invalidate_en <= '1';
|
||||
sn <= invalidate;
|
||||
|
||||
when invalidate =>
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
cache_ctrl_state_next <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if cache_hit_inv = '1' or invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
@@ -645,106 +447,68 @@ cache_ctrl_state_fsm:
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when invalidate_post =>
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when wait_write_thru =>
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
if write_data_avail = '1' then
|
||||
read_write_buffer <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
else
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
end if;
|
||||
else
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
when mem_access =>
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
request_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when mem_read_data_single =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_din_vld = '1' then
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when rd_cache =>
|
||||
mem_fetch_ack <= '1';
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if flush_load_en = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= flush_count_preset;
|
||||
flush_addr <= flush_addr_preset;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
flush_addr <= flush_addr + 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
@@ -756,14 +520,14 @@ request_counter:
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if ACK_I_r = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: Types, constants and functions for JIPS
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package mips_func_pkg is
|
||||
|
||||
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned;
|
||||
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t;
|
||||
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned;
|
||||
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t;
|
||||
function events_clr return event_t;
|
||||
function event_is_active(e : event_t) return std_logic;
|
||||
function "or" (a, b : event_t) return event_t;
|
||||
|
||||
end mips_func_pkg;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package body mips_func_pkg is
|
||||
|
||||
function store_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||
variable stage1 : word_t;
|
||||
variable result : word_t;
|
||||
variable sa : unsigned(1 downto 0);
|
||||
begin
|
||||
|
||||
if bypass = '1' then
|
||||
sa := "00";
|
||||
else
|
||||
sa := va + shift_off;
|
||||
end if;
|
||||
|
||||
stage1 := x;
|
||||
if sa(0) = '1' then
|
||||
stage1 := x(23 downto 0) & x(31 downto 24);
|
||||
end if;
|
||||
result := stage1;
|
||||
if sa(1) = '1' then
|
||||
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||
end if;
|
||||
|
||||
return result;
|
||||
end store_shift;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function store_be(va : unsigned(1 downto 0); be_src, word2_en, word4_en, align_left, bypass : std_logic) return unsigned is
|
||||
variable result : unsigned(3 downto 0);
|
||||
begin
|
||||
result := (3 downto 0 => be_src);
|
||||
if bypass = '0' then
|
||||
if word2_en = '1' then
|
||||
case va is
|
||||
when "00" =>
|
||||
result := "00" & be_src & be_src;
|
||||
when "10" =>
|
||||
result := be_src & be_src & "00";
|
||||
when others => null;
|
||||
end case;
|
||||
elsif word4_en = '1' then
|
||||
case va is
|
||||
when "00" =>
|
||||
result := "000" & be_src;
|
||||
when "01" =>
|
||||
result := "00" & be_src & '0';
|
||||
when "10" =>
|
||||
result := '0' & be_src & "00";
|
||||
when "11" =>
|
||||
result := be_src & "000";
|
||||
when others => null;
|
||||
end case;
|
||||
elsif align_left = '1' then
|
||||
case va is
|
||||
when "00" =>
|
||||
result := be_src & be_src & be_src & be_src;
|
||||
when "01" =>
|
||||
result := be_src & be_src & be_src & '0';
|
||||
when "10" =>
|
||||
result := be_src & be_src & "00";
|
||||
when "11" =>
|
||||
result := be_src & "000";
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
case va is
|
||||
when "00" =>
|
||||
result := "000" & be_src;
|
||||
when "01" =>
|
||||
result := "00" & be_src & be_src;
|
||||
when "10" =>
|
||||
result := '0' & be_src & be_src & be_src;
|
||||
when "11" =>
|
||||
result := be_src & be_src & be_src & be_src;
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return result;
|
||||
|
||||
end store_be;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function load_shift(x : word_t; va, shift_off : unsigned(1 downto 0); bypass : std_logic) return word_t is
|
||||
variable stage1 : word_t;
|
||||
variable result : word_t;
|
||||
variable sa : unsigned(1 downto 0);
|
||||
|
||||
begin
|
||||
if bypass = '1' then
|
||||
sa := "00";
|
||||
else
|
||||
sa := va + shift_off;
|
||||
end if;
|
||||
|
||||
stage1 := x;
|
||||
if sa(0) = '1' then
|
||||
stage1 := x(7 downto 0) & x(31 downto 8);
|
||||
end if;
|
||||
result := stage1;
|
||||
if sa(1) = '1' then
|
||||
result := stage1(15 downto 0) & stage1(31 downto 16);
|
||||
end if;
|
||||
|
||||
return result;
|
||||
end load_shift;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function load_be(va : unsigned(1 downto 0); align_left, bypass : std_logic) return unsigned is
|
||||
variable result : unsigned(3 downto 0);
|
||||
begin
|
||||
result := (3 downto 0 => '1');
|
||||
if bypass = '0' then
|
||||
if align_left = '1' then
|
||||
case va is
|
||||
when "00" =>
|
||||
result := "1000";
|
||||
when "01" =>
|
||||
result := "1100";
|
||||
when "10" =>
|
||||
result := "1110";
|
||||
when "11" =>
|
||||
result := "1111";
|
||||
when others => null;
|
||||
end case;
|
||||
else
|
||||
case va is
|
||||
when "00" =>
|
||||
result := "1111";
|
||||
when "01" =>
|
||||
result := "0111";
|
||||
when "10" =>
|
||||
result := "0011";
|
||||
when "11" =>
|
||||
result := "0001";
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
return result;
|
||||
|
||||
end load_be;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function load_sign_ext(x : word_t; bypass, signed, word2_en, word4_en : std_logic) return word_t is
|
||||
variable result : word_t;
|
||||
variable sign : std_logic;
|
||||
|
||||
begin
|
||||
if bypass = '1' then
|
||||
result := x;
|
||||
elsif word2_en = '1' then
|
||||
sign := signed and x(15);
|
||||
result := (31 downto 16 => sign) & x(15 downto 0);
|
||||
else
|
||||
sign := signed and x(7);
|
||||
result := (31 downto 8 => sign) & x(7 downto 0);
|
||||
end if;
|
||||
|
||||
return result;
|
||||
end load_sign_ext;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function events_clr return event_t is
|
||||
variable result : event_t;
|
||||
begin
|
||||
result.NMI := '0';
|
||||
result.Int := '0';
|
||||
result.data_load_err := '0';
|
||||
result.data_store_err := '0';
|
||||
result.inst_load_err := '0';
|
||||
result.inst_priv_addr := '0';
|
||||
result.alu_ovf := '0';
|
||||
result.alu_uvf := '0';
|
||||
result.syscall := '0';
|
||||
result.break := '0';
|
||||
result.illegal := '0';
|
||||
|
||||
return result;
|
||||
|
||||
end events_clr;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function event_is_active(e : event_t) return std_logic is
|
||||
variable result : std_logic;
|
||||
begin
|
||||
result := '0';
|
||||
|
||||
result := result or e.NMI;
|
||||
result := result or e.Int;
|
||||
result := result or e.data_load_err;
|
||||
result := result or e.data_store_err;
|
||||
result := result or e.inst_load_err;
|
||||
result := result or e.inst_priv_addr;
|
||||
result := result or e.alu_ovf;
|
||||
result := result or e.alu_uvf;
|
||||
result := result or e.syscall;
|
||||
result := result or e.break;
|
||||
result := result or e.illegal;
|
||||
|
||||
return result;
|
||||
|
||||
end event_is_active;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function "or" (a, b : event_t) return event_t is
|
||||
variable result : event_t;
|
||||
begin
|
||||
result.NMI := a.NMI or b.NMI;
|
||||
result.Int := a.Int or b.Int;
|
||||
result.data_load_err := a.data_load_err or b.data_load_err;
|
||||
result.data_store_err := a.data_store_err or b.data_store_err;
|
||||
result.inst_load_err := a.inst_load_err or b.inst_load_err;
|
||||
result.inst_priv_addr := a.inst_priv_addr or b.inst_priv_addr;
|
||||
result.alu_ovf := a.alu_ovf or b.alu_ovf;
|
||||
result.alu_uvf := a.alu_uvf or b.alu_uvf;
|
||||
result.syscall := a.syscall or b.syscall;
|
||||
result.break := a.break or b.break;
|
||||
result.illegal := a.illegal or b.illegal;
|
||||
|
||||
return result;
|
||||
|
||||
end "or";
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end mips_func_pkg;
|
||||
|
||||
@@ -26,40 +26,30 @@ USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY icache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8 -- words
|
||||
cache_size : natural := 2048; -- words
|
||||
line_size : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in icache_query_in_t;
|
||||
query_out : out icache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
ADDR_O : out word_t;
|
||||
DAT_I : in word_t;
|
||||
STB_O : out STD_LOGIC;
|
||||
CYC_O : out STD_LOGIC;
|
||||
ctrl : in cache_ctrl_t;
|
||||
cpu_en : in STD_LOGIC;
|
||||
cpu_addr : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END icache;
|
||||
|
||||
@@ -75,7 +65,7 @@ COMPONENT dpram_1w1r2c_ra
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
re_b : in STD_LOGIC;
|
||||
re_b : in STD_LOGIC;
|
||||
addr_a : in unsigned (addr_width-1 downto 0);
|
||||
addr_b : in unsigned (addr_width-1 downto 0);
|
||||
din_a : in unsigned (data_width-1 downto 0);
|
||||
@@ -107,26 +97,27 @@ COMPONENT dpram_2w2r2c_ra is
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES);
|
||||
constant word_index_width : natural := lg2(line_size);
|
||||
constant cache_index_width : natural := lg2(cache_size) - word_index_width;
|
||||
constant tag_width : natural := addr_width - word_index_width - cache_index_width - 2;
|
||||
constant tag_parity_width : natural := 3;
|
||||
constant tag_ram_data_width : natural := 1 + tag_parity_width + tag_width;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type icache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
tlb_idx : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
valid : std_logic;
|
||||
tv_p : unsigned(tag_parity_width-1 downto 0);
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
end record;
|
||||
|
||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||
variable result : icache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.tlb_idx := x(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1);
|
||||
result.tv_p := x(3 downto 1);
|
||||
result.tag := x(tag_width+3 downto 4);
|
||||
|
||||
return result;
|
||||
end to_icache_entry;
|
||||
@@ -134,222 +125,150 @@ END COMPONENT;
|
||||
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1) := x.tlb_idx;
|
||||
result(0) := x.valid;
|
||||
result(3 downto 1) := x.tv_p;
|
||||
result(tag_width+3 downto 4) := x.tag;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
type cache_state_t is (init, ready, invalidate_init, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
|
||||
function to_cache_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(cache_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_cache_index;
|
||||
|
||||
function to_tag(x : word_t) return unsigned is
|
||||
variable result : unsigned(tag_width-1 downto 0);
|
||||
begin
|
||||
result := x(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_tag;
|
||||
|
||||
type cache_busy_state_t is (init, ready, busy);
|
||||
signal cache_busy_state, cache_busy_state_next : cache_busy_state_t;
|
||||
|
||||
type cache_ctrl_state_t is (init, ready, invalidate, invalidate_post, flush, bus_request, mem_read, mem_read_single, mem_read_data, mem_read_data_single, rd_cache, upd_cache);
|
||||
signal cache_ctrl_state, cache_ctrl_state_next : cache_ctrl_state_t;
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||
|
||||
type debug_t is record
|
||||
ready : std_logic;
|
||||
req_strobe : std_logic;
|
||||
req_read : std_logic;
|
||||
req_va : word_t;
|
||||
req_pa : word_t;
|
||||
dout_reg : word_t;
|
||||
end record;
|
||||
|
||||
signal debug : debug_t;
|
||||
|
||||
signal req_strobe : std_logic;
|
||||
signal cache_req_rd : std_logic;
|
||||
signal read_rdy : std_logic;
|
||||
signal cache_rdy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal request_va : word_t;
|
||||
signal request_pa : word_t;
|
||||
signal request_nc : std_logic;
|
||||
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
|
||||
signal mem_fetch_req : std_logic;
|
||||
signal mem_fetch_ack : std_logic;
|
||||
signal single_read_en : std_logic;
|
||||
signal single_read_set : std_logic;
|
||||
signal single_read_reg_vld : std_logic;
|
||||
signal cache_entry_in : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : icache_entry_t;
|
||||
signal data_ram_addr_rd : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal data_ram_data_rd : word_t;
|
||||
signal data_ram_addr_wr : unsigned(lg2(cache_size)-1 downto 0);
|
||||
signal data_ram_data_wr : word_t;
|
||||
signal data_ram_we : std_logic;
|
||||
signal data_ram_re : std_logic;
|
||||
|
||||
signal cache_index_inv : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_reg_inv : unsigned(tag_width-1 downto 0);
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_data_rd_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_wr : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
-- signal tag_ram_re : std_logic;
|
||||
|
||||
signal cache_entry_in : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : icache_entry_t;
|
||||
signal data_ram_addr_rd : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_rd : word_t;
|
||||
signal data_ram_addr_wr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_wr : word_t;
|
||||
signal data_ram_we : std_logic;
|
||||
signal single_read_reg : word_t;
|
||||
signal cache_dout : word_t;
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_load_en : std_logic;
|
||||
signal flush_addr_preset : unsigned(cache_index_width-1 downto 0);
|
||||
signal flush_count_preset : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_addr : unsigned(cache_index_width-1 downto 0);
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
signal tag_ram_addr_rd : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_data_rd_inv : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_wr : tag_ram_data_t;
|
||||
signal tag_ram_we : std_logic;
|
||||
signal DAT_I_r : word_t;
|
||||
signal ACK_I_r : std_logic;
|
||||
|
||||
alias cpu_word_index is cpu_addr(word_index_width+1 downto 2);
|
||||
alias cpu_cache_index is cpu_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias cpu_tag is cpu_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_rst : std_logic;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal ram_read_en : std_logic;
|
||||
signal ram_write_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
alias fill_word_index is fill_addr(word_index_width+1 downto 2);
|
||||
alias fill_cache_index is fill_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias fill_tag is fill_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
signal fill_word_index : unsigned(word_index_width-1 downto 0);
|
||||
signal req_word_index : unsigned(word_index_width-1 downto 0);
|
||||
alias req_word_index is request_addr(word_index_width+1 downto 2);
|
||||
alias req_cache_index is request_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
alias req_tag is request_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
begin
|
||||
|
||||
-- Print info
|
||||
assert false report "addr_width = " & natural'image(addr_width) & "." severity note;
|
||||
assert false report "tag_width = " & natural'image(tag_width) & "." severity note;
|
||||
assert false report "word_index_width = " & natural'image(word_index_width) & "." severity note;
|
||||
assert false report "cache_index_width = " & natural'image(cache_index_width) & "." severity note;
|
||||
cache_index_inv <= ctrl.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
-- tlb_query_out.vld <= cache_req_rd;
|
||||
-- tlb_query_out.vaddr <= request_va;
|
||||
-- tlb_query_out.write <= '0';
|
||||
-- tlb_query_out.vld <= req_strobe;
|
||||
-- tlb_query_out.vaddr <= query_in.addr;
|
||||
-- tlb_query_out.write <= '0';
|
||||
|
||||
cache_index_inv <= ctrl_in.inv_addr(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
tag_inv <= ctrl_in.inv_addr(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
request_pa <= request_va;
|
||||
|
||||
debug.req_strobe <= req_strobe;
|
||||
debug.req_read <= cache_req_rd;
|
||||
debug.req_va <= request_va;
|
||||
debug.req_pa <= request_pa;
|
||||
debug.dout_reg <= cache_dout;
|
||||
debug.ready <= cache_rdy;
|
||||
|
||||
-------------------------------------------------
|
||||
-- ctrl
|
||||
-------------------------------------------------
|
||||
req_strobe <= cache_rdy and query_in.en;
|
||||
|
||||
ctrl_request_register:
|
||||
process(clk)
|
||||
data_in_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en;
|
||||
if rising_edge(CLK_I) then
|
||||
ACK_I_r <= ACK_I;
|
||||
if ACK_I = '1' then
|
||||
DAT_I_r <= DAT_I;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------
|
||||
|
||||
fill_address_register:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
fill_word_index <= to_word_index(query_in.addr);
|
||||
elsif bus_din_vld = '1' and fill_count_en = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I_r = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_request_address_register:
|
||||
process(clk)
|
||||
request_address_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if req_strobe = '1' then
|
||||
req_word_index <= to_word_index(query_in.addr);
|
||||
elsif request_count_en = '1' and bus_cmd_rdy = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
req_word_index <= req_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
request_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
single_read_register:
|
||||
process(clk)
|
||||
cpu_request_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
elsif single_read_en = '0' then
|
||||
if single_read_set = '1' then
|
||||
single_read_en <= '1';
|
||||
end if;
|
||||
elsif single_read_reg_vld = '1' then
|
||||
if query_in.en = '1' then
|
||||
single_read_en <= '0';
|
||||
single_read_reg_vld <= '0';
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cache_req <= '1';
|
||||
end if;
|
||||
elsif bus_din_vld = '1' and single_read_en = '1' then
|
||||
single_read_reg <= bus_din;
|
||||
single_read_reg_vld <= '1';
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl_in.inv_all or rst;
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
@@ -366,12 +285,12 @@ inst_tag_ram : dpram_2w2r2c_ra
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
re_a => '1',
|
||||
re_b => ram_read_en,
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
re_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_data_wr,
|
||||
@@ -383,15 +302,15 @@ inst_tag_ram : dpram_2w2r2c_ra
|
||||
inst_data_ram : dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
re_b => data_ram_re,
|
||||
we_a => data_ram_we,
|
||||
re_b => ram_read_en,
|
||||
addr_a => data_ram_addr_wr,
|
||||
addr_b => data_ram_addr_rd,
|
||||
din_a => data_ram_data_wr,
|
||||
@@ -399,236 +318,172 @@ inst_data_ram : dpram_1w1r2c_ra
|
||||
);
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_din_rdy <= fill_count_en or single_read_en;
|
||||
bus_cmd_out.addr <= to_tag(request_pa) & to_cache_index(request_pa) & req_word_index & "00";
|
||||
bus_cmd_out.rw <= '0';
|
||||
bus_cmd_out.sel <= (others => '1');
|
||||
|
||||
cache_rdy <= read_rdy;
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
MRDY_O <= fill_count_en;
|
||||
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else data_ram_data_rd;
|
||||
query_out.data <= cache_dout;
|
||||
cpu_busy <= cache_busy;
|
||||
cpu_dout <= data_ram_data_rd;
|
||||
|
||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||
tag_match <= '1' when fill_tag = cache_entry_out.tag else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
cache_entry_out <= to_icache_entry(to_mips_01(tag_ram_data_rd));
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(to_mips_01(tag_ram_data_rd_inv));
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= flush_addr when invalidate_en = '1' else fill_cache_index;
|
||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else fill_cache_index;
|
||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (fill_cache_index & fill_word_index);
|
||||
data_ram_addr_wr <= fill_cache_index & fill_word_index;
|
||||
data_ram_data_wr <= DAT_I_r;
|
||||
data_ram_we <= fill_count_en and ACK_I_r;
|
||||
data_ram_re <= (cpu_en or was_miss) and not data_ram_we;
|
||||
-- tag_ram_re <= (cpu_en or was_miss) and not data_ram_we;
|
||||
|
||||
ram_read_en <= query_in.en or was_miss;
|
||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else to_cache_index(request_va);
|
||||
tag_ram_addr_rd <= to_cache_index(query_in.addr) when was_miss = '0' else to_cache_index(request_va);
|
||||
data_ram_addr_rd <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when was_miss = '0' else (to_cache_index(request_va) & fill_word_index);
|
||||
data_ram_addr_wr <= to_cache_index(request_va) & fill_word_index;
|
||||
data_ram_data_wr <= bus_din;
|
||||
data_ram_we <= ram_write_en and bus_din_vld;
|
||||
|
||||
cache_busy_state_fsm:
|
||||
process(cache_busy_state, request_nc, cache_req_rd, cache_hit, mem_fetch_ack, single_read_en, single_read_reg_vld)
|
||||
begin
|
||||
|
||||
read_rdy <= '0';
|
||||
mem_fetch_req <= '0';
|
||||
single_read_set <= '0';
|
||||
cache_busy_state_next <= cache_busy_state;
|
||||
|
||||
case cache_busy_state is
|
||||
|
||||
when init =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if single_read_en = '1' then
|
||||
read_rdy <= single_read_reg_vld;
|
||||
else
|
||||
read_rdy <= '1';
|
||||
if cache_req_rd = '1' then
|
||||
-- if tlb_query_in.exc = '0' then
|
||||
if request_nc = '1' or cache_hit = '0' then
|
||||
-- mem_fetch_req <= '1';
|
||||
read_rdy <= '0';
|
||||
single_read_set <= request_nc;
|
||||
cache_busy_state_next <= busy;
|
||||
end if;
|
||||
-- end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when busy =>
|
||||
mem_fetch_req <= '1';
|
||||
if mem_fetch_ack = '1' then
|
||||
cache_busy_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when others =>
|
||||
cache_busy_state_next <= ready;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
cache_ctrl_state_fsm:
|
||||
process(cache_ctrl_state, mem_fetch_req, request_nc, bus_din_vld, cache_hit_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, request_pa, bus_cmd_rdy, invalidate_req, invalidate_all)
|
||||
cache_state:
|
||||
process(s, cache_req, cache_hit, cache_hit_inv, cache_index_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
|
||||
invalidate_en <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
|
||||
flush_load_en <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_addr_preset <= (others=>'0'); -- all
|
||||
flush_count_preset <= 2**cache_index_width-1;
|
||||
|
||||
cache_entry_in.tag <= to_tag(request_pa);
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_ctrl_state_next <= cache_ctrl_state;
|
||||
sn <= s;
|
||||
|
||||
case cache_ctrl_state is
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
sn <= invalidate_init;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
end if;
|
||||
|
||||
when invalidate =>
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
cache_ctrl_state_next <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when invalidate_post =>
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
flush_load_en <= '1';
|
||||
if invalidate_all = '1' then
|
||||
flush_addr_preset <= (others=>'0'); -- all
|
||||
flush_count_preset <= 2**cache_index_width-1;
|
||||
else
|
||||
flush_addr_preset <= cache_index_inv; -- at
|
||||
flush_count_preset <= 0;
|
||||
end if;
|
||||
elsif cache_req = '1' then
|
||||
if cache_hit = '0' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= '0';
|
||||
cache_ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
|
||||
when invalidate_init =>
|
||||
invalidate_en <= '1';
|
||||
sn <= invalidate;
|
||||
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if cache_hit_inv = '1' or invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
request_count_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when mem_read_data_single =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_din_vld = '1' then
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
|
||||
when rd_cache =>
|
||||
mem_fetch_ack <= '1';
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
sn <= ready;
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if flush_load_en = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= flush_count_preset;
|
||||
flush_addr <= flush_addr_preset;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
flush_addr <= flush_addr + 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
@@ -640,14 +495,14 @@ request_counter:
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if ACK_I_r = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
|
||||
@@ -27,30 +27,30 @@ use IEEE.numeric_std.ALL;
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_instr.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
entity pipeline is
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
dmem_err : in STD_LOGIC;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
ctrl_out : out pipe_ctrl_out_t;
|
||||
ctrl_in : in pipe_ctrl_in_t;
|
||||
dtlb_qry_out : out tlb_query_in_t;
|
||||
dtlb_qry_in : in tlb_query_out_t;
|
||||
dcache_qry_out : out dcache_query_in_t;
|
||||
dcache_qry_in : in dcache_query_out_t;
|
||||
itlb_qry_out : out tlb_query_in_t;
|
||||
itlb_qry_in : in tlb_query_out_t;
|
||||
icache_qry_out : out icache_query_in_t;
|
||||
icache_qry_in : in icache_query_out_t
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_rdy : in STD_LOGIC;
|
||||
dmem_en : out STD_LOGIC;
|
||||
dmem_we : out STD_LOGIC;
|
||||
dmem_be : out unsigned(3 downto 0);
|
||||
dmem_addr : out word_t;
|
||||
dmem_din : in word_t;
|
||||
dmem_dout : out word_t;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
||||
c0_ctrl_in : in cop0_ctrl_out_t
|
||||
|
||||
);
|
||||
end pipeline;
|
||||
@@ -146,78 +146,87 @@ architecture Behavioral of pipeline is
|
||||
signal EX_stage : EX_t;
|
||||
signal MEM_stage : MEM_t;
|
||||
signal WB_stage : WB_t;
|
||||
signal clk_2, clk_1 : STD_LOGIC;
|
||||
signal hdu : hdu_t;
|
||||
signal sdu : sdu_t;
|
||||
signal reg_a : word_t;
|
||||
signal reg_b : word_t;
|
||||
signal branch_ce : STD_LOGIC;
|
||||
signal cpu_run : STD_LOGIC;
|
||||
signal branch_taken : STD_LOGIC;
|
||||
signal alu_result : word_t;
|
||||
signal mul_result : word_t;
|
||||
signal mul_busy : STD_LOGIC;
|
||||
signal EX_events_instr : event_t;
|
||||
signal EX_events_alu : event_t;
|
||||
signal EX_events_mem : event_t;
|
||||
signal EX_events_DTLB : event_t;
|
||||
signal EX_events : event_t;
|
||||
signal MEM_events : event_t;
|
||||
signal stage_rst : unsigned(3 downto 0);
|
||||
signal pipe_rst : STD_LOGIC;
|
||||
signal bcu_op_a : word_t;
|
||||
signal bcu_op_b : word_t;
|
||||
signal bcu_flags : bcu_flags_t;
|
||||
signal vaddr : word_t;
|
||||
signal dmem_src : word_t;
|
||||
|
||||
signal pc : pc_t;
|
||||
signal pc_branch : word_t;
|
||||
signal pc_curr : word_t;
|
||||
signal pc_last : word_t;
|
||||
signal pc_nxt : word_t;
|
||||
signal pc_branch_take : STD_LOGIC;
|
||||
signal ID_ctrl_branch : STD_LOGIC;
|
||||
signal EX_ctrl_branch : STD_LOGIC;
|
||||
signal MEM_ctrl_branch : STD_LOGIC;
|
||||
signal sdu_ID_stall : STD_LOGIC;
|
||||
signal sdu_ID_nop : STD_LOGIC;
|
||||
signal c0_ctrl_in_exc_pending : STD_LOGIC;
|
||||
signal c0_ctrl_in_exc_inject : STD_LOGIC;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
clk_1 <= clk;
|
||||
clk_2 <= not clk;
|
||||
cpu_run <= ce;
|
||||
|
||||
-- Stall Detection Unit ---------------------------------------------------
|
||||
sdu.ID_nop <= sdu.imem_dep or ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc; -- or pc.branch_not_taken;
|
||||
sdu.ID_nop <= sdu.imem_dep or c0_ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
|
||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.exc or WB_stage.exc or ctrl_in.exc_pending;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
|
||||
|
||||
sdu.stall_all <= sdu.dmem_dep;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or ctrl_in.exc_exit;
|
||||
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
|
||||
sdu.EX_stall <= sdu.stall_all;
|
||||
sdu.MEM_stall <= sdu.stall_all;
|
||||
sdu.WB_stall <= '0';
|
||||
sdu.WB_stall <= sdu.stall_all;
|
||||
|
||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||
sdu.imem_dep <= not icache_qry_in.rdy;
|
||||
sdu.dmem_dep <= not dcache_qry_in.rdy and MEM_stage.ctrl.dmem_en;
|
||||
sdu.imem_dep <= not imem_rdy;
|
||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||
---------------------------------------------------------------------------
|
||||
itlb_qry_out.vld <= (not sdu.ID_stall or ctrl_in.exc_inject);
|
||||
itlb_qry_out.write <= '0';
|
||||
itlb_qry_out.vaddr <= pc.nxt;
|
||||
|
||||
icache_qry_out.addr <= itlb_qry_in.paddr;
|
||||
icache_qry_out.en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or ctrl_in.exc_commit);
|
||||
icache_qry_out.nc <= itlb_qry_in.flags.N;
|
||||
imem_en <= ce and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
|
||||
pc_branch <= pc.pc_branch;
|
||||
pc_curr <= pc.curr;
|
||||
pc_last <= pc.last;
|
||||
pc_nxt <= pc.nxt;
|
||||
pc_branch_take <= pc.branch_take;
|
||||
ID_ctrl_branch <= ID_stage.ctrl.branch;
|
||||
EX_ctrl_branch <= EX_stage.ctrl.branch;
|
||||
MEM_ctrl_branch <= MEM_stage.ctrl.branch;
|
||||
sdu_ID_stall <= sdu.ID_stall;
|
||||
sdu_ID_nop <= sdu.ID_nop;
|
||||
c0_ctrl_in_exc_pending <= c0_ctrl_in.exc_pending;
|
||||
c0_ctrl_in_exc_inject <= c0_ctrl_in.exc_inject;
|
||||
|
||||
dtlb_qry_out.vld <= ID_stage.ctrl.dmem_en and not sdu.dmem_dep;
|
||||
dtlb_qry_out.write <= ID_stage.ctrl.dmem_we;
|
||||
dtlb_qry_out.vaddr <= ID_stage.va;
|
||||
|
||||
dcache_qry_out.be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp);
|
||||
dcache_qry_out.en <= EX_stage.dmem_en;
|
||||
dcache_qry_out.we <= EX_stage.ctrl.dmem_we;
|
||||
dcache_qry_out.data <= store_shift(EX_stage.reg_b, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp);
|
||||
dcache_qry_out.addr <= dtlb_qry_in.paddr;
|
||||
dcache_qry_out.nc <= dtlb_qry_in.flags.N;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Coprocessor assignments
|
||||
--------------------------------------------------------------------------
|
||||
ctrl_out.sdu <= sdu;
|
||||
ctrl_out.exc_req <= WB_stage.exc and not WB_stage.exc_last;
|
||||
ctrl_out.exc_ack <= '1';
|
||||
c0_ctrl_out.bd_wb <= WB_stage.bd;
|
||||
c0_ctrl_out.epc_mem <= MEM_stage.pcn;
|
||||
c0_ctrl_out.epc_wb <= MEM_stage.epc;
|
||||
c0_ctrl_out.imem_addr <= EX_stage.epc;
|
||||
c0_ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
c0_ctrl_out.sdu <= sdu;
|
||||
c0_ctrl_out.events <= WB_stage.events;
|
||||
c0_ctrl_out.exc_req <= MEM_stage.exc;
|
||||
c0_ctrl_out.exc_ack <= WB_stage.exc;
|
||||
cop_ir <= ID_stage.IR;
|
||||
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
|
||||
cop_dout <= EX_stage.reg_b;
|
||||
cop_dout <= dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Muldiv
|
||||
@@ -241,191 +250,90 @@ inst_muldiv: muldiv
|
||||
--------------------------------------------------------------------------
|
||||
-- IF stage
|
||||
--------------------------------------------------------------------------
|
||||
imem_addr <= pc.curr;
|
||||
|
||||
pipe_rst <= stage_rst(0);
|
||||
|
||||
proc_stage_reset:
|
||||
process(clk_1)
|
||||
proc_stage_pc_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
stage_rst <= (others => '1');
|
||||
else
|
||||
stage_rst <= stage_rst(stage_rst'left-1 downto 0) & '0';
|
||||
end if;
|
||||
if rising_edge(clk) then
|
||||
if c0_ctrl_in.exc_inject = '1' then
|
||||
pc.nxt <= c0_ctrl_in.exc_vec;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
pc.last <= pc.curr;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
pc.nxt <= ID_stage.jimm32;
|
||||
elsif ID_stage.ctrl.jump_long = '1' then
|
||||
pc.nxt <= ID_stage.reg_a;
|
||||
else
|
||||
pc.nxt <= pc.curr + 4;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- pc
|
||||
--------------------------------------------------------------------------
|
||||
inst_bcu_alt_ID: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => ID_stage.reg_a,
|
||||
op2_in => ID_stage.reg_b,
|
||||
flags => ID_stage.bcu_flags
|
||||
);
|
||||
|
||||
inst_bcu_alt_EX: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => EX_stage.reg_a,
|
||||
op2_in => EX_stage.reg_b,
|
||||
flags => EX_stage.bcu_flags
|
||||
);
|
||||
|
||||
|
||||
proc_stage_branch_alt:
|
||||
process(ID_stage)
|
||||
proc_stage_branch:
|
||||
process(EX_stage, bcu_flags)
|
||||
begin
|
||||
pc.branch_take <= '0';
|
||||
if ID_stage.ctrl.branch = '1' then
|
||||
if EX_stage.ctrl.branch = '1' then
|
||||
|
||||
case ID_stage.ctrl.bc_src is
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq;
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz);
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.ltz;
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch_not:
|
||||
process(EX_stage)
|
||||
proc_stage_branch_taken:
|
||||
process(clk)
|
||||
begin
|
||||
EX_stage.branch_not_taken <= '0';
|
||||
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.eq);
|
||||
|
||||
when bc_lez_gtz =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor (EX_stage.bcu_flags.eq or EX_stage.bcu_flags.ltz));
|
||||
|
||||
when bc_ltz_gez =>
|
||||
EX_stage.branch_not_taken <= EX_stage.ctrl.branch and not(EX_stage.ctrl.bc_not xor EX_stage.bcu_flags.ltz);
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
-- proc_stage_pc_next_alt:
|
||||
process(ctrl_in, sdu, pc, ID_stage, EX_stage)
|
||||
begin
|
||||
-- pc.nxt <= ctrl_in.exc_vec;
|
||||
-- if ctrl_in.exc_inject = '0' then
|
||||
pc.nxt <= pc.plus4;
|
||||
if ID_stage.ctrl.jump = '1' then
|
||||
pc.nxt <= ID_stage.jimm32;
|
||||
elsif ID_stage.ctrl.jump_long = '1' then
|
||||
pc.nxt <= ID_stage.reg_a;
|
||||
elsif pc.branch_take = '1' then
|
||||
pc.nxt <= pc.pc_branch;
|
||||
end if;
|
||||
-- end if;
|
||||
end process;
|
||||
|
||||
-- always branch in ID and revert in EX
|
||||
-- proc_stage_pc_next_alt:
|
||||
-- process(ctrl_in, sdu, ID_stage, EX_stage, pc)
|
||||
-- begin
|
||||
-- if EX_stage.branch_not_taken = '1' then
|
||||
-- pc.nxt <= pc.pc_branch_revert;
|
||||
-- else
|
||||
-- pc.nxt <= pc.plus4;
|
||||
-- if ID_stage.ctrl.jump = '1' then
|
||||
-- pc.nxt <= ID_stage.jimm32;
|
||||
-- elsif ID_stage.ctrl.jump_long = '1' then
|
||||
-- pc.nxt <= ID_stage.reg_a;
|
||||
-- elsif ID_stage.ctrl.branch = '1' then -- always take branch
|
||||
-- pc.nxt <= pc.pc_branch;
|
||||
-- end if;
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
proc_stage_pc_plus_4_alt:
|
||||
process(clk_2)
|
||||
begin
|
||||
if rising_edge(clk_2) then
|
||||
if rst = '1' then
|
||||
pc.plus4 <= ctrl_in.exc_vec;
|
||||
elsif cpu_run = '1' then
|
||||
if ctrl_in.exc_inject = '1' then
|
||||
pc.plus4 <= ctrl_in.exc_vec;
|
||||
else
|
||||
pc.plus4 <= pc.curr + 4;
|
||||
if rising_edge(clk) then
|
||||
if branch_taken = '0' then
|
||||
if sdu.ID_stall = '1' or c0_ctrl_in.exc_inject = '1' then
|
||||
if pc.branch_take = '1' then
|
||||
branch_taken <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
branch_taken <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_branch_alt:
|
||||
process(clk_2)
|
||||
proc_stage_pc_branch:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_2) then
|
||||
if cpu_run = '1' then
|
||||
if rising_edge(clk) then
|
||||
if sdu.ID_stall = '0' and ID_stage.ctrl.branch = '1' then
|
||||
pc.pc_branch <= pc.curr + ID_stage.bimm18;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_curr_alt:
|
||||
process(clk_1)
|
||||
proc_stage_pc:
|
||||
process(pc, branch_taken)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rst = '1' then
|
||||
pc.curr <= ctrl_in.exc_vec;
|
||||
pc.last <= ctrl_in.exc_vec;
|
||||
elsif cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
pc.last <= pc.curr;
|
||||
pc.curr <= pc.nxt;
|
||||
end if;
|
||||
if pc.branch_take = '1' or branch_taken = '1' then
|
||||
pc.curr <= pc.pc_branch;
|
||||
else
|
||||
pc.curr <= pc.nxt;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc_revert_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
if ID_stage.ctrl.branch = '1' then
|
||||
pc.pc_branch_revert <= pc.plus4;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch_not_taken_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if cpu_run = '1' and (sdu.ID_stall = '0' or ctrl_in.exc_inject = '1') then
|
||||
pc.branch_not_taken <= EX_stage.branch_not_taken;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- ID stage
|
||||
--------------------------------------------------------------------------
|
||||
ID_stage.IR <= to_01(icache_qry_in.data);
|
||||
ID_stage.IR <= to_01(imem_data);
|
||||
ID_stage.pcn <= pc.curr;
|
||||
ID_stage.op <= decode_op(ID_stage.IR);
|
||||
ID_stage.jimm32 <= extract_jimm32(ID_stage.IR, ID_stage.pcn);
|
||||
@@ -438,25 +346,13 @@ proc_stage_branch_not_taken_alt:
|
||||
ID_stage.epc <= pc.last;
|
||||
ID_stage.exc <= event_is_active(ID_stage.events); -- Todo: works
|
||||
ID_stage.nop <= sdu.ID_nop;
|
||||
ID_stage.va <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
||||
|
||||
ID_stage_tlb_query_results:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
ID_stage.itlb_qry <= itlb_qry_in;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_ID_except:
|
||||
process(ID_stage, ctrl_in, pc)
|
||||
process(ID_stage, c0_ctrl_in, pc)
|
||||
begin
|
||||
ID_stage.events <= events_clr;
|
||||
ID_stage.events.inst_load_err <= not ctrl_in.exc_pending and (ID_stage.pcn(1) or ID_stage.pcn(0));
|
||||
ID_stage.events.inst_priv_addr <= not ctrl_in.exc_pending and (ID_stage.pcn(word_t'left) and ctrl_in.user_mode);
|
||||
ID_stage.events.ITLB_LOAD <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.miss and not ID_stage.itlb_qry.write;
|
||||
ID_stage.events.ITLB_STORE <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.miss and ID_stage.itlb_qry.write;
|
||||
ID_stage.events.ITLB_MOD <= not ctrl_in.exc_pending and ID_stage.itlb_qry.vld and ID_stage.itlb_qry.dirty;
|
||||
ID_stage.events.inst_load_err <= not c0_ctrl_in.exc_pending and (pc.nxt(1) or pc.nxt(0));
|
||||
ID_stage.events.inst_priv_addr <= not c0_ctrl_in.exc_pending and (pc.nxt(word_t'left) and c0_ctrl_in.user_mode);
|
||||
end process;
|
||||
|
||||
proc_stage_hdu:
|
||||
@@ -470,19 +366,19 @@ proc_stage_hdu:
|
||||
|
||||
reg_ptr_a := ID_stage.reg_a_rptr;
|
||||
reg_ptr_b := ID_stage.reg_b_rptr;
|
||||
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.reg_we = '1';
|
||||
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.reg_we = '1';
|
||||
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.reg_we = '1';
|
||||
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.reg_we = '1';
|
||||
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.reg_we = '1';
|
||||
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.reg_we = '1';
|
||||
raw_a_EX := reg_ptr_a = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||
raw_a_MEM := reg_ptr_a = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||
raw_a_WB := reg_ptr_a = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||
raw_b_EX := reg_ptr_b = EX_stage.reg_wptr and EX_stage.wreg_we = '1';
|
||||
raw_b_MEM := reg_ptr_b = MEM_stage.reg_wptr and MEM_stage.wreg_we = '1';
|
||||
raw_b_WB := reg_ptr_b = WB_stage.reg_wptr and WB_stage.wreg_we = '1';
|
||||
|
||||
hdu.alu_fwd_a_ex <= raw_a_EX after 1 ns;
|
||||
hdu.alu_fwd_a_mem <= raw_a_MEM after 1 ns;
|
||||
hdu.alu_fwd_a_wb <= raw_a_WB after 1 ns;
|
||||
hdu.alu_fwd_b_ex <= raw_b_EX after 1 ns;
|
||||
hdu.alu_fwd_b_mem <= raw_b_MEM after 1 ns;
|
||||
hdu.alu_fwd_b_wb <= raw_b_WB after 1 ns;
|
||||
hdu.alu_fwd_a_ex <= raw_a_EX;
|
||||
hdu.alu_fwd_a_mem <= raw_a_MEM;
|
||||
hdu.alu_fwd_a_wb <= raw_a_WB;
|
||||
hdu.alu_fwd_b_ex <= raw_b_EX;
|
||||
hdu.alu_fwd_b_mem <= raw_b_MEM;
|
||||
hdu.alu_fwd_b_wb <= raw_b_WB;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -494,12 +390,18 @@ proc_stage_fwd_a:
|
||||
if hdu.alu_fwd_a_ex then
|
||||
data := EX_stage.result;
|
||||
elsif hdu.alu_fwd_a_mem then
|
||||
data := MEM_stage.result;
|
||||
data := MEM_stage.data;
|
||||
elsif hdu.alu_fwd_a_wb then
|
||||
data := WB_stage.result;
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
ID_stage.reg_a <= to_mips_01(data) after 1 ns;
|
||||
for i in 0 to 31 loop
|
||||
if data(i) = '1' then
|
||||
ID_stage.reg_a(i) <= '1';
|
||||
else
|
||||
ID_stage.reg_a(i) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -511,12 +413,18 @@ proc_stage_fwd_b:
|
||||
if hdu.alu_fwd_b_ex then
|
||||
data := EX_stage.result;
|
||||
elsif hdu.alu_fwd_b_mem then
|
||||
data := MEM_stage.result;
|
||||
data := MEM_stage.data;
|
||||
elsif hdu.alu_fwd_b_wb then
|
||||
data := WB_stage.result;
|
||||
data := WB_stage.data;
|
||||
end if;
|
||||
|
||||
ID_stage.reg_b <= to_mips_01(data) after 1 ns;
|
||||
for i in 0 to 31 loop
|
||||
if data(i) = '1' then
|
||||
ID_stage.reg_b(i) <= '1';
|
||||
else
|
||||
ID_stage.reg_b(i) <= '0';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -541,7 +449,7 @@ proc_imm_mux:
|
||||
|
||||
end case;
|
||||
|
||||
ID_stage.imm <= data after 1 ns;
|
||||
ID_stage.imm <= data;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -554,11 +462,11 @@ inst_reg_dual: reg_dual
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_w => clk_1,
|
||||
we => WB_stage.reg_we,
|
||||
clk_w => clk,
|
||||
we => WB_stage.wreg_we,
|
||||
en => '1',
|
||||
wptr => WB_stage.reg_wptr,
|
||||
din => WB_stage.result,
|
||||
din => WB_stage.data,
|
||||
rptr_a => ID_stage.reg_a_rptr,
|
||||
rptr_b => ID_stage.reg_b_rptr,
|
||||
dout_a => reg_a,
|
||||
@@ -571,13 +479,13 @@ inst_reg_dual: reg_dual
|
||||
EX_stage.reg_a_rptr <= extract_rs(EX_stage.IR);
|
||||
EX_stage.reg_b_rptr <= extract_rt(EX_stage.IR);
|
||||
EX_stage.result <= alu_result when EX_stage.ctrl.mul_access = '0' else mul_result;
|
||||
EX_stage.dtlb_qry <= dtlb_qry_in;
|
||||
|
||||
proc_stage_ID_EX_1:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(1) = '1' then
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
EX_stage.nop <= '1';
|
||||
EX_stage.op <= op_nop;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
@@ -585,20 +493,22 @@ proc_stage_ID_EX_1:
|
||||
EX_stage.epc <= (others => '0');
|
||||
EX_stage.pcn <= (others => '0');
|
||||
EX_stage.events_in <= events_clr;
|
||||
EX_stage.reg_a <= (others => '0');
|
||||
EX_stage.reg_b <= (others => '0');
|
||||
elsif sdu.EX_stall = '0' then
|
||||
EX_stage.va <= vaddr;
|
||||
EX_stage.nop <= sdu.EX_nop;
|
||||
EX_stage.op <= ID_stage.op;
|
||||
EX_stage.IR <= ID_stage.IR;
|
||||
EX_stage.va <= ID_stage.va;
|
||||
|
||||
EX_stage.reg_a <= ID_stage.reg_a;
|
||||
EX_stage.reg_b <= ID_stage.reg_b;
|
||||
EX_stage.events_in <= ID_stage.events;
|
||||
EX_stage.op <= ID_stage.op;
|
||||
EX_stage.ctrl <= ID_stage.ctrl;
|
||||
EX_stage.reg_write <= ID_stage.reg_write;
|
||||
EX_stage.IR <= ID_stage.IR;
|
||||
EX_stage.pcn <= ID_stage.pcn;
|
||||
EX_stage.epc <= ID_stage.epc;
|
||||
if sdu.EX_nop = '1' then
|
||||
EX_stage.op <= op_nop;
|
||||
EX_stage.IR <= (others => '0');
|
||||
EX_stage.ctrl <= ctrl_lines_default;
|
||||
EX_stage.reg_write <= '0';
|
||||
@@ -616,15 +526,6 @@ proc_stage_EX_instr_except:
|
||||
EX_events_instr.syscall <= EX_stage.ctrl.exc_syscall;
|
||||
end process;
|
||||
|
||||
proc_stage_EX_DTLB_except:
|
||||
process(EX_stage)
|
||||
begin
|
||||
EX_events_DTLB <= events_clr;
|
||||
EX_events_DTLB.DTLB_LOAD <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.miss and not EX_stage.dtlb_qry.write;
|
||||
EX_events_DTLB.DTLB_STORE <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.miss and EX_stage.dtlb_qry.write;
|
||||
EX_events_DTLB.DTLB_MOD <= EX_stage.dtlb_qry.vld and EX_stage.dtlb_qry.dirty;
|
||||
end process;
|
||||
|
||||
proc_stage_EX_alu_except:
|
||||
process(EX_stage)
|
||||
begin
|
||||
@@ -639,28 +540,30 @@ proc_stage_EX_alu_except:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
vaddr <= ID_stage.reg_a + extract_simm32(ID_stage.IR);
|
||||
|
||||
proc_stage_EX_mem_except:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if pipe_rst = '1' then
|
||||
EX_stage.dmem_en <= '0';
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
dmem_en <= '0';
|
||||
elsif sdu.EX_stall = '0' then
|
||||
EX_events_mem <= events_clr;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
if ID_stage.ctrl.dmem_en = '1' then
|
||||
EX_stage.dmem_en <= '1';
|
||||
dmem_en <= '1';
|
||||
if ID_stage.ctrl.except_en = '1' then
|
||||
if ID_stage.ctrl.word2_en = '1' then
|
||||
if ID_stage.va(0) = '1' then
|
||||
if vaddr(0) = '1' then
|
||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
end if;
|
||||
elsif ID_stage.va(1 downto 0) /= "00" then
|
||||
elsif vaddr(1 downto 0) /= "00" then
|
||||
EX_events_mem.data_load_err <= not ID_stage.ctrl.dmem_we;
|
||||
EX_events_mem.data_store_err <= ID_stage.ctrl.dmem_we;
|
||||
EX_stage.dmem_en <= '0';
|
||||
dmem_en <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -669,23 +572,28 @@ proc_stage_EX_mem_except:
|
||||
end process;
|
||||
|
||||
proc_stage_DMEM_ADDR:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if rising_edge(clk) then
|
||||
if sdu.EX_stall = '0' then
|
||||
if ctrl_in.EB = '1' then
|
||||
if c0_ctrl_in.EB = '1' then
|
||||
if ID_stage.ctrl.word2_en = '0' then
|
||||
EX_stage.pa_off <= not ID_stage.va(1 downto 0);
|
||||
EX_stage.pa_off <= not vaddr(1 downto 0);
|
||||
else
|
||||
EX_stage.pa_off <= not ID_stage.va(1) & ID_stage.va(0);
|
||||
EX_stage.pa_off <= not vaddr(1) & vaddr(0);
|
||||
end if;
|
||||
else
|
||||
EX_stage.pa_off <= ID_stage.va(1 downto 0);
|
||||
EX_stage.pa_off <= vaddr(1 downto 0);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
EX_stage.events <= EX_events_DTLB or EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||
dmem_src <= cop_din when EX_stage.ctrl.cop_instr_en = '1' else EX_stage.reg_b;
|
||||
dmem_be <= store_be(EX_stage.pa_off, EX_stage.ctrl.dmem_en, EX_stage.ctrl.word2_en, EX_stage.ctrl.word4_en, EX_stage.ctrl.align_left, EX_stage.ctrl.shift_byp);
|
||||
dmem_we <= EX_stage.ctrl.dmem_we;
|
||||
dmem_dout <= store_shift(dmem_src, EX_stage.pa_off, EX_stage.ctrl.shift_offset, EX_stage.ctrl.shift_byp);
|
||||
dmem_addr <= EX_stage.va;
|
||||
EX_stage.events <= EX_events_instr or EX_events_mem or EX_events_alu or EX_stage.events_in;
|
||||
EX_stage.exc <= event_is_active(EX_stage.events);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
@@ -703,19 +611,19 @@ proc_wptr_mux:
|
||||
reg_wptr := extract_rt(EX_stage.IR);
|
||||
end case;
|
||||
|
||||
EX_stage.reg_we <= EX_stage.reg_write after 1 ns;
|
||||
EX_stage.wreg_we <= EX_stage.reg_write;
|
||||
if reg_wptr = "00000" then
|
||||
EX_stage.reg_we <= '0' after 1 ns;
|
||||
EX_stage.wreg_we <= '0';
|
||||
end if;
|
||||
|
||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||
EX_stage.reg_wptr <= reg_wptr;
|
||||
case EX_stage.ctrl.wptr_srcsel is
|
||||
when wptr_src_imm =>
|
||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||
EX_stage.reg_wptr <= reg_wptr;
|
||||
|
||||
when wptr_src_const =>
|
||||
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
|
||||
EX_stage.reg_we <= '1' after 1 ns;
|
||||
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length);
|
||||
EX_stage.wreg_we <= '1';
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
@@ -723,62 +631,76 @@ proc_wptr_mux:
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_bcu_op:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if sdu.EX_stall = '0' then
|
||||
bcu_op_a <= ID_stage.reg_a;
|
||||
bcu_op_b <= ID_stage.reg_b;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
EX_stage.alu_op1 <= EX_stage.reg_a;
|
||||
|
||||
alu_op2_mux:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
variable data : word_t;
|
||||
begin
|
||||
|
||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||
data := ID_stage.reg_b;
|
||||
|
||||
case ID_stage.ctrl.alu.op2_src is
|
||||
|
||||
when alu_src_reg =>
|
||||
if rising_edge(clk) then
|
||||
if sdu.EX_stall = '0' then
|
||||
data := ID_stage.reg_b;
|
||||
|
||||
when alu_src_imm =>
|
||||
data := ID_stage.imm;
|
||||
case ID_stage.ctrl.alu.op2_src is
|
||||
|
||||
when others => null;
|
||||
when alu_src_reg =>
|
||||
data := ID_stage.reg_b;
|
||||
|
||||
end case;
|
||||
when alu_src_imm =>
|
||||
data := ID_stage.imm;
|
||||
|
||||
EX_stage.alu_op2 <= data;
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
|
||||
EX_stage.alu_op2 <= data;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
|
||||
shifter_sa_mux:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
variable data : shamt_t;
|
||||
variable data_inv : shamt_t;
|
||||
|
||||
begin
|
||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||
data := ID_stage.reg_a(4 downto 0);
|
||||
case ID_stage.ctrl.shamt2_srcsel is
|
||||
if rising_edge(clk) then
|
||||
if sdu.EX_stall = '0' then
|
||||
data := ID_stage.reg_a(4 downto 0);
|
||||
case ID_stage.ctrl.shamt2_srcsel is
|
||||
|
||||
when sa_src_reg =>
|
||||
data := ID_stage.reg_a(4 downto 0);
|
||||
when sa_src_reg =>
|
||||
data := ID_stage.reg_a(4 downto 0);
|
||||
|
||||
when sa_src_imm =>
|
||||
data := ID_stage.shamt;
|
||||
when sa_src_imm =>
|
||||
data := ID_stage.shamt;
|
||||
|
||||
when others => null;
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
data_inv := not data + 1;
|
||||
if ID_stage.ctrl.alu.shift_right = '0' then
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 1 ns;
|
||||
else
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data after 1 ns;
|
||||
end case;
|
||||
data_inv := not data + 1;
|
||||
if ID_stage.ctrl.alu.shift_right = '0' then
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv;
|
||||
else
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data;
|
||||
end if;
|
||||
EX_stage.shift_ctrl.shamt_nrm <= data;
|
||||
EX_stage.shift_ctrl.shift_right <= ID_stage.ctrl.alu.shift_right;
|
||||
EX_stage.shift_ctrl.shift_arith <= ID_stage.ctrl.alu.shift_arith;
|
||||
end if;
|
||||
EX_stage.shift_ctrl.shamt_nrm <= data after 1 ns;
|
||||
EX_stage.shift_ctrl.shift_right <= ID_stage.ctrl.alu.shift_right;
|
||||
EX_stage.shift_ctrl.shift_arith <= ID_stage.ctrl.alu.shift_arith;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
@@ -811,31 +733,43 @@ inst_alu: alu
|
||||
flags => EX_stage.alu_flags
|
||||
);
|
||||
|
||||
inst_bcu: bcu
|
||||
GENERIC MAP
|
||||
(
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
op1_in => bcu_op_a,
|
||||
op2_in => bcu_op_b,
|
||||
flags => bcu_flags
|
||||
);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- MEM stage
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_MEM_n:
|
||||
process(clk_1)
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(2) = '1' then
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.reg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
MEM_stage.pa_off <= (others => '0');
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
MEM_stage.nop <= '1';
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.va <= (others => '0');
|
||||
MEM_stage.pcn <= (others => '0');
|
||||
MEM_stage.ex_result <= (others => '0');
|
||||
MEM_stage.epc <= (others => '0');
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.reg_wptr <= (others => '0');
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
MEM_stage.pa_off <= (others => '0');
|
||||
MEM_stage.events_in <= events_clr;
|
||||
elsif sdu.MEM_stall = '0' then
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
MEM_stage.reg_a <= EX_stage.reg_a;
|
||||
MEM_stage.reg_b <= EX_stage.reg_b;
|
||||
MEM_stage.result_in <= EX_stage.result;
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.epc <= EX_stage.epc;
|
||||
MEM_stage.pcn <= EX_stage.pcn;
|
||||
MEM_stage.events_in <= EX_stage.events;
|
||||
MEM_stage.reg_we <= EX_stage.reg_we;
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.wreg_we <= EX_stage.wreg_we;
|
||||
MEM_stage.ctrl <= EX_stage.ctrl;
|
||||
MEM_stage.branch_not_taken <= EX_stage.branch_not_taken;
|
||||
if EX_stage.ctrl.dmem_en = '1' then
|
||||
MEM_stage.va <= EX_stage.va;
|
||||
end if;
|
||||
@@ -843,40 +777,44 @@ proc_stage_MEM_n:
|
||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||
if MEM_stage.reg_wptr = EX_stage.reg_wptr then
|
||||
if (EX_stage.ctrl.dmem_en and MEM_stage.ctrl.dmem_en) = '1' then
|
||||
MEM_stage.result_in <= MEM_stage.result;
|
||||
MEM_stage.ex_result <= MEM_stage.data;
|
||||
end if;
|
||||
else
|
||||
MEM_stage.result_in <= EX_stage.reg_b;
|
||||
MEM_stage.ex_result <= EX_stage.reg_b;
|
||||
end if;
|
||||
if EX_stage.ctrl.cop_instr_en = '1' then
|
||||
if EX_stage.ctrl.cop_read = '1' then
|
||||
MEM_stage.result_in <= cop_din;
|
||||
MEM_stage.ex_result <= cop_din;
|
||||
end if;
|
||||
elsif EX_stage.ctrl.dmem_en = '0' then
|
||||
MEM_stage.result_in <= EX_stage.result;
|
||||
MEM_stage.ex_result <= EX_stage.result;
|
||||
end if;
|
||||
if sdu.MEM_nop = '1' then
|
||||
MEM_stage.reg_we <= '0';
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
MEM_stage.ctrl <= ctrl_lines_default;
|
||||
else
|
||||
MEM_stage.pcn <= EX_stage.pcn;
|
||||
MEM_stage.epc <= EX_stage.epc;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_MEM_mux:
|
||||
process(MEM_stage, dcache_qry_in.data)
|
||||
process(MEM_stage, dmem_din)
|
||||
variable temp1 : word_t;
|
||||
variable temp2 : word_t;
|
||||
variable data : word_t;
|
||||
variable be : unsigned(3 downto 0);
|
||||
begin
|
||||
data := MEM_stage.result_in;
|
||||
data := MEM_stage.ex_result;
|
||||
temp1 := load_shift(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||
if MEM_stage.ctrl.reg_link = '1' then
|
||||
data := MEM_stage.epc + 8;
|
||||
elsif MEM_stage.ctrl.dmem_en = '1' then
|
||||
temp1 := load_shift(dcache_qry_in.data, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
temp2 := load_sign_ext(temp1, MEM_stage.ctrl.sign_ext_byp, MEM_stage.ctrl.load_signed, MEM_stage.ctrl.word2_en, MEM_stage.ctrl.word4_en);
|
||||
be := load_be(MEM_stage.pa_off, MEM_stage.ctrl.align_left, MEM_stage.ctrl.byte_en_byp);
|
||||
if be(0) = '1' then
|
||||
data(7 downto 0) := temp2(7 downto 0);
|
||||
end if;
|
||||
@@ -890,16 +828,16 @@ proc_stage_MEM_mux:
|
||||
data(31 downto 24) := temp2(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
MEM_stage.result <= data after 1 ns;
|
||||
MEM_stage.data <= data;
|
||||
|
||||
end process;
|
||||
|
||||
proc_stage_MEM_except:
|
||||
process(MEM_stage, ctrl_in)
|
||||
process(MEM_stage, c0_ctrl_in)
|
||||
begin
|
||||
MEM_stage.events <= MEM_stage.events_in;
|
||||
MEM_stage.events.Int <= ctrl_in.int;
|
||||
MEM_stage.events.NMI <= ctrl_in.NMI;
|
||||
MEM_stage.events.Int <= c0_ctrl_in.int;
|
||||
MEM_stage.events.NMI <= c0_ctrl_in.NMI;
|
||||
end process;
|
||||
|
||||
MEM_stage.exc <= event_is_active(MEM_stage.events);
|
||||
@@ -908,50 +846,34 @@ proc_stage_MEM_except:
|
||||
-- WB stage
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_WB_p:
|
||||
process(clk_1)
|
||||
variable branch_delay : std_logic;
|
||||
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(3) = '1' then
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
WB_stage.nop <= '1';
|
||||
WB_stage.op <= op_nop;
|
||||
WB_stage.reg_we <= '1';
|
||||
WB_stage.wreg_we <= '1';
|
||||
WB_stage.reg_wptr <= (others => '0');
|
||||
WB_stage.epc <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
WB_stage.data <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
WB_stage.bd <= '0';
|
||||
WB_stage.exc <= '0';
|
||||
elsif sdu.WB_stall = '0' then
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
WB_stage.reg_a <= MEM_stage.reg_a;
|
||||
WB_stage.reg_b <= MEM_stage.reg_b;
|
||||
WB_stage.result <= MEM_stage.result;
|
||||
WB_stage.op <= MEM_stage.op;
|
||||
WB_stage.epc <= MEM_stage.epc;
|
||||
branch_delay := MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
WB_stage.bd <= branch_delay;
|
||||
WB_stage.exc_last <= WB_stage.exc;
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
WB_stage.reg_we <= MEM_stage.reg_we;
|
||||
WB_stage.wreg_we <= MEM_stage.wreg_we;
|
||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
if sdu.stall_all = '0' then
|
||||
if MEM_stage.exc = '1' and WB_stage.exc = '0' then
|
||||
ctrl_out.dmem_addr <= MEM_stage.va;
|
||||
ctrl_out.imem_addr <= MEM_stage.epc;
|
||||
ctrl_out.epc_wb <= MEM_stage.epc;
|
||||
ctrl_out.bd_wb <= WB_stage.bd;
|
||||
ctrl_out.events <= MEM_stage.events;
|
||||
if WB_stage.bd = '1' then
|
||||
ctrl_out.epc_wb <= WB_stage.epc;
|
||||
end if;
|
||||
end if;
|
||||
WB_stage.data <= MEM_stage.data;
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
if MEM_stage.exc = '1' then
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
end if;
|
||||
if sdu.WB_nop = '1' then
|
||||
WB_stage.reg_we <= '0';
|
||||
WB_stage.op <= op_nop;
|
||||
WB_stage.wreg_we <= '0';
|
||||
else
|
||||
WB_stage.bd <= MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
end if;
|
||||
if WB_stage.exc = '0' then
|
||||
WB_stage.va <= MEM_stage.va;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
@@ -30,37 +30,37 @@ use work.mips_types.all;
|
||||
entity shifter is
|
||||
Generic
|
||||
(
|
||||
DATA_WIDTH : integer := 8
|
||||
data_width : integer := 8
|
||||
);
|
||||
Port
|
||||
(
|
||||
shift_ctrl : in shift_ctrl_t;
|
||||
din : in unsigned (DATA_WIDTH-1 downto 0);
|
||||
dout : out unsigned (DATA_WIDTH-1 downto 0)
|
||||
din : in unsigned (data_width-1 downto 0);
|
||||
dout : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
end shifter;
|
||||
|
||||
architecture Behavioral of shifter is
|
||||
|
||||
subtype word_t is unsigned(DATA_WIDTH-1 downto 0);
|
||||
subtype word_t is unsigned(data_width-1 downto 0);
|
||||
type word_array_t is array (0 to 5) of word_t;
|
||||
|
||||
signal rot_data : word_array_t;
|
||||
signal sa_rnd : unsigned (4 downto 0);
|
||||
signal fill : std_logic;
|
||||
|
||||
type fill_mask_rom_t is array (0 to 2*DATA_WIDTH-1) of unsigned(DATA_WIDTH-1 downto 0);
|
||||
type fill_mask_rom_t is array (0 to 2*data_width-1) of unsigned(data_width-1 downto 0);
|
||||
--------------------------------------------------------------------------
|
||||
function gen_fill_mask_rom(width : natural) return fill_mask_rom_t is
|
||||
function gen_fill_mask_rom(data_width_arg : natural) return fill_mask_rom_t is
|
||||
variable result : fill_mask_rom_t;
|
||||
begin
|
||||
result(0) := (width-1 downto 0 => '0');
|
||||
for i in 1 to width-1 loop
|
||||
result(i) := (width-1-i downto 0 => '0') & (i-1 downto 0 => '1');
|
||||
result(0) := (data_width_arg-1 downto 0 => '0');
|
||||
for i in 1 to data_width_arg-1 loop
|
||||
result(i) := (data_width_arg-1-i downto 0 => '0') & (i-1 downto 0 => '1');
|
||||
end loop;
|
||||
result(width) := (width-1 downto 0 => '0');
|
||||
for i in 1 to width-1 loop
|
||||
result(width+i) := (i-1 downto 0 => '1') & (width-1-i downto 0 => '0');
|
||||
result(data_width_arg) := (data_width_arg-1 downto 0 => '0');
|
||||
for i in 1 to data_width_arg-1 loop
|
||||
result(data_width_arg+i) := (i-1 downto 0 => '1') & (data_width_arg-1-i downto 0 => '0');
|
||||
end loop;
|
||||
return result;
|
||||
|
||||
@@ -79,10 +79,10 @@ function rot_stage(x : unsigned; en : std_logic; stage_num : natural) return uns
|
||||
|
||||
end rot_stage;
|
||||
|
||||
constant fill_mask_rom : fill_mask_rom_t := gen_fill_mask_rom(DATA_WIDTH);
|
||||
signal fill_mask : unsigned(DATA_WIDTH-1 downto 0);
|
||||
constant fill_mask_rom : fill_mask_rom_t := gen_fill_mask_rom(data_width);
|
||||
signal fill_mask : unsigned(data_width-1 downto 0);
|
||||
signal fill_mask_addr : unsigned(5 downto 0);
|
||||
signal dout_filled : unsigned (DATA_WIDTH-1 downto 0);
|
||||
signal dout_filled : unsigned (data_width-1 downto 0);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
@@ -96,7 +96,7 @@ gen_rotate_right:
|
||||
end generate;
|
||||
|
||||
sa_rnd <= shift_ctrl.shamt_rnd;
|
||||
fill <= shift_ctrl.shift_arith and din(DATA_WIDTH-1);
|
||||
fill <= shift_ctrl.shift_arith and din(data_width-1);
|
||||
fill_mask_addr <= shift_ctrl.shift_right & shift_ctrl.shamt_nrm;
|
||||
fill_mask <= fill_mask_rom(to_integer(fill_mask_addr));
|
||||
|
||||
@@ -110,7 +110,7 @@ proc_fill_neu:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
dout <= dout_filled after 5 ns;
|
||||
dout <= dout_filled;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end Behavioral;
|
||||
|
||||
@@ -1,340 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
ENTITY tlb IS
|
||||
Generic
|
||||
(
|
||||
NUM_ENTRIES : natural := 8;
|
||||
CACHE_KSEG1 : boolean := false;
|
||||
TRANSLATE_KSEG0_1 : boolean := true;
|
||||
USE_TLB : boolean := false
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
ctrl_in : in tlb_ctrl_in_t;
|
||||
ctrl_out : out tlb_ctrl_out_t;
|
||||
|
||||
query_in : in tlb_query_in_t;
|
||||
query_out : out tlb_query_out_t
|
||||
|
||||
);
|
||||
END tlb;
|
||||
|
||||
ARCHITECTURE behavior OF tlb IS
|
||||
|
||||
signal clk_rd : STD_LOGIC;
|
||||
signal blk_hit : unsigned(NUM_ENTRIES-1 downto 0);
|
||||
signal blk_entry_lo : tlb_entry_lo_t;
|
||||
|
||||
constant C_ENTRY_LO_DEFAULT : tlb_entry_lo_t :=
|
||||
(
|
||||
N => '0', D => '0', V => '1', G => '0', PFN => (others => '0')
|
||||
);
|
||||
|
||||
signal kseg1_force_cached : STD_LOGIC;
|
||||
signal kseg_0_1_pfn : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
signal hit_umc : STD_LOGIC;
|
||||
signal hit_umuc : STD_LOGIC;
|
||||
signal entry_lo_res : tlb_entry_lo_t;
|
||||
signal qry_res : tlb_query_out_t;
|
||||
|
||||
signal pa : word_t;
|
||||
signal hit : STD_LOGIC;
|
||||
signal vld_r : STD_LOGIC;
|
||||
|
||||
signal cam_rdy : STD_LOGIC;
|
||||
signal cam_hit_vld : STD_LOGIC;
|
||||
|
||||
signal vaddr_reg : word_t;
|
||||
signal write_reg : STD_LOGIC;
|
||||
|
||||
subtype reg_lo_t is unsigned(23 downto 0);
|
||||
subtype reg_hi_t is unsigned(25 downto 0);
|
||||
|
||||
signal reg_ctrl_entry_lo_din : reg_lo_t;
|
||||
signal reg_ctrl_entry_lo_dout : reg_lo_t;
|
||||
signal reg_qry_entry_lo_dout : reg_lo_t;
|
||||
signal reg_qry_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||
signal reg_ctrl_entry_lo_addr : unsigned(lg2(NUM_ENTRIES)-1 downto 0);
|
||||
|
||||
signal reg_ctrl_entry_hi_din : reg_hi_t;
|
||||
signal reg_ctrl_entry_hi_dout : reg_hi_t;
|
||||
|
||||
function to_entry_lo(x : reg_lo_t) return tlb_entry_lo_t is
|
||||
variable result : tlb_entry_lo_t;
|
||||
begin
|
||||
result.PFN := x(23 downto 4);
|
||||
result.N := x(3);
|
||||
result.D := x(2);
|
||||
result.V := x(1);
|
||||
result.G := x(0);
|
||||
|
||||
return result;
|
||||
|
||||
end to_entry_lo;
|
||||
|
||||
function to_entry_hi(x : reg_hi_t) return tlb_entry_hi_t is
|
||||
variable result : tlb_entry_hi_t;
|
||||
begin
|
||||
result.VPN := x(25 downto 6);
|
||||
result.ASID := x(5 downto 0);
|
||||
|
||||
return result;
|
||||
|
||||
end to_entry_hi;
|
||||
|
||||
function to_reg_lo(x : tlb_entry_lo_t) return reg_lo_t is
|
||||
variable result : reg_lo_t;
|
||||
begin
|
||||
result(23 downto 4) := x.PFN;
|
||||
result(3) := x.N;
|
||||
result(2) := x.D;
|
||||
result(1) := x.V;
|
||||
result(0) := x.G;
|
||||
|
||||
return result;
|
||||
|
||||
end to_reg_lo;
|
||||
|
||||
function to_reg_hi(x : tlb_entry_hi_t) return reg_hi_t is
|
||||
variable result : reg_hi_t;
|
||||
begin
|
||||
result(25 downto 6) := x.VPN;
|
||||
result(5 downto 0) := x.ASID;
|
||||
|
||||
return result;
|
||||
|
||||
end to_reg_hi;
|
||||
|
||||
signal hit_idx : integer;
|
||||
function decode(x : unsigned; N : integer) return integer is
|
||||
variable result : integer;
|
||||
begin
|
||||
result := 0;
|
||||
for i in 0 to N-1 loop
|
||||
if x(i) = '1' then
|
||||
result := i;
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
|
||||
end decode;
|
||||
|
||||
function decode2(x : unsigned; N : integer) return unsigned is
|
||||
variable result : unsigned (lg2(N)-1 downto 0);
|
||||
begin
|
||||
result := (others => '0');
|
||||
for i in 0 to N-1 loop
|
||||
result := result or ((lg2(N)-1 downto 0 => x(i)) and to_unsigned(i, lg2(N)));
|
||||
end loop;
|
||||
|
||||
return result;
|
||||
|
||||
end decode2;
|
||||
|
||||
begin
|
||||
kseg1_force_cached <= '1' when CACHE_KSEG1 else '0';
|
||||
kseg_0_1_pfn <= "000" & vaddr_reg(28 downto lg2(TLB_PAGE_SIZE)) when TRANSLATE_KSEG0_1 else vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||
|
||||
clk_rd <= clk;
|
||||
rdy <= cam_rdy;
|
||||
|
||||
qry_res.vld <= vld_r;
|
||||
qry_res.miss <= not hit;
|
||||
qry_res.dirty <= hit and qry_res.flags.D and write_reg;
|
||||
qry_res.write <= write_reg;
|
||||
qry_res.flags.N <= entry_lo_res.N;
|
||||
qry_res.flags.D <= entry_lo_res.D;
|
||||
qry_res.flags.V <= entry_lo_res.V;
|
||||
qry_res.paddr <= pa;
|
||||
|
||||
query_out <= qry_res;
|
||||
|
||||
pa <= entry_lo_res.PFN & vaddr_reg(lg2(TLB_PAGE_SIZE)-1 downto 0);
|
||||
|
||||
hit_idx <= decode(blk_hit, NUM_ENTRIES);
|
||||
|
||||
blk_entry_lo <= to_entry_lo(to_mips_01(reg_qry_entry_lo_dout));
|
||||
-- reg_qry_entry_lo_addr <= to_unsigned(hit_idx, lg2(NUM_ENTRIES));
|
||||
reg_qry_entry_lo_addr <= decode2(blk_hit, NUM_ENTRIES);
|
||||
reg_ctrl_entry_lo_din <= to_reg_lo(ctrl_in.entry_lo);
|
||||
|
||||
ctrl_out.entry_hi <= to_entry_hi(to_mips_01(reg_ctrl_entry_hi_dout));
|
||||
reg_ctrl_entry_hi_din <= to_reg_hi(ctrl_in.entry_hi);
|
||||
|
||||
registered_ctrl_out:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
vaddr_reg <= query_in.vaddr;
|
||||
write_reg <= query_in.write;
|
||||
end if;
|
||||
vld_r <= query_in.vld;
|
||||
if ce = '1' then
|
||||
if ctrl_in.entry_re = '1' then
|
||||
|
||||
ctrl_out.entry_lo <= to_entry_lo(to_mips_01(reg_ctrl_entry_lo_dout));
|
||||
ctrl_out.entry_vld <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_reg_entry_lo: entity work.reg_dual
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(NUM_ENTRIES),
|
||||
data_width => reg_lo_t'length
|
||||
)
|
||||
PORT MAP (
|
||||
clk_w => clk,
|
||||
we => ctrl_in.entry_we,
|
||||
en => '1',
|
||||
wptr => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
din => reg_ctrl_entry_lo_din,
|
||||
rptr_a => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
rptr_b => reg_qry_entry_lo_addr,
|
||||
dout_a => reg_ctrl_entry_lo_dout,
|
||||
dout_b => reg_qry_entry_lo_dout
|
||||
);
|
||||
|
||||
inst_reg_entry_hi: entity work.dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(NUM_ENTRIES),
|
||||
data_width => reg_hi_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
we_a => ctrl_in.entry_we,
|
||||
re_b => ctrl_in.entry_re,
|
||||
addr_a => ctrl_in.entry_wr_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
addr_b => ctrl_in.entry_rd_idx(lg2(NUM_ENTRIES)-1 downto 0),
|
||||
din_a => reg_ctrl_entry_hi_din,
|
||||
dout_b => reg_ctrl_entry_hi_dout
|
||||
);
|
||||
|
||||
inst_cam_va: entity work.cam
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => NUM_ENTRIES,
|
||||
DATA_WIDTH => 20,
|
||||
CAM_RAM_MAX_WIDTH => 15
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => rst,
|
||||
clk => clk,
|
||||
clk_rd => clk_rd,
|
||||
rdy => cam_rdy,
|
||||
|
||||
re => query_in.vld,
|
||||
we => ctrl_in.entry_we,
|
||||
vld => '1',
|
||||
addr => ctrl_in.entry_wr_idx,
|
||||
tag_wr => ctrl_in.entry_hi.VPN,
|
||||
|
||||
tag_rd => query_in.vaddr(31 downto lg2(TLB_PAGE_SIZE)),
|
||||
hit => blk_hit(NUM_ENTRIES-1 downto 0),
|
||||
hit_vld => cam_hit_vld
|
||||
|
||||
);
|
||||
|
||||
hit_umc <= '1' when vaddr_reg(31 downto 29) = "100" else '0';
|
||||
hit_umuc <= '1' when vaddr_reg(31 downto 29) = "101" else '0';
|
||||
|
||||
tlb_entry_lo_result_translate:
|
||||
if USE_TLB = true generate
|
||||
tlb_entry_lo_result:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||
begin
|
||||
entry_lo_res <= blk_entry_lo;
|
||||
if hit_umc = '1' or hit_umuc = '1' then
|
||||
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||
end if;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_entry_lo_result_notranslate:
|
||||
if USE_TLB = false generate
|
||||
tlb_entry_lo_result:
|
||||
process(blk_entry_lo, vaddr_reg, hit_umc, hit_umuc, kseg_0_1_pfn, kseg1_force_cached)
|
||||
begin
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= vaddr_reg(31 downto lg2(TLB_PAGE_SIZE));
|
||||
if hit_umc = '1' or hit_umuc = '1' then
|
||||
entry_lo_res.N <= hit_umuc and not kseg1_force_cached;
|
||||
entry_lo_res <= C_ENTRY_LO_DEFAULT;
|
||||
entry_lo_res.PFN <= kseg_0_1_pfn;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_hit_combine_translate:
|
||||
if USE_TLB = true generate
|
||||
tlb_hit_combine:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||
variable t_v : std_logic;
|
||||
begin
|
||||
t_v := blk_entry_lo.V;
|
||||
t_v := t_v or hit_umc or hit_umuc;
|
||||
hit <= t_v;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
tlb_hit_combine_notranslate:
|
||||
if USE_TLB = false generate
|
||||
tlb_hit_combine:
|
||||
process(blk_entry_lo, hit_umc, hit_umuc)
|
||||
variable t_v : std_logic;
|
||||
begin
|
||||
t_v := hit_umc or hit_umuc;
|
||||
hit <= t_v;
|
||||
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
------------------------------------------------------------------
|
||||
end behavior;
|
||||
+109
-168
@@ -31,16 +31,14 @@ use work.mips_types.all;
|
||||
entity mips_top is
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 1024; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 1024; -- words
|
||||
dcache_line : natural := 8; -- words
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
icache_size : natural := 1024; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 1024; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
debug : out chip_debug_t;
|
||||
debug : out unsigned(1 downto 0);
|
||||
eb : in STD_LOGIC;
|
||||
nmi : in STD_LOGIC;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
@@ -69,32 +67,42 @@ architecture rtl of mips_top is
|
||||
COMPONENT pipeline is
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
dmem_err : in STD_LOGIC;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
ctrl_out : out pipe_ctrl_out_t;
|
||||
ctrl_in : in pipe_ctrl_in_t;
|
||||
dtlb_qry_out : out tlb_query_in_t;
|
||||
dtlb_qry_in : in tlb_query_out_t;
|
||||
dcache_qry_out : out dcache_query_in_t;
|
||||
dcache_qry_in : in dcache_query_out_t;
|
||||
itlb_qry_out : out tlb_query_in_t;
|
||||
itlb_qry_in : in tlb_query_out_t;
|
||||
icache_qry_out : out icache_query_in_t;
|
||||
icache_qry_in : in icache_query_out_t
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_rdy : in STD_LOGIC;
|
||||
dmem_en : out STD_LOGIC;
|
||||
dmem_we : out STD_LOGIC;
|
||||
dmem_be : out unsigned(3 downto 0);
|
||||
dmem_addr : out word_t;
|
||||
dmem_din : in word_t;
|
||||
dmem_dout : out word_t;
|
||||
cop_ir : out word_t;
|
||||
cop_ir_en : out STD_LOGIC;
|
||||
cop_din : in word_t;
|
||||
cop_dout : out word_t;
|
||||
c0_ctrl_out : out cop0_ctrl_in_t;
|
||||
c0_ctrl_in : in cop0_ctrl_out_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
signal imem_err : std_logic;
|
||||
signal imem_rdy : std_logic;
|
||||
signal imem_en : std_logic;
|
||||
signal imem_addr : word_t;
|
||||
signal imem_din : word_t;
|
||||
signal dmem_err : std_logic;
|
||||
signal dmem_rdy : std_logic;
|
||||
signal dmem_en : std_logic;
|
||||
signal dmem_we : std_logic;
|
||||
signal dmem_addr : word_t;
|
||||
signal dmem_dout : word_t;
|
||||
signal dmem_din : word_t;
|
||||
signal dmem_be : unsigned(3 downto 0);
|
||||
|
||||
signal biu_busy : STD_LOGIC;
|
||||
signal biu_rst : STD_LOGIC;
|
||||
signal cpu_rst : STD_LOGIC;
|
||||
signal cpu_run : STD_LOGIC;
|
||||
@@ -103,14 +111,8 @@ architecture rtl of mips_top is
|
||||
signal pipe_cop_ir_en : STD_LOGIC;
|
||||
signal pipe_cop_din : word_t;
|
||||
signal pipe_cop_dout : word_t;
|
||||
signal pipe_ctrl_in : pipe_ctrl_in_t;
|
||||
signal pipe_ctrl_out : pipe_ctrl_out_t;
|
||||
|
||||
signal cop0_ctrl_in : cop0_ctrl_in_t;
|
||||
signal cop0_ctrl_out : cop0_ctrl_out_t;
|
||||
|
||||
signal biu_ctrl_in : biu_ctrl_in_t;
|
||||
signal biu_ctrl_out : biu_ctrl_out_t;
|
||||
signal pipe_c0_ctrl_out : cop0_ctrl_in_t;
|
||||
signal pipe_c0_ctrl_in : cop0_ctrl_out_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Coprocessor
|
||||
@@ -145,48 +147,53 @@ architecture rtl of mips_top is
|
||||
COMPONENT biu
|
||||
GENERIC
|
||||
(
|
||||
icache_size : natural;
|
||||
icache_line : natural;
|
||||
dcache_size : natural;
|
||||
dcache_line : natural;
|
||||
WRITE_FIFO_SIZE : natural;
|
||||
WITH_TLB : boolean;
|
||||
TRANSLATE_KSEG0_1 : boolean
|
||||
icache_size : natural;
|
||||
icache_line : natural;
|
||||
dcache_size : natural;
|
||||
dcache_line : natural
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
busy : out STD_LOGIC;
|
||||
|
||||
imem_err : out STD_LOGIC;
|
||||
dmem_err : out STD_LOGIC;
|
||||
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out unsigned(31 downto 0);
|
||||
MDAT_I : in unsigned(31 downto 0);
|
||||
MDAT_O : out unsigned(31 downto 0);
|
||||
DAT_I : in unsigned(31 downto 0);
|
||||
DAT_O : out unsigned(31 downto 0);
|
||||
WE_O : out STD_LOGIC;
|
||||
SEL_O : out unsigned(3 downto 0);
|
||||
CYC_O : out STD_LOGIC;
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
|
||||
ctrl_in : in biu_ctrl_in_t;
|
||||
ctrl_out : out biu_ctrl_out_t
|
||||
|
||||
cop0_ctrl_in : in cop0_ctrl_out_t;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
cpu_imem_err : out STD_LOGIC;
|
||||
cpu_imem_rdy : out STD_LOGIC;
|
||||
cpu_imem_en : in STD_LOGIC;
|
||||
cpu_imem_addr : in word_t;
|
||||
cpu_imem_din : out word_t;
|
||||
cpu_dmem_err : out STD_LOGIC;
|
||||
cpu_dmem_rdy : out STD_LOGIC;
|
||||
cpu_dmem_en : in STD_LOGIC;
|
||||
cpu_dmem_we : in STD_LOGIC;
|
||||
cpu_dmem_be : in unsigned(3 downto 0);
|
||||
cpu_dmem_dout : in word_t;
|
||||
cpu_dmem_din : out word_t;
|
||||
cpu_dmem_addr : in word_t
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
begin
|
||||
|
||||
-------------------------------------------------------------------
|
||||
process(cpu_clk)
|
||||
debug(0) <= imem_err;
|
||||
debug(1) <= dmem_err;
|
||||
|
||||
process(CLK_I)
|
||||
variable reset_delay : unsigned (31 downto 0);
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
reset_delay := (others => '0');
|
||||
biu_rst <= '1';
|
||||
@@ -200,7 +207,7 @@ begin
|
||||
if reset_delay(31) = '1' then
|
||||
cpu_rst <= '0';
|
||||
end if;
|
||||
if reset_delay(16) = '1' and biu_busy = '0' then
|
||||
if reset_delay(16) = '1' then
|
||||
cpu_run <= '1';
|
||||
end if;
|
||||
end if;
|
||||
@@ -210,29 +217,28 @@ begin
|
||||
inst_pipeline: pipeline
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
ce => cpu_run,
|
||||
imem_err => imem_err,
|
||||
dmem_err => dmem_err,
|
||||
cop_ir => pipe_cop_ir,
|
||||
cop_ir_en => pipe_cop_ir_en,
|
||||
cop_din => pipe_cop_din,
|
||||
cop_dout => pipe_cop_dout,
|
||||
ctrl_out => pipe_ctrl_out,
|
||||
ctrl_in => pipe_ctrl_in,
|
||||
dtlb_qry_out => biu_ctrl_in.dtlb_qry,
|
||||
dtlb_qry_in => biu_ctrl_out.dtlb_qry,
|
||||
dcache_qry_out => biu_ctrl_in.dcache_qry,
|
||||
dcache_qry_in => biu_ctrl_out.dcache_qry,
|
||||
itlb_qry_out => biu_ctrl_in.itlb_qry,
|
||||
itlb_qry_in => biu_ctrl_out.itlb_qry,
|
||||
icache_qry_out => biu_ctrl_in.icache_qry,
|
||||
icache_qry_in => biu_ctrl_out.icache_qry
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
ce => cpu_run,
|
||||
imem_rdy => imem_rdy,
|
||||
imem_en => imem_en,
|
||||
imem_addr => imem_addr,
|
||||
imem_data => imem_din,
|
||||
dmem_rdy => dmem_rdy,
|
||||
dmem_en => dmem_en,
|
||||
dmem_we => dmem_we,
|
||||
dmem_be => dmem_be,
|
||||
dmem_addr => dmem_addr,
|
||||
dmem_din => dmem_din,
|
||||
dmem_dout => dmem_dout,
|
||||
cop_ir => pipe_cop_ir,
|
||||
cop_ir_en => pipe_cop_ir_en,
|
||||
cop_din => pipe_cop_din,
|
||||
cop_dout => pipe_cop_dout,
|
||||
c0_ctrl_out => pipe_c0_ctrl_out,
|
||||
c0_ctrl_in => pipe_c0_ctrl_in
|
||||
);
|
||||
|
||||
pipe_ctrl_in <= cop0_ctrl_out.pipe;
|
||||
|
||||
inst_cop: cop
|
||||
GENERIC MAP
|
||||
(
|
||||
@@ -250,114 +256,49 @@ inst_cop: cop
|
||||
int => INT,
|
||||
ir_en => pipe_cop_ir_en,
|
||||
ir => pipe_cop_ir,
|
||||
ctrl_in => cop0_ctrl_in,
|
||||
ctrl_out => cop0_ctrl_out,
|
||||
ctrl_in => pipe_c0_ctrl_out,
|
||||
ctrl_out => pipe_c0_ctrl_in,
|
||||
dout => pipe_cop_din,
|
||||
din => pipe_cop_dout
|
||||
);
|
||||
|
||||
cop0_ctrl_in.pipe <= pipe_ctrl_out;
|
||||
cop0_ctrl_in.itlb_ctrl <= biu_ctrl_out.itlb_ctrl;
|
||||
cop0_ctrl_in.dtlb_ctrl <= biu_ctrl_out.dtlb_ctrl;
|
||||
|
||||
|
||||
inst_biu: biu
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => icache_size, -- words
|
||||
icache_line => icache_line, -- words
|
||||
dcache_size => dcache_size, -- words
|
||||
dcache_line => dcache_line, -- words
|
||||
WRITE_FIFO_SIZE => 4,
|
||||
WITH_TLB => WITH_TLB,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1
|
||||
icache_size => icache_size, -- words
|
||||
icache_line => icache_line, -- words
|
||||
dcache_size => dcache_size, -- words
|
||||
dcache_line => dcache_line -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
|
||||
clk => cpu_clk,
|
||||
busy => biu_busy,
|
||||
|
||||
imem_err => imem_err,
|
||||
dmem_err => dmem_err,
|
||||
|
||||
RST_I => biu_rst,
|
||||
CLK_I => CLK_I,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => DAT_I,
|
||||
MDAT_O => DAT_O,
|
||||
DAT_I => DAT_I,
|
||||
DAT_O => DAT_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
|
||||
ctrl_in => biu_ctrl_in,
|
||||
ctrl_out => biu_ctrl_out
|
||||
|
||||
cop0_ctrl_in => pipe_c0_ctrl_in,
|
||||
cpu_clk => cpu_clk,
|
||||
cpu_imem_err => imem_err,
|
||||
cpu_imem_rdy => imem_rdy,
|
||||
cpu_imem_en => imem_en,
|
||||
cpu_imem_addr => imem_addr,
|
||||
cpu_imem_din => imem_din,
|
||||
cpu_dmem_err => dmem_err,
|
||||
cpu_dmem_rdy => dmem_rdy,
|
||||
cpu_dmem_en => dmem_en,
|
||||
cpu_dmem_we => dmem_we,
|
||||
cpu_dmem_be => dmem_be,
|
||||
cpu_dmem_addr => dmem_addr,
|
||||
cpu_dmem_din => dmem_din,
|
||||
cpu_dmem_dout => dmem_dout
|
||||
);
|
||||
|
||||
biu_ctrl_in.icache <= cop0_ctrl_out.icache;
|
||||
biu_ctrl_in.dcache <= cop0_ctrl_out.dcache;
|
||||
biu_ctrl_in.itlb_ctrl <= cop0_ctrl_out.itlb_ctrl;
|
||||
biu_ctrl_in.dtlb_ctrl <= cop0_ctrl_out.dtlb_ctrl;
|
||||
-- biu_ctrl_in.itlb_qry <= pipe_ctrl_out.itlb_qry;
|
||||
-- biu_ctrl_in.dtlb_qry <= pipe_ctrl_out.dtlb_qry;
|
||||
|
||||
-------------------------------------------
|
||||
-- debug
|
||||
-------------------------------------------
|
||||
debug.imem_err <= imem_err;
|
||||
debug.dmem_err <= dmem_err;
|
||||
|
||||
debug_imem_din_register:
|
||||
process(cpu_clk)
|
||||
variable en_r: std_logic;
|
||||
variable addr_r: word_t;
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
debug.imem_din_vld <= '0';
|
||||
if biu_ctrl_out.icache_qry.rdy = '1' then
|
||||
if en_r = '1' then
|
||||
debug.imem_addr_reg <= addr_r;
|
||||
debug.imem_din_reg <= biu_ctrl_out.icache_qry.data;
|
||||
debug.imem_din_vld <= '1';
|
||||
end if;
|
||||
if biu_ctrl_in.icache_qry.en = '1' then
|
||||
addr_r := biu_ctrl_in.icache_qry.addr;
|
||||
end if;
|
||||
en_r := biu_ctrl_in.icache_qry.en;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
debug_dmem_din_register:
|
||||
process(cpu_clk)
|
||||
variable en_r: std_logic;
|
||||
variable we_r: std_logic;
|
||||
variable addr_r: word_t;
|
||||
variable dout_r: word_t;
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
debug.dmem_din_vld <= '0';
|
||||
debug.dmem_dout_vld <= '0';
|
||||
if biu_ctrl_out.dcache_qry.rdy = '1' then
|
||||
if en_r = '1' then
|
||||
debug.dmem_addr_reg <= addr_r;
|
||||
debug.dmem_din_reg <= biu_ctrl_out.dcache_qry.data;
|
||||
debug.dmem_din_vld <= not we_r;
|
||||
debug.dmem_dout_reg <= dout_r;
|
||||
debug.dmem_dout_vld <= we_r;
|
||||
end if;
|
||||
if biu_ctrl_in.dcache_qry.en = '1' then
|
||||
dout_r := biu_ctrl_in.dcache_qry.data;
|
||||
addr_r := biu_ctrl_in.dcache_qry.addr;
|
||||
end if;
|
||||
en_r := biu_ctrl_in.dcache_qry.en;
|
||||
we_r := biu_ctrl_in.dcache_qry.we;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end rtl;
|
||||
|
||||
@@ -26,18 +26,12 @@ use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package mips_types is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 14;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
constant TLB_PAGE_SIZE : positive := 4096;
|
||||
constant TLB_NUM_ASIDS : positive := 64;
|
||||
constant TLB_NUM_ENTRIES : positive := 32;
|
||||
constant REVISION : integer := 13;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
|
||||
--Types
|
||||
subtype instr_name_t is string(1 to 12);
|
||||
@@ -51,17 +45,9 @@ package mips_types is
|
||||
|
||||
type chip_debug_t is record
|
||||
imem_err : std_logic;
|
||||
imem_addr_reg : word_t;
|
||||
imem_din_reg : word_t;
|
||||
imem_din_vld : std_logic;
|
||||
dmem_err : std_logic;
|
||||
dmem_addr_reg : word_t;
|
||||
dmem_din_reg : word_t;
|
||||
dmem_din_vld : std_logic;
|
||||
dmem_dout_reg : word_t;
|
||||
dmem_dout_vld : std_logic;
|
||||
end record;
|
||||
|
||||
|
||||
type op_t is
|
||||
(
|
||||
op_illegal,
|
||||
@@ -173,14 +159,11 @@ package mips_types is
|
||||
type wptr_src_t is (wptr_src_imm, wptr_src_const);
|
||||
|
||||
type pc_t is record
|
||||
curr : word_t;
|
||||
last : word_t;
|
||||
nxt : word_t;
|
||||
pc_branch : word_t;
|
||||
pc_branch_revert : word_t;
|
||||
branch_take : std_logic;
|
||||
branch_not_taken : std_logic;
|
||||
plus4 : word_t;
|
||||
curr : word_t;
|
||||
last : word_t;
|
||||
nxt : word_t;
|
||||
pc_branch : word_t;
|
||||
branch_take : std_logic;
|
||||
end record;
|
||||
|
||||
type alu_outsel_t is
|
||||
@@ -244,12 +227,6 @@ package mips_types is
|
||||
syscall : STD_LOGIC;
|
||||
break : STD_LOGIC;
|
||||
illegal : STD_LOGIC;
|
||||
ITLB_MOD : STD_LOGIC;
|
||||
ITLB_LOAD : STD_LOGIC;
|
||||
ITLB_STORE : STD_LOGIC;
|
||||
DTLB_MOD : STD_LOGIC;
|
||||
DTLB_LOAD : STD_LOGIC;
|
||||
DTLB_STORE : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type exc_flags_t is record
|
||||
@@ -262,12 +239,6 @@ package mips_types is
|
||||
Sys : STD_LOGIC;
|
||||
Bp : STD_LOGIC;
|
||||
RI : STD_LOGIC;
|
||||
ITLB_MOD : STD_LOGIC;
|
||||
ITLB_LOAD : STD_LOGIC;
|
||||
ITLB_STORE : STD_LOGIC;
|
||||
DTLB_MOD : STD_LOGIC;
|
||||
DTLB_LOAD : STD_LOGIC;
|
||||
DTLB_STORE : STD_LOGIC;
|
||||
IBE : STD_LOGIC;
|
||||
DBE : STD_LOGIC;
|
||||
end record;
|
||||
@@ -278,108 +249,25 @@ package mips_types is
|
||||
cause : word_t;
|
||||
end record;
|
||||
|
||||
type icache_query_in_t is record
|
||||
en : std_logic;
|
||||
nc : std_logic;
|
||||
addr : word_t;
|
||||
end record;
|
||||
|
||||
type icache_query_out_t is record
|
||||
rdy : std_logic;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type dcache_query_in_t is record
|
||||
en : std_logic;
|
||||
we : std_logic;
|
||||
be : unsigned(3 downto 0);
|
||||
nc : std_logic;
|
||||
addr : word_t;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type dcache_query_out_t is record
|
||||
rdy : std_logic;
|
||||
data : word_t;
|
||||
end record;
|
||||
|
||||
type cache_ctrl_t is record
|
||||
inv_addr : word_t;
|
||||
inv_at : STD_LOGIC;
|
||||
inv_all : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type tlb_flags_t is record
|
||||
N : std_logic;
|
||||
D : std_logic;
|
||||
V : std_logic;
|
||||
type cop0_ctrl_in_t is record
|
||||
sdu : sdu_t;
|
||||
events : event_t;
|
||||
bd_wb : STD_LOGIC;
|
||||
epc_mem : word_t;
|
||||
epc_wb : word_t;
|
||||
imem_addr : word_t;
|
||||
dmem_addr : word_t;
|
||||
exc_req : STD_LOGIC;
|
||||
exc_ack : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type tlb_entry_lo_t is record
|
||||
PFN : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
G : std_logic;
|
||||
N : std_logic;
|
||||
D : std_logic;
|
||||
V : std_logic;
|
||||
end record;
|
||||
|
||||
type tlb_entry_hi_t is record
|
||||
VPN : unsigned (31 downto lg2(TLB_PAGE_SIZE));
|
||||
ASID : unsigned (lg2(TLB_NUM_ASIDS)-1 downto 0);
|
||||
end record;
|
||||
|
||||
type tlb_query_in_t is record
|
||||
vld : std_logic;
|
||||
write : std_logic;
|
||||
vaddr : word_t;
|
||||
end record;
|
||||
|
||||
type tlb_query_out_t is record
|
||||
vld : std_logic;
|
||||
paddr : word_t;
|
||||
miss : STD_LOGIC;
|
||||
dirty : std_logic;
|
||||
write : std_logic;
|
||||
flags : tlb_flags_t;
|
||||
end record;
|
||||
|
||||
type tlb_ctrl_in_t is record
|
||||
entry_we : STD_LOGIC;
|
||||
entry_re : STD_LOGIC;
|
||||
entry_rd_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
entry_wr_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
entry_lo : tlb_entry_lo_t;
|
||||
entry_hi : tlb_entry_hi_t;
|
||||
end record;
|
||||
|
||||
type tlb_ctrl_out_t is record
|
||||
entry_vld : std_logic;
|
||||
entry_lo : tlb_entry_lo_t;
|
||||
entry_hi : tlb_entry_hi_t;
|
||||
entry_prb_idx : unsigned (lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
end record;
|
||||
|
||||
type biu_ctrl_in_t is record
|
||||
itlb_ctrl : tlb_ctrl_in_t;
|
||||
dtlb_ctrl : tlb_ctrl_in_t;
|
||||
icache : cache_ctrl_t;
|
||||
dcache : cache_ctrl_t;
|
||||
itlb_qry : tlb_query_in_t;
|
||||
dtlb_qry : tlb_query_in_t;
|
||||
icache_qry : icache_query_in_t;
|
||||
dcache_qry : dcache_query_in_t;
|
||||
end record;
|
||||
|
||||
type biu_ctrl_out_t is record
|
||||
itlb_ctrl : tlb_ctrl_out_t;
|
||||
dtlb_ctrl : tlb_ctrl_out_t;
|
||||
itlb_qry : tlb_query_out_t;
|
||||
dtlb_qry : tlb_query_out_t;
|
||||
icache_qry : icache_query_out_t;
|
||||
dcache_qry : dcache_query_out_t;
|
||||
end record;
|
||||
|
||||
type pipe_ctrl_in_t is record
|
||||
type cop0_ctrl_out_t is record
|
||||
EB : STD_LOGIC;
|
||||
exc_inject : STD_LOGIC;
|
||||
exc_commit : STD_LOGIC;
|
||||
@@ -389,29 +277,6 @@ package mips_types is
|
||||
NMI : STD_LOGIC;
|
||||
int : STD_LOGIC;
|
||||
exc_vec : word_t;
|
||||
end record;
|
||||
|
||||
type pipe_ctrl_out_t is record
|
||||
sdu : sdu_t;
|
||||
events : event_t;
|
||||
bd_wb : STD_LOGIC;
|
||||
epc_wb : word_t;
|
||||
imem_addr : word_t;
|
||||
dmem_addr : word_t;
|
||||
exc_req : STD_LOGIC;
|
||||
exc_ack : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type cop0_ctrl_in_t is record
|
||||
pipe : pipe_ctrl_out_t;
|
||||
itlb_ctrl : tlb_ctrl_out_t;
|
||||
dtlb_ctrl : tlb_ctrl_out_t;
|
||||
end record;
|
||||
|
||||
type cop0_ctrl_out_t is record
|
||||
pipe : pipe_ctrl_in_t;
|
||||
itlb_ctrl : tlb_ctrl_in_t;
|
||||
dtlb_ctrl : tlb_ctrl_in_t;
|
||||
icache : cache_ctrl_t;
|
||||
dcache : cache_ctrl_t;
|
||||
end record;
|
||||
@@ -472,93 +337,76 @@ package mips_types is
|
||||
type ID_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
IR : word_t;
|
||||
epc : word_t;
|
||||
op : op_t;
|
||||
pcn : word_t;
|
||||
epc : word_t;
|
||||
jimm32 : word_t;
|
||||
bimm18 : word_t;
|
||||
imm : word_t;
|
||||
shamt : shamt_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
va : word_t;
|
||||
reg_write : STD_LOGIC;
|
||||
reg_a_rptr : reg_ptr_t;
|
||||
reg_b_rptr : reg_ptr_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
itlb_qry : tlb_query_out_t;
|
||||
end record;
|
||||
|
||||
type EX_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
IR : word_t;
|
||||
epc : word_t;
|
||||
op : op_t;
|
||||
pcn : word_t;
|
||||
epc : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
shift_ctrl : shift_ctrl_t;
|
||||
alu_op1 : word_t;
|
||||
alu_op2 : word_t;
|
||||
alu_op2_s : word_t;
|
||||
alu_flags : alu_flags_t;
|
||||
result : word_t;
|
||||
reg_write : STD_LOGIC;
|
||||
reg_we : STD_LOGIC;
|
||||
wreg_we : STD_LOGIC;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_a_rptr : reg_ptr_t;
|
||||
reg_b_rptr : reg_ptr_t;
|
||||
va : word_t;
|
||||
dmem_en : STD_LOGIC;
|
||||
pa_off : unsigned(1 downto 0);
|
||||
events_in : event_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
branch_not_taken : std_logic;
|
||||
dtlb_qry : tlb_query_out_t;
|
||||
end record;
|
||||
|
||||
type MEM_t is record
|
||||
nop : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
op : op_t;
|
||||
epc : word_t;
|
||||
pcn : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
result_in : word_t;
|
||||
epc : word_t;
|
||||
ctrl : ctrl_lines_t;
|
||||
ex_result : word_t;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_we : STD_LOGIC;
|
||||
wreg_we : STD_LOGIC;
|
||||
data : word_t;
|
||||
va : word_t;
|
||||
pa_off : unsigned(1 downto 0);
|
||||
events_in : event_t;
|
||||
events : event_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
branch_not_taken : std_logic;
|
||||
end record;
|
||||
|
||||
type WB_t is record
|
||||
nop : STD_LOGIC;
|
||||
epc : word_t;
|
||||
reg_a : word_t;
|
||||
reg_b : word_t;
|
||||
result : word_t;
|
||||
bd : STD_LOGIC;
|
||||
exc : std_logic;
|
||||
exc_last : std_logic;
|
||||
events : event_t;
|
||||
op : op_t;
|
||||
reg_wptr : reg_ptr_t;
|
||||
reg_we : STD_LOGIC;
|
||||
va : word_t;
|
||||
bcu_flags : bcu_flags_t;
|
||||
wreg_we : STD_LOGIC;
|
||||
data : word_t;
|
||||
bd : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
|
||||
@@ -574,7 +422,9 @@ package mips_types is
|
||||
function events_clr return event_t;
|
||||
function event_is_active(e : event_t) return std_logic;
|
||||
function "or" (a, b : event_t) return event_t;
|
||||
function "or" (a, b : tlb_flags_t) return tlb_flags_t;
|
||||
|
||||
function lg2(x : natural) return natural;
|
||||
function po2(x : natural) return natural;
|
||||
|
||||
end mips_types;
|
||||
|
||||
@@ -735,6 +585,9 @@ package body mips_types is
|
||||
elsif word2_en = '1' then
|
||||
sign := signed and x(15);
|
||||
result := (31 downto 16 => sign) & x(15 downto 0);
|
||||
elsif word4_en = '1' then
|
||||
sign := signed and x(7);
|
||||
result := (31 downto 8 => sign) & x(7 downto 0);
|
||||
else
|
||||
sign := signed and x(7);
|
||||
result := (31 downto 8 => sign) & x(7 downto 0);
|
||||
@@ -758,12 +611,6 @@ package body mips_types is
|
||||
result.syscall := '0';
|
||||
result.break := '0';
|
||||
result.illegal := '0';
|
||||
result.ITLB_MOD := '0';
|
||||
result.ITLB_LOAD := '0';
|
||||
result.ITLB_STORE := '0';
|
||||
result.DTLB_MOD := '0';
|
||||
result.DTLB_LOAD := '0';
|
||||
result.DTLB_STORE := '0';
|
||||
|
||||
return result;
|
||||
|
||||
@@ -786,12 +633,6 @@ package body mips_types is
|
||||
result := result or e.syscall;
|
||||
result := result or e.break;
|
||||
result := result or e.illegal;
|
||||
result := result or e.ITLB_MOD;
|
||||
result := result or e.ITLB_LOAD;
|
||||
result := result or e.ITLB_STORE;
|
||||
result := result or e.DTLB_MOD;
|
||||
result := result or e.DTLB_LOAD;
|
||||
result := result or e.DTLB_STORE;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -812,28 +653,23 @@ package body mips_types is
|
||||
result.syscall := a.syscall or b.syscall;
|
||||
result.break := a.break or b.break;
|
||||
result.illegal := a.illegal or b.illegal;
|
||||
result.ITLB_MOD := a.ITLB_MOD or b.ITLB_MOD;
|
||||
result.ITLB_LOAD := a.ITLB_LOAD or b.ITLB_LOAD;
|
||||
result.ITLB_STORE := a.ITLB_STORE or b.ITLB_STORE;
|
||||
result.DTLB_MOD := a.DTLB_MOD or b.DTLB_MOD;
|
||||
result.DTLB_LOAD := a.DTLB_LOAD or b.DTLB_LOAD;
|
||||
result.DTLB_STORE := a.DTLB_STORE or b.DTLB_STORE;
|
||||
|
||||
return result;
|
||||
|
||||
end "or";
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function "or" (a, b : tlb_flags_t) return tlb_flags_t is
|
||||
variable result : tlb_flags_t;
|
||||
function lg2(x : natural) return natural is
|
||||
begin
|
||||
result.N := a.N or b.N;
|
||||
result.D := a.D or b.D;
|
||||
result.V := a.V or b.V;
|
||||
|
||||
return result;
|
||||
|
||||
end "or";
|
||||
return natural(ceil(log2(real(x))));
|
||||
end lg2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
function po2(x : natural) return natural is
|
||||
begin
|
||||
|
||||
return 2**lg2(x);
|
||||
end po2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end mips_types;
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: Types, constants and functions for JIPS
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.NUMERIC_STD.ALL;
|
||||
use IEEE.MATH_REAL.ALL;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package mips_util_pkg is
|
||||
|
||||
|
||||
function to_mips_01(x : unsigned) return unsigned;
|
||||
function lg2(x : natural) return natural;
|
||||
function po2(x : natural) return natural;
|
||||
|
||||
end mips_util_pkg;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
package body mips_util_pkg is
|
||||
|
||||
function to_mips_01(x : unsigned) return unsigned is
|
||||
variable result : unsigned (x'left downto x'right);
|
||||
begin
|
||||
for i in x'left downto x'right loop
|
||||
if x(i) = '1' then
|
||||
result(i) := '1';
|
||||
else
|
||||
result(i) := '0';
|
||||
end if;
|
||||
end loop;
|
||||
return result;
|
||||
end to_mips_01;
|
||||
|
||||
function lg2(x : natural) return natural is
|
||||
begin
|
||||
return natural(ceil(log2(real(x))));
|
||||
end lg2;
|
||||
|
||||
function po2(x : natural) return natural is
|
||||
begin
|
||||
|
||||
return 2**lg2(x);
|
||||
end po2;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
end mips_util_pkg;
|
||||
|
||||
@@ -1,410 +0,0 @@
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY tb_biu IS
|
||||
END tb_biu;
|
||||
|
||||
ARCHITECTURE behavior OF tb_biu IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
signal CLK : std_logic := '1';
|
||||
signal RST : std_logic := '1';
|
||||
signal INT_O : std_logic;
|
||||
signal CYC_O : std_logic;
|
||||
signal STB_O : std_logic;
|
||||
signal WE_O : std_logic;
|
||||
signal SEL_O : unsigned(3 downto 0) := (others => '1');
|
||||
signal ACK_I : std_logic := '0';
|
||||
signal MRDY_O : std_logic := '1';
|
||||
signal SRDY_I : std_logic := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_I : unsigned(31 downto 0) := (others => '-');
|
||||
signal MDAT_O : unsigned(31 downto 0) := (others => '-');
|
||||
|
||||
signal index_in : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_we : STD_LOGIC := '0';
|
||||
signal entry_lo_in : tlb_entry_lo_t;
|
||||
signal entry_hi_in : tlb_entry_hi_t;
|
||||
|
||||
signal index_out : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal entry_re : STD_LOGIC := '0';
|
||||
signal entry_lo_out : tlb_entry_lo_t;
|
||||
signal entry_hi_out : tlb_entry_hi_t;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_imem_err : STD_LOGIC := '0';
|
||||
signal cpu_imem_en : STD_LOGIC := '0';
|
||||
signal cpu_imem_addr : word_t := (others => '-');
|
||||
signal cpu_imem_dout : word_t;
|
||||
signal cpu_imem_rdy : STD_LOGIC;
|
||||
|
||||
signal cpu_dmem_err : STD_LOGIC := '0';
|
||||
signal cpu_dmem_en : STD_LOGIC := '0';
|
||||
signal cpu_dmem_we : STD_LOGIC := '0';
|
||||
signal cpu_dmem_addr : word_t := (others => '-');
|
||||
signal cpu_dmem_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_dmem_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_dmem_dout : word_t;
|
||||
signal cpu_dmem_rdy : STD_LOGIC;
|
||||
|
||||
-- BIU control
|
||||
signal ctrl_in : biu_ctrl_in_t;
|
||||
signal ctrl_out : biu_ctrl_out_t;
|
||||
|
||||
type op_descr_t is (op_idle, op_entry_i_write, op_entry_d_write, op_cpu_i_read, op_cpu_d_read, op_cpu_d_write);
|
||||
signal op_descr : op_descr_t := op_idle;
|
||||
|
||||
signal cpu_imem_din_reg : word_t;
|
||||
signal cpu_imem_din_vld : STD_LOGIC;
|
||||
signal cpu_dmem_din_reg : word_t;
|
||||
signal cpu_dmem_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_biu: entity work.biu
|
||||
GENERIC MAP
|
||||
(
|
||||
ICACHE_SIZE => 1024, -- words
|
||||
ICACHE_LINE => 8, -- words
|
||||
DCACHE_SIZE => 1024, -- words
|
||||
DCACHE_LINE => 8, -- words
|
||||
WRITE_FIFO_SIZE => 4, -- words
|
||||
WITH_TLB => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk => CLK,
|
||||
|
||||
imem_err => cpu_imem_err,
|
||||
imem_rdy => cpu_imem_rdy,
|
||||
imem_en => cpu_imem_en,
|
||||
imem_addr => cpu_imem_addr,
|
||||
imem_dout => cpu_imem_dout,
|
||||
dmem_err => cpu_dmem_err,
|
||||
dmem_rdy => cpu_dmem_rdy,
|
||||
dmem_en => cpu_dmem_en,
|
||||
dmem_we => cpu_dmem_we,
|
||||
dmem_be => cpu_dmem_be,
|
||||
dmem_dout => cpu_dmem_dout,
|
||||
dmem_din => cpu_dmem_din,
|
||||
dmem_addr => cpu_dmem_addr,
|
||||
|
||||
RST_I => RST,
|
||||
CLK_I => CLK,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
|
||||
ctrl_in => ctrl_in,
|
||||
ctrl_out => ctrl_out
|
||||
|
||||
);
|
||||
|
||||
|
||||
inst_rom_wb: entity work.rom_wb
|
||||
-- GENERIC MAP
|
||||
-- (
|
||||
-- NUM_WORDS => 256
|
||||
-- )
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => CLK,
|
||||
RST_I => RST,
|
||||
CYC_I => CYC_O,
|
||||
STB_I => STB_O,
|
||||
-- SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_I,
|
||||
SRDY_O => SRDY_I,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
-- DAT_I => MDAT_O,
|
||||
DAT_O => MDAT_I
|
||||
);
|
||||
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
end process;
|
||||
|
||||
cpu_imem_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_imem_din_vld <= '0';
|
||||
if en2 = '1' and cpu_imem_rdy = '1' then
|
||||
cpu_imem_din_reg <= cpu_imem_dout;
|
||||
cpu_imem_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_imem_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cpu_dmem_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_dmem_din_vld <= '0';
|
||||
if en2 = '1' and cpu_dmem_rdy = '1' then
|
||||
cpu_dmem_din_reg <= cpu_dmem_dout;
|
||||
cpu_dmem_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_dmem_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
ctrl_in.icache.inv_addr <= X"BEEF_BABE";
|
||||
ctrl_in.icache.inv_at <= '0';
|
||||
ctrl_in.icache.inv_all <= '0';
|
||||
|
||||
ctrl_in.dcache.inv_addr <= X"BEEF_BABE";
|
||||
ctrl_in.dcache.inv_at <= '0';
|
||||
ctrl_in.dcache.inv_all <= '0';
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable result : unsigned(31 downto 0);
|
||||
|
||||
procedure cmd_entry_i_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
op_descr <= op_entry_i_write;
|
||||
|
||||
ctrl_in.itlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
ctrl_in.itlb.entry_hi.vpn <= vpn;
|
||||
ctrl_in.itlb.entry_hi.asid <= asid;
|
||||
|
||||
ctrl_in.itlb.entry_lo.pfn <= pfn;
|
||||
ctrl_in.itlb.entry_lo.n <= n;
|
||||
ctrl_in.itlb.entry_lo.d <= d;
|
||||
ctrl_in.itlb.entry_lo.v <= v;
|
||||
ctrl_in.itlb.entry_lo.g <= g;
|
||||
|
||||
ctrl_in.itlb.entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
ctrl_in.itlb.entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_i_write;
|
||||
|
||||
procedure cmd_entry_d_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
op_descr <= op_entry_d_write;
|
||||
ctrl_in.dtlb.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
ctrl_in.dtlb.entry_hi.vpn <= vpn;
|
||||
ctrl_in.dtlb.entry_hi.asid <= asid;
|
||||
|
||||
ctrl_in.dtlb.entry_lo.pfn <= pfn;
|
||||
ctrl_in.dtlb.entry_lo.n <= n;
|
||||
ctrl_in.dtlb.entry_lo.d <= d;
|
||||
ctrl_in.dtlb.entry_lo.v <= v;
|
||||
ctrl_in.dtlb.entry_lo.g <= g;
|
||||
|
||||
ctrl_in.dtlb.entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
ctrl_in.dtlb.entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_d_write;
|
||||
|
||||
procedure cpu_i_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_i_read;
|
||||
cpu_imem_addr <= addr;
|
||||
cpu_imem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_imem_rdy = '1';
|
||||
cpu_imem_en <= '0';
|
||||
|
||||
end procedure cpu_i_read;
|
||||
|
||||
procedure cpu_d_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_d_read;
|
||||
cpu_dmem_addr <= addr;
|
||||
cpu_dmem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
|
||||
cpu_dmem_en <= '0';
|
||||
|
||||
end procedure cpu_d_read;
|
||||
|
||||
procedure cpu_d_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
op_descr <= op_cpu_d_write;
|
||||
cpu_dmem_we <= '1';
|
||||
cpu_dmem_addr <= addr;
|
||||
cpu_dmem_din <= data;
|
||||
cpu_dmem_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_dmem_rdy = '1';
|
||||
cpu_dmem_en <= '0';
|
||||
|
||||
end procedure cpu_d_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_imem_rdy = '1' and cpu_dmem_rdy = '1';
|
||||
|
||||
cmd_entry_i_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_i_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
cmd_entry_d_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_d_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
cpu_i_read(X"BFC0_0200");
|
||||
cpu_i_read(X"BFC0_0180");
|
||||
cpu_d_read(X"BFC0_0200");
|
||||
|
||||
cpu_i_read(X"8000_0204");
|
||||
cpu_i_read(X"8000_0300");
|
||||
cpu_i_read(X"8000_0304");
|
||||
cpu_i_read(X"8000_0308");
|
||||
|
||||
cpu_i_read(X"9000_0208");
|
||||
cpu_i_read(X"9000_030C");
|
||||
cpu_i_read(X"9100_0310");
|
||||
cpu_i_read(X"9200_0314");
|
||||
|
||||
cpu_i_read(X"A000_020C");
|
||||
cpu_i_read(X"A000_0318");
|
||||
cpu_i_read(X"A100_031C");
|
||||
cpu_i_read(X"A200_0320");
|
||||
|
||||
cpu_i_read(X"B000_0210");
|
||||
cpu_i_read(X"B000_0324");
|
||||
cpu_i_read(X"B000_0328");
|
||||
cpu_i_read(X"B000_032C");
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
cpu_i_read(X"0000_1420");
|
||||
cpu_i_read(X"0000_2440");
|
||||
cpu_i_read(X"0000_3460");
|
||||
cpu_i_read(X"0000_4480");
|
||||
cpu_i_read(X"0000_54A0");
|
||||
cpu_i_read(X"0000_64C0");
|
||||
cpu_i_read(X"0000_74E0");
|
||||
cpu_i_read(X"0000_8500");
|
||||
cpu_i_read(X"0000_9520");
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
cpu_i_read(X"0000_1420");
|
||||
cpu_i_read(X"0000_2440");
|
||||
cpu_i_read(X"0000_3460");
|
||||
cpu_i_read(X"0000_4480");
|
||||
cpu_i_read(X"0000_54A0");
|
||||
cpu_i_read(X"0000_64C0");
|
||||
cpu_i_read(X"0000_74E0");
|
||||
|
||||
|
||||
cpu_i_read(X"0000_0400");
|
||||
|
||||
cpu_i_read(X"0000_0410");
|
||||
cpu_i_read(X"0000_0404");
|
||||
cpu_i_read(X"0000_0408");
|
||||
cpu_i_read(X"0000_0404");
|
||||
cpu_i_read(X"0000_0434");
|
||||
cpu_i_read(X"0000_0400");
|
||||
|
||||
|
||||
---------------------------------------------
|
||||
cpu_d_read(X"BFC0_0200");
|
||||
cpu_d_read(X"BFC0_0180");
|
||||
|
||||
cpu_d_read(X"8000_0204");
|
||||
cpu_d_read(X"8000_0300");
|
||||
cpu_d_read(X"8000_0304");
|
||||
cpu_d_read(X"8000_0308");
|
||||
|
||||
cpu_d_read(X"9000_0208");
|
||||
cpu_d_read(X"9000_030C");
|
||||
cpu_d_read(X"9100_0310");
|
||||
cpu_d_read(X"9200_0314");
|
||||
|
||||
cpu_d_read(X"A000_020C");
|
||||
cpu_d_read(X"A000_0318");
|
||||
cpu_d_read(X"A100_031C");
|
||||
cpu_d_read(X"A200_0320");
|
||||
|
||||
cpu_d_read(X"B000_0210");
|
||||
cpu_d_read(X"B000_0324");
|
||||
cpu_d_read(X"B000_0328");
|
||||
cpu_d_read(X"B000_032C");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
cpu_d_read(X"0000_1420");
|
||||
cpu_d_read(X"0000_2440");
|
||||
cpu_d_read(X"0000_3460");
|
||||
cpu_d_read(X"0000_4480");
|
||||
cpu_d_read(X"0000_54A0");
|
||||
cpu_d_read(X"0000_64C0");
|
||||
cpu_d_read(X"0000_74E0");
|
||||
cpu_d_read(X"0000_8500");
|
||||
cpu_d_read(X"0000_9520");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
cpu_d_read(X"0000_1420");
|
||||
cpu_d_read(X"0000_2440");
|
||||
cpu_d_read(X"0000_3460");
|
||||
cpu_d_read(X"0000_4480");
|
||||
cpu_d_read(X"0000_54A0");
|
||||
cpu_d_read(X"0000_64C0");
|
||||
cpu_d_read(X"0000_74E0");
|
||||
cpu_d_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
cpu_d_read(X"0000_0400");
|
||||
|
||||
cpu_d_read(X"0000_0410");
|
||||
cpu_d_read(X"0000_0404");
|
||||
cpu_d_read(X"0000_0408");
|
||||
cpu_d_write(X"0000_0404", X"5555_5555");
|
||||
cpu_d_read(X"0000_0404");
|
||||
cpu_d_write(X"0000_0404", X"6666_6666");
|
||||
cpu_d_read(X"0000_0434");
|
||||
cpu_d_write(X"0000_0400", X"1111_1111");
|
||||
cpu_d_write(X"0000_0404", X"2222_2222");
|
||||
cpu_d_write(X"0000_0408", X"3333_3333");
|
||||
cpu_d_write(X"0000_040C", X"4444_4444");
|
||||
cpu_d_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,265 +0,0 @@
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
ENTITY tb_cam IS
|
||||
END tb_cam;
|
||||
|
||||
ARCHITECTURE behavior OF tb_cam IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant DATA_WIDTH : integer := 20;
|
||||
constant CAM_NUM_ENTRIES : integer := 32;
|
||||
|
||||
signal CLK_O : std_logic := '1';
|
||||
signal RST_O : std_logic := '1';
|
||||
signal cam_we : std_logic := '0';
|
||||
signal cam_re : std_logic := '0';
|
||||
signal cam_vld : std_logic := '0';
|
||||
signal cam_rdy : std_logic := '-';
|
||||
|
||||
signal cam_addr : unsigned(lg2(CAM_NUM_ENTRIES)-1 downto 0) := (others => '0');
|
||||
signal cam_rtag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
signal cam_wtag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
|
||||
signal cam_hit : unsigned (CAM_NUM_ENTRIES-1 downto 0);
|
||||
signal cam_hit_vld : std_logic := '-';
|
||||
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_cam: entity work.cam
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => CAM_NUM_ENTRIES,
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
CAM_RAM_MAX_WIDTH => 15
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_O,
|
||||
clk => CLK_O,
|
||||
clk_rd => CLK_O,
|
||||
|
||||
rdy => cam_rdy,
|
||||
|
||||
re => cam_re,
|
||||
we => cam_we,
|
||||
vld => cam_vld,
|
||||
addr => cam_addr,
|
||||
tag_rd => cam_rtag,
|
||||
tag_wr => cam_wtag,
|
||||
|
||||
hit_vld => cam_hit_vld,
|
||||
hit => cam_hit
|
||||
|
||||
);
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK_O <= not CLK_O;
|
||||
end process;
|
||||
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable tag : unsigned(DATA_WIDTH-1 downto 0) := (others => '0');
|
||||
|
||||
procedure cam_entry_write(index : integer; data : unsigned; valid : std_logic) is
|
||||
begin
|
||||
|
||||
cam_wtag <= data;
|
||||
cam_addr <= to_unsigned(index, lg2(CAM_NUM_ENTRIES));
|
||||
cam_vld <= valid;
|
||||
cam_we <= '1';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_we <= '0';
|
||||
|
||||
end procedure cam_entry_write;
|
||||
|
||||
procedure cam_lookup(data : unsigned) is
|
||||
begin
|
||||
|
||||
cam_rtag <= data;
|
||||
cam_re <= '1';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_re <= '0';
|
||||
|
||||
end procedure cam_lookup;
|
||||
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST_O <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0100_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0100_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0010_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0010_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0001_0";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0001_0";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0000_1";
|
||||
end loop;
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0000_1";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_entry_write(i, tag, '1');
|
||||
tag := tag + X"0102_3";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
tag := X"CAF0_0";
|
||||
for i in 0 to CAM_NUM_ENTRIES-1 loop
|
||||
cam_lookup(tag);
|
||||
tag := tag + X"0102_3";
|
||||
end loop;
|
||||
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
RST_O <= '1';
|
||||
wait for 6*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O);
|
||||
RST_O <= '0';
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
-----------------------
|
||||
-- overwrite
|
||||
cam_entry_write(2, X"BEEF_2", '1');
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
|
||||
-- overwrite entry
|
||||
cam_entry_write(2, X"CAFE_2", '1');
|
||||
-- new entry
|
||||
cam_entry_write(3, X"CAFE_3", '1');
|
||||
cam_entry_write(4, X"CAFE_4", '1');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(1, X"CAFE_1", '0');
|
||||
cam_entry_write(2, X"CAFE_2", '0');
|
||||
cam_entry_write(3, X"CAFE_3", '0');
|
||||
cam_entry_write(4, X"CAFE_4", '0');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_lookup(X"BEEF_2");
|
||||
cam_lookup(X"CAFE_1");
|
||||
cam_lookup(X"CAFE_2");
|
||||
cam_lookup(X"CAFE_3");
|
||||
cam_lookup(X"CAFE_4");
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(1, X"CAFE_1", '1');
|
||||
cam_entry_write(2, X"CAFE_2", '1');
|
||||
cam_entry_write(3, X"CAFE_3", '1');
|
||||
cam_entry_write(4, X"CAFE_4", '1');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_lookup(X"CAFE_1");
|
||||
cam_lookup(X"CAFE_2");
|
||||
cam_lookup(X"CAFE_3");
|
||||
cam_lookup(X"CAFE_4");
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
cam_entry_write(7, X"CAFE_7", '0');
|
||||
|
||||
wait for 8*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and cam_rdy = '1';
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -1,211 +0,0 @@
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
ENTITY tb_tlb IS
|
||||
END tb_tlb;
|
||||
|
||||
ARCHITECTURE behavior OF tb_tlb IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
signal CLK_O : std_logic := '1';
|
||||
signal RST_O : std_logic := '1';
|
||||
signal ce : std_logic := '1';
|
||||
|
||||
signal tlb_rdy : std_logic;
|
||||
|
||||
signal tlb_ctrl_in : tlb_ctrl_in_t;
|
||||
signal tlb_ctrl_out : tlb_ctrl_out_t;
|
||||
signal tlb_query_in : tlb_query_in_t;
|
||||
signal tlb_query_out : tlb_query_out_t;
|
||||
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_uut : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
USE_TLB => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST_O,
|
||||
clk => CLK_O,
|
||||
ce => ce,
|
||||
|
||||
rdy => tlb_rdy,
|
||||
|
||||
ctrl_in => tlb_ctrl_in,
|
||||
ctrl_out => tlb_ctrl_out,
|
||||
|
||||
query_in => tlb_query_in,
|
||||
query_out => tlb_query_out
|
||||
|
||||
);
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK_O <= not CLK_O;
|
||||
end process;
|
||||
|
||||
STIMULUS: process
|
||||
|
||||
variable result : unsigned(31 downto 0);
|
||||
|
||||
procedure cmd_entry_write(index : integer; asid, vpn, pfn : unsigned; g, n, d, v : std_logic) is
|
||||
begin
|
||||
|
||||
tlb_ctrl_in.entry_wr_idx <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
tlb_ctrl_in.entry_hi.vpn <= vpn;
|
||||
tlb_ctrl_in.entry_hi.asid <= asid;
|
||||
|
||||
tlb_ctrl_in.entry_lo.pfn <= pfn;
|
||||
tlb_ctrl_in.entry_lo.g <= g;
|
||||
tlb_ctrl_in.entry_lo.n <= n;
|
||||
tlb_ctrl_in.entry_lo.d <= d;
|
||||
tlb_ctrl_in.entry_lo.v <= v;
|
||||
|
||||
tlb_ctrl_in.entry_we <= '1';
|
||||
wait until rising_edge(CLK_O) and tlb_rdy = '1';
|
||||
tlb_ctrl_in.entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_write;
|
||||
|
||||
procedure cmd_read_single(addr : unsigned) is
|
||||
begin
|
||||
|
||||
end procedure cmd_read_single;
|
||||
|
||||
begin
|
||||
|
||||
tlb_ctrl_in.entry_we <= '0';
|
||||
tlb_ctrl_in.entry_re <= '0';
|
||||
tlb_query_in.vld <= '0';
|
||||
tlb_query_in.write <= '0';
|
||||
tlb_query_in.vaddr <= X"BFC0_CAFE";
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST_O <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK_O) and tlb_rdy = '1';
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
tlb_query_in.vaddr <= X"9FC0_CAFE";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"00DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(1, "110000", X"0000_1", X"01DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(2, "110000", X"0000_2", X"02DE_F", '0', '0', '0', '0');
|
||||
cmd_entry_write(3, "110000", X"0000_3", X"43DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(4, "100000", X"0000_4", X"44DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(5, "110000", X"0000_5", X"65DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(6, "100000", X"0000_6", X"66DE_F", '1', '0', '0', '1');
|
||||
cmd_entry_write(7, "110000", X"0000_7", X"67DE_F", '0', '0', '0', '1');
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
|
||||
tlb_query_in.vaddr <= X"8000_BABE";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"8000_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"8100_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"8200_1234";
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"9000_BABE";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"9000_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"9100_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"9200_1234";
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"A000_BABE";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"A000_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"A100_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"A200_1234";
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"B000_BABE";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"B000_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"B100_1234";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"B200_1234";
|
||||
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= X"0000_0CAF";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vaddr <= tlb_query_in.vaddr + X"1000";
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
tlb_query_in.vaddr <= X"0000_0CAF";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
tlb_query_in.write <= '1';
|
||||
tlb_query_in.vaddr <= X"0008_0CAF";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '1';
|
||||
tlb_query_in.write <= '1';
|
||||
tlb_query_in.vaddr <= X"0000_0CAF";
|
||||
wait until rising_edge(CLK_O);
|
||||
tlb_query_in.vld <= '0';
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -25,7 +25,6 @@
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
USE std.textio.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
@@ -34,18 +33,21 @@ use work.async_types.all;
|
||||
use work.async_defs.all;
|
||||
|
||||
ENTITY tb_mips_top IS
|
||||
Generic
|
||||
(
|
||||
app : string := "apps/hello.elf.flash.bin"
|
||||
);
|
||||
|
||||
END tb_mips_top;
|
||||
|
||||
ARCHITECTURE behavior OF tb_mips_top IS
|
||||
|
||||
constant SYS_FREQ : real := 100.0;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
|
||||
constant WITH_TLB : boolean := false;
|
||||
constant KSEG_01_TRANSLATED : boolean := false;
|
||||
signal debug : chip_debug_t;
|
||||
signal tb_fin : STD_LOGIC := '0';
|
||||
constant SRAM_ADDR_WIDTH : integer := 18; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 18; -- bits
|
||||
|
||||
signal debug : unsigned(1 downto 0);
|
||||
|
||||
-- Master
|
||||
signal nmi : STD_LOGIC := '0';
|
||||
@@ -116,45 +118,9 @@ ARCHITECTURE behavior OF tb_mips_top IS
|
||||
signal mem_area : mem_area_t;
|
||||
|
||||
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
||||
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
||||
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
||||
|
||||
subtype nibble_t is unsigned (3 downto 0);
|
||||
signal sram_memory_content : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
||||
signal flash_memory_content : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
||||
|
||||
function to_character(x : nibble_t) return character is
|
||||
type cnv_tbl_t is array (0 to 15) of character;
|
||||
variable cnv_tbl : cnv_tbl_t := "0123456789ABCDEF";
|
||||
variable result : character;
|
||||
begin
|
||||
for i in nibble_t'low to nibble_t'high loop
|
||||
result := '0';
|
||||
if x(i) /= '0' and x(i) /= '1' then
|
||||
result := 'X';
|
||||
end if;
|
||||
end loop;
|
||||
|
||||
if result = '0' then
|
||||
result := cnv_tbl(to_integer(x));
|
||||
end if;
|
||||
|
||||
return result;
|
||||
end to_character;
|
||||
|
||||
|
||||
function to_string(x : word_t ) return string is
|
||||
variable result : string (1 to 8);
|
||||
variable j : integer := 32;
|
||||
variable nibble : nibble_t;
|
||||
begin
|
||||
for i in 1 to 8 loop
|
||||
nibble := x(j-1 downto j-4);
|
||||
j := j - 4;
|
||||
result(i) := to_character(nibble);
|
||||
end loop;
|
||||
return result;
|
||||
|
||||
end to_string;
|
||||
|
||||
BEGIN
|
||||
|
||||
------------------------------------------------------------------
|
||||
@@ -167,46 +133,6 @@ CLK_GEN: process
|
||||
------------------------------------------------------------------
|
||||
-- Memory mux
|
||||
------------------------------------------------------------------
|
||||
-- rom_u : Virtual = 0xBFC00000, Physical = 0x1FC00000
|
||||
-- rom_c : Virtual = 0x9FC00000, Physical = 0x1FC00000
|
||||
|
||||
-- ram_u : Virtual = 0xA0000000, Physical = 0x00000000
|
||||
-- ram_c : Virtual = 0x80000000, Physical = 0x00000000
|
||||
-- flash_u : Virtual = 0xA4000000, Physical = 0x04000000
|
||||
-- flash_c : Virtual = 0x88000000, Physical = 0x08000000
|
||||
-- io_u : Virtual = 0xA8000000, Physical = 0x0C000000
|
||||
-- io_c : Virtual = 0x88000000, Physical = 0x0C000000
|
||||
|
||||
gen_mem_mux_translate:
|
||||
if KSEG_01_TRANSLATED = true generate
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
mem_area <= mem_dead;
|
||||
flash_page_mode_en <= '0';
|
||||
if ADDR_O(31 downto 28) = X"0" then
|
||||
if ADDR_O(27 downto 26) = "00" then
|
||||
mem_area <= mem_sram;
|
||||
elsif ADDR_O(27 downto 26) = "01" then
|
||||
mem_area <= mem_flash;
|
||||
elsif ADDR_O(27 downto 26) = "10" then
|
||||
mem_area <= mem_flash;
|
||||
flash_page_mode_en <= '1';
|
||||
elsif ADDR_O(27 downto 26) = "11" then
|
||||
if ADDR_O(18 downto 16) = "000" then
|
||||
mem_area <= mem_gpio;
|
||||
elsif ADDR_O(18 downto 16) = "001" then
|
||||
mem_area <= mem_uart;
|
||||
end if;
|
||||
end if;
|
||||
elsif (ADDR_O(31 downto 28) = X"1" and ADDR_O(15) = '0') then
|
||||
mem_area <= mem_rom;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
gen_mem_mux_non_translate:
|
||||
if KSEG_01_TRANSLATED = false generate
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
@@ -231,7 +157,6 @@ mem_mux:
|
||||
mem_area <= mem_sram;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
@@ -279,10 +204,8 @@ signal_mux:
|
||||
uut: entity work.mips_top
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => 256, -- words
|
||||
dcache_size => 256, -- words
|
||||
WITH_TLB => WITH_TLB,
|
||||
TRANSLATE_KSEG0_1 => KSEG_01_TRANSLATED
|
||||
icache_size => 1024, -- words
|
||||
dcache_size => 1024 -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
@@ -306,6 +229,7 @@ uut: entity work.mips_top
|
||||
);
|
||||
INT(1) <= int_uart;
|
||||
INT(5) <= int_timer;
|
||||
INT(2) <= '1';
|
||||
|
||||
inst_rom : entity work.rom_wb
|
||||
PORT MAP
|
||||
@@ -437,16 +361,16 @@ SRAM_READ:
|
||||
if sram_oe_n = '0' then
|
||||
if sram_cs_n = '0' then
|
||||
if sram_be_n(0) = '0' then
|
||||
sram_d(7 downto 0) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
||||
sram_d(7 downto 0) <= sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(1) = '0' then
|
||||
sram_d(15 downto 8) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
||||
sram_d(15 downto 8) <= sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(2) = '0' then
|
||||
sram_d(23 downto 16) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
||||
sram_d(23 downto 16) <= sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
|
||||
end if;
|
||||
if sram_be_n(3) = '0' then
|
||||
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
||||
sram_d(31 downto 24) <= sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
@@ -458,31 +382,26 @@ SRAM_WRITE:
|
||||
if rising_edge(sram_wr_n) then
|
||||
if sram_cs_n = '0' then
|
||||
if sram_be_n(0) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
||||
sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
|
||||
end if;
|
||||
if sram_be_n(1) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
||||
sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
|
||||
end if;
|
||||
if sram_be_n(2) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
||||
sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
|
||||
end if;
|
||||
if sram_be_n(3) = '0' then
|
||||
sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
||||
sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
FLASH_READ:
|
||||
process(rst, flash_cs_n, flash_oe_n, flash_a)
|
||||
type file_t is file of integer;
|
||||
file load_flash : file_t open read_mode is "hello.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "test_tlb_sim.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "test_exception_sim.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "test_timer.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "test_dcache_sim.elf.flash.bin";
|
||||
-- file load_flash : file_t open read_mode is "dhry.flash.bin";
|
||||
file load_flash : file_t open read_mode is app;
|
||||
variable instr : integer;
|
||||
variable index : natural;
|
||||
variable temp : signed(31 downto 0);
|
||||
@@ -493,7 +412,7 @@ FLASH_READ:
|
||||
while not endfile(load_flash) loop
|
||||
read(load_flash, instr);
|
||||
temp := to_signed(instr, word_t'length);
|
||||
flash_data(index) <= unsigned(temp);
|
||||
flash_memory_content(index) <= unsigned(temp);
|
||||
index := index + 1;
|
||||
end loop;
|
||||
else
|
||||
@@ -502,78 +421,22 @@ FLASH_READ:
|
||||
if flash_oe_n = '0' then
|
||||
if flash_cs_n = '0' then
|
||||
if flash_be_n(0) = '0' then
|
||||
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd;
|
||||
flash_d(7 downto 0) <= flash_memory_content(index)(7 downto 0) after tpd;
|
||||
end if;
|
||||
if flash_be_n(1) = '0' then
|
||||
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd;
|
||||
flash_d(15 downto 8) <= flash_memory_content(index)(15 downto 8) after tpd;
|
||||
end if;
|
||||
if flash_be_n(2) = '0' then
|
||||
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd;
|
||||
flash_d(23 downto 16) <= flash_memory_content(index)(23 downto 16) after tpd;
|
||||
end if;
|
||||
if flash_be_n(3) = '0' then
|
||||
flash_d(31 downto 24) <= flash_data(index)(31 downto 24) after tpd;
|
||||
flash_d(31 downto 24) <= flash_memory_content(index)(31 downto 24) after tpd;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
icache_trace_write:
|
||||
process(clk)
|
||||
type file_t is file of string;
|
||||
file f : file_t open write_mode is "icache_trace.dat";
|
||||
variable file_opened : std_logic;
|
||||
variable saddr : string(1 to 8);
|
||||
variable sdata : string(1 to 8);
|
||||
begin
|
||||
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
file_opened := '1';
|
||||
elsif file_opened = '1' then
|
||||
if debug.imem_din_vld = '1' then
|
||||
saddr := to_string(debug.imem_addr_reg);
|
||||
sdata := to_string(debug.imem_din_reg);
|
||||
write(f, saddr & " : " & sdata & CR);
|
||||
end if;
|
||||
else
|
||||
file_close(f);
|
||||
file_opened := '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
dcache_trace_write:
|
||||
process(clk)
|
||||
type file_t is file of string;
|
||||
file f : file_t open write_mode is "dcache_trace.dat";
|
||||
variable file_opened : std_logic;
|
||||
variable saddr : string(1 to 8);
|
||||
variable sdata : string(1 to 8);
|
||||
begin
|
||||
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
file_opened := '1';
|
||||
elsif file_opened = '1' then
|
||||
if debug.dmem_din_vld = '1' then
|
||||
saddr := to_string(debug.dmem_addr_reg);
|
||||
sdata := to_string(debug.dmem_din_reg);
|
||||
write(f, saddr & " : " & sdata & " R" & CR);
|
||||
elsif debug.dmem_dout_vld = '1' then
|
||||
saddr := to_string(debug.dmem_addr_reg);
|
||||
sdata := to_string(debug.dmem_dout_reg);
|
||||
write(f, saddr & " : " & sdata & " W" & CR);
|
||||
end if;
|
||||
else
|
||||
file_close(f);
|
||||
file_opened := '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
------------------------------------------------------------------
|
||||
STIMULUS: process
|
||||
|
||||
@@ -583,13 +446,10 @@ STIMULUS: process
|
||||
wait for 3*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
rst <= '0';
|
||||
|
||||
wait for 1200000*CLK_PERIOD;
|
||||
|
||||
nmi <= '0';
|
||||
wait until rising_edge(clk);
|
||||
tb_fin <= '1';
|
||||
wait for 1500 us;
|
||||
wait until rising_edge(clk);
|
||||
tb_fin <= '0';
|
||||
|
||||
wait;
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
include $(VHDL_HOME)/defs.mk
|
||||
PRJDIR := ./project
|
||||
|
||||
PRJ := mips_top
|
||||
|
||||
@@ -81,7 +81,7 @@ set_global_assignment -name DEVICE EP4CE22F17C6
|
||||
set_global_assignment -name TOP_LEVEL_ENTITY mips_sys
|
||||
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 14.0
|
||||
set_global_assignment -name PROJECT_CREATION_TIME_DATE "08:21:44 MAY 14, 2015"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "21.1.1 Lite Edition"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "24.1std.0 Standard Edition"
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
|
||||
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
|
||||
@@ -320,4 +320,5 @@ set_location_assignment PIN_R8 -to clk_brd
|
||||
set_location_assignment PIN_J15 -to rst_brd_n
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to clk_brd
|
||||
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to rst_brd_n
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
Binary file not shown.
@@ -0,0 +1,806 @@
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Copyright (C) 2025 Altera Corporation. All rights reserved.
|
||||
# Your use of Altera Corporation's design tools, logic functions
|
||||
# and other software and tools, and any partner logic
|
||||
# functions, and any output files from any of the foregoing
|
||||
# (including device programming or simulation files), and any
|
||||
# associated documentation or information are expressly subject
|
||||
# to the terms and conditions of the Altera Program License
|
||||
# Subscription Agreement, the Altera Quartus Prime License Agreement,
|
||||
# the Altera IP License Agreement, or other applicable license
|
||||
# agreement, including, without limitation, that your use is for
|
||||
# the sole purpose of programming logic devices manufactured by
|
||||
# Altera and sold by Altera or its authorized distributors. Please
|
||||
# refer to the Altera Software License Subscription Agreements
|
||||
# on the Quartus Prime software download page.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Quartus Prime
|
||||
# Version 24.1std.0 Build 1077 03/04/2025 SC Standard Edition
|
||||
# Date created = 19:12:31 October 08, 2025
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
#
|
||||
# Note:
|
||||
#
|
||||
# 1) Do not modify this file. This file was generated
|
||||
# automatically by the Quartus Prime software and is used
|
||||
# to preserve global assignments across Quartus Prime versions.
|
||||
#
|
||||
# -------------------------------------------------------------------------- #
|
||||
|
||||
set_global_assignment -name IP_COMPONENT_REPORT_HIERARCHY Off
|
||||
set_global_assignment -name IP_COMPONENT_INTERNAL Off
|
||||
set_global_assignment -name PROJECT_SHOW_ENTITY_NAME On
|
||||
set_global_assignment -name PROJECT_USE_SIMPLIFIED_NAMES Off
|
||||
set_global_assignment -name ENABLE_REDUCED_MEMORY_MODE Off
|
||||
set_global_assignment -name VER_COMPATIBLE_DB_DIR export_db
|
||||
set_global_assignment -name AUTO_EXPORT_VER_COMPATIBLE_DB Off
|
||||
set_global_assignment -name FLOW_DISABLE_ASSEMBLER Off
|
||||
set_global_assignment -name FLOW_ENABLE_POWER_ANALYZER Off
|
||||
set_global_assignment -name FLOW_ENABLE_HC_COMPARE Off
|
||||
set_global_assignment -name HC_OUTPUT_DIR hc_output
|
||||
set_global_assignment -name SAVE_MIGRATION_INFO_DURING_COMPILATION Off
|
||||
set_global_assignment -name FLOW_ENABLE_IO_ASSIGNMENT_ANALYSIS Off
|
||||
set_global_assignment -name RUN_FULL_COMPILE_ON_DEVICE_CHANGE On
|
||||
set_global_assignment -name FLOW_ENABLE_RTL_VIEWER Off
|
||||
set_global_assignment -name READ_OR_WRITE_IN_BYTE_ADDRESS "Use global settings"
|
||||
set_global_assignment -name FLOW_HARDCOPY_DESIGN_READINESS_CHECK On
|
||||
set_global_assignment -name FLOW_ENABLE_PARALLEL_MODULES On
|
||||
set_global_assignment -name ENABLE_COMPACT_REPORT_TABLE Off
|
||||
set_global_assignment -name REVISION_TYPE Base -family "Arria V"
|
||||
set_global_assignment -name REVISION_TYPE Base -family "Stratix V"
|
||||
set_global_assignment -name REVISION_TYPE Base -family "Arria V GZ"
|
||||
set_global_assignment -name REVISION_TYPE Base -family "Cyclone V"
|
||||
set_global_assignment -name DEFAULT_HOLD_MULTICYCLE "Same as Multicycle"
|
||||
set_global_assignment -name CUT_OFF_PATHS_BETWEEN_CLOCK_DOMAINS On
|
||||
set_global_assignment -name CUT_OFF_READ_DURING_WRITE_PATHS On
|
||||
set_global_assignment -name CUT_OFF_IO_PIN_FEEDBACK On
|
||||
set_global_assignment -name DO_COMBINED_ANALYSIS Off
|
||||
set_global_assignment -name TDC_AGGRESSIVE_HOLD_CLOSURE_EFFORT Off
|
||||
set_global_assignment -name ENABLE_HPS_INTERNAL_TIMING Off
|
||||
set_global_assignment -name EMIF_SOC_PHYCLK_ADVANCE_MODELING Off
|
||||
set_global_assignment -name USE_DLL_FREQUENCY_FOR_DQS_DELAY_CHAIN Off
|
||||
set_global_assignment -name ANALYZE_LATCHES_AS_SYNCHRONOUS_ELEMENTS On
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_SCRIPT_INCLUDE_DEFAULT_ANALYSIS On
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Arria V"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "MAX 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Stratix IV"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Cyclone IV E"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Arria 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS Off -family "MAX V"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Stratix V"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Arria V GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS Off -family "MAX II"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Arria II GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Arria II GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Cyclone IV GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_MULTICORNER_ANALYSIS On -family "Cyclone V"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_REPORT_TIMING Off
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria V"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "MAX 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Stratix IV"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone IV E"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS On -family "MAX V"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Stratix V"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria V GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS On -family "MAX II"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria II GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Arria II GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS On -family "Cyclone IV GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_WORST_CASE_TIMING_PATHS Off -family "Cyclone V"
|
||||
set_global_assignment -name TIMING_ANALYZER_REPORT_NUM_WORST_CASE_TIMING_PATHS 100
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Arria V"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "MAX 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Cyclone IV E"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Stratix IV"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Arria 10"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL Off -family "MAX V"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Stratix V"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Arria V GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL Off -family "MAX II"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Arria II GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Arria II GZ"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Cyclone IV GX"
|
||||
set_global_assignment -name TIMING_ANALYZER_DO_CCPP_REMOVAL On -family "Cyclone V"
|
||||
set_global_assignment -name OPTIMIZATION_MODE Balanced
|
||||
set_global_assignment -name ALLOW_REGISTER_MERGING On
|
||||
set_global_assignment -name ALLOW_REGISTER_DUPLICATION On
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Arria V"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER ON -family "Cyclone 10 LP"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "MAX 10"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Stratix IV"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Cyclone IV E"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER ON -family "Arria 10"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "MAX V"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Stratix V"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Arria V GZ"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "MAX II"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Arria II GX"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Arria II GZ"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Cyclone IV GX"
|
||||
set_global_assignment -name DISABLE_LEGACY_TIMING_ANALYZER OFF -family "Cyclone V"
|
||||
set_global_assignment -name MUX_RESTRUCTURE Auto
|
||||
set_global_assignment -name MLAB_ADD_TIMING_CONSTRAINTS_FOR_MIXED_PORT_FEED_THROUGH_MODE_SETTING_DONT_CARE Off
|
||||
set_global_assignment -name ENABLE_IP_DEBUG Off
|
||||
set_global_assignment -name SAVE_DISK_SPACE On
|
||||
set_global_assignment -name OCP_HW_EVAL Enable
|
||||
set_global_assignment -name DEVICE_FILTER_PACKAGE Any
|
||||
set_global_assignment -name DEVICE_FILTER_PIN_COUNT Any
|
||||
set_global_assignment -name DEVICE_FILTER_SPEED_GRADE Any
|
||||
set_global_assignment -name EDA_DESIGN_ENTRY_SYNTHESIS_TOOL "<None>"
|
||||
set_global_assignment -name VERILOG_INPUT_VERSION Verilog_2001
|
||||
set_global_assignment -name VHDL_INPUT_VERSION VHDL_1993
|
||||
set_global_assignment -name FAMILY "Cyclone V"
|
||||
set_global_assignment -name TRUE_WYSIWYG_FLOW Off
|
||||
set_global_assignment -name SMART_COMPILE_IGNORES_TDC_FOR_STRATIX_PLL_CHANGES Off
|
||||
set_global_assignment -name STATE_MACHINE_PROCESSING Auto
|
||||
set_global_assignment -name SAFE_STATE_MACHINE Off
|
||||
set_global_assignment -name EXTRACT_VERILOG_STATE_MACHINES On
|
||||
set_global_assignment -name EXTRACT_VHDL_STATE_MACHINES On
|
||||
set_global_assignment -name IGNORE_VERILOG_INITIAL_CONSTRUCTS Off
|
||||
set_global_assignment -name VERILOG_CONSTANT_LOOP_LIMIT 5000
|
||||
set_global_assignment -name VERILOG_NON_CONSTANT_LOOP_LIMIT 250
|
||||
set_global_assignment -name INFER_RAMS_FROM_RAW_LOGIC On
|
||||
set_global_assignment -name PARALLEL_SYNTHESIS On
|
||||
set_global_assignment -name DSP_BLOCK_BALANCING Auto
|
||||
set_global_assignment -name MAX_BALANCING_DSP_BLOCKS "-1 (Unlimited)"
|
||||
set_global_assignment -name NOT_GATE_PUSH_BACK On
|
||||
set_global_assignment -name ALLOW_POWER_UP_DONT_CARE On
|
||||
set_global_assignment -name REMOVE_REDUNDANT_LOGIC_CELLS Off
|
||||
set_global_assignment -name REMOVE_DUPLICATE_REGISTERS On
|
||||
set_global_assignment -name IGNORE_CARRY_BUFFERS Off
|
||||
set_global_assignment -name IGNORE_CASCADE_BUFFERS Off
|
||||
set_global_assignment -name IGNORE_GLOBAL_BUFFERS Off
|
||||
set_global_assignment -name IGNORE_ROW_GLOBAL_BUFFERS Off
|
||||
set_global_assignment -name IGNORE_LCELL_BUFFERS Off
|
||||
set_global_assignment -name MAX7000_IGNORE_LCELL_BUFFERS AUTO
|
||||
set_global_assignment -name IGNORE_SOFT_BUFFERS On
|
||||
set_global_assignment -name MAX7000_IGNORE_SOFT_BUFFERS Off
|
||||
set_global_assignment -name LIMIT_AHDL_INTEGERS_TO_32_BITS Off
|
||||
set_global_assignment -name AUTO_GLOBAL_CLOCK_MAX On
|
||||
set_global_assignment -name AUTO_GLOBAL_OE_MAX On
|
||||
set_global_assignment -name MAX_AUTO_GLOBAL_REGISTER_CONTROLS On
|
||||
set_global_assignment -name AUTO_IMPLEMENT_IN_ROM Off
|
||||
set_global_assignment -name APEX20K_TECHNOLOGY_MAPPER Lut
|
||||
set_global_assignment -name OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name STRATIXII_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name CYCLONE_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name CYCLONEII_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name STRATIX_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name MAXII_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name MAX7000_OPTIMIZATION_TECHNIQUE Speed
|
||||
set_global_assignment -name APEX20K_OPTIMIZATION_TECHNIQUE Balanced
|
||||
set_global_assignment -name MERCURY_OPTIMIZATION_TECHNIQUE Area
|
||||
set_global_assignment -name FLEX6K_OPTIMIZATION_TECHNIQUE Area
|
||||
set_global_assignment -name FLEX10K_OPTIMIZATION_TECHNIQUE Area
|
||||
set_global_assignment -name ALLOW_XOR_GATE_USAGE On
|
||||
set_global_assignment -name AUTO_LCELL_INSERTION On
|
||||
set_global_assignment -name CARRY_CHAIN_LENGTH 48
|
||||
set_global_assignment -name FLEX6K_CARRY_CHAIN_LENGTH 32
|
||||
set_global_assignment -name FLEX10K_CARRY_CHAIN_LENGTH 32
|
||||
set_global_assignment -name MERCURY_CARRY_CHAIN_LENGTH 48
|
||||
set_global_assignment -name STRATIX_CARRY_CHAIN_LENGTH 70
|
||||
set_global_assignment -name STRATIXII_CARRY_CHAIN_LENGTH 70
|
||||
set_global_assignment -name CASCADE_CHAIN_LENGTH 2
|
||||
set_global_assignment -name PARALLEL_EXPANDER_CHAIN_LENGTH 16
|
||||
set_global_assignment -name MAX7000_PARALLEL_EXPANDER_CHAIN_LENGTH 4
|
||||
set_global_assignment -name AUTO_CARRY_CHAINS On
|
||||
set_global_assignment -name AUTO_CASCADE_CHAINS On
|
||||
set_global_assignment -name AUTO_PARALLEL_EXPANDERS On
|
||||
set_global_assignment -name AUTO_OPEN_DRAIN_PINS On
|
||||
set_global_assignment -name ADV_NETLIST_OPT_SYNTH_WYSIWYG_REMAP Off
|
||||
set_global_assignment -name AUTO_ROM_RECOGNITION On
|
||||
set_global_assignment -name AUTO_RAM_RECOGNITION On
|
||||
set_global_assignment -name AUTO_DSP_RECOGNITION On
|
||||
set_global_assignment -name AUTO_SHIFT_REGISTER_RECOGNITION Auto
|
||||
set_global_assignment -name ALLOW_SHIFT_REGISTER_MERGING_ACROSS_HIERARCHIES Auto
|
||||
set_global_assignment -name AUTO_CLOCK_ENABLE_RECOGNITION On
|
||||
set_global_assignment -name STRICT_RAM_RECOGNITION Off
|
||||
set_global_assignment -name ALLOW_SYNCH_CTRL_USAGE On
|
||||
set_global_assignment -name FORCE_SYNCH_CLEAR Off
|
||||
set_global_assignment -name AUTO_RAM_BLOCK_BALANCING On
|
||||
set_global_assignment -name AUTO_RAM_TO_LCELL_CONVERSION Off
|
||||
set_global_assignment -name AUTO_RESOURCE_SHARING Off
|
||||
set_global_assignment -name ALLOW_ANY_SHIFT_REGISTER_SIZE_FOR_RECOGNITION Off
|
||||
set_global_assignment -name MAX7000_FANIN_PER_CELL 100
|
||||
set_global_assignment -name USE_LOGICLOCK_CONSTRAINTS_IN_BALANCING On
|
||||
set_global_assignment -name MAX_RAM_BLOCKS_M512 "-1 (Unlimited)"
|
||||
set_global_assignment -name MAX_RAM_BLOCKS_M4K "-1 (Unlimited)"
|
||||
set_global_assignment -name MAX_RAM_BLOCKS_MRAM "-1 (Unlimited)"
|
||||
set_global_assignment -name IGNORE_TRANSLATE_OFF_AND_SYNTHESIS_OFF Off
|
||||
set_global_assignment -name STRATIXGX_BYPASS_REMAPPING_OF_FORCE_SIGNAL_DETECT_SIGNAL_THRESHOLD_SELECT Off
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria II GZ"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria V"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "MAX 10"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone IV GX"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Stratix IV"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone IV E"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria 10"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Stratix V"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria V GZ"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Cyclone V"
|
||||
set_global_assignment -name SYNTH_TIMING_DRIVEN_SYNTHESIS On -family "Arria II GX"
|
||||
set_global_assignment -name REPORT_PARAMETER_SETTINGS On
|
||||
set_global_assignment -name REPORT_SOURCE_ASSIGNMENTS On
|
||||
set_global_assignment -name REPORT_CONNECTIVITY_CHECKS On
|
||||
set_global_assignment -name IGNORE_MAX_FANOUT_ASSIGNMENTS Off
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria V"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone 10 LP"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "MAX 10"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone IV E"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Stratix IV"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria 10"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "MAX V"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Stratix V"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "MAX II"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria V GZ"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria II GX"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Arria II GZ"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 2 -family "Cyclone IV GX"
|
||||
set_global_assignment -name SYNCHRONIZATION_REGISTER_CHAIN_LENGTH 3 -family "Cyclone V"
|
||||
set_global_assignment -name OPTIMIZE_POWER_DURING_SYNTHESIS "Normal compilation"
|
||||
set_global_assignment -name HDL_MESSAGE_LEVEL Level2
|
||||
set_global_assignment -name USE_HIGH_SPEED_ADDER Auto
|
||||
set_global_assignment -name NUMBER_OF_PROTECTED_REGISTERS_REPORTED 100
|
||||
set_global_assignment -name NUMBER_OF_REMOVED_REGISTERS_REPORTED 5000
|
||||
set_global_assignment -name NUMBER_OF_SYNTHESIS_MIGRATION_ROWS 5000
|
||||
set_global_assignment -name SYNTHESIS_S10_MIGRATION_CHECKS Off
|
||||
set_global_assignment -name NUMBER_OF_SWEPT_NODES_REPORTED 5000
|
||||
set_global_assignment -name NUMBER_OF_INVERTED_REGISTERS_REPORTED 100
|
||||
set_global_assignment -name SYNTH_CLOCK_MUX_PROTECTION On
|
||||
set_global_assignment -name SYNTH_GATED_CLOCK_CONVERSION Off
|
||||
set_global_assignment -name BLOCK_DESIGN_NAMING Auto
|
||||
set_global_assignment -name SYNTH_PROTECT_SDC_CONSTRAINT Off
|
||||
set_global_assignment -name SYNTHESIS_EFFORT Auto
|
||||
set_global_assignment -name SHIFT_REGISTER_RECOGNITION_ACLR_SIGNAL On
|
||||
set_global_assignment -name PRE_MAPPING_RESYNTHESIS Off
|
||||
set_global_assignment -name SYNTH_MESSAGE_LEVEL Medium
|
||||
set_global_assignment -name DISABLE_REGISTER_MERGING_ACROSS_HIERARCHIES Auto
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria II GZ"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria V"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "MAX 10"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone IV GX"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Stratix IV"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone IV E"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria 10"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Stratix V"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria V GZ"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Cyclone V"
|
||||
set_global_assignment -name SYNTH_RESOURCE_AWARE_INFERENCE_FOR_BLOCK_RAM On -family "Arria II GX"
|
||||
set_global_assignment -name MAX_LABS "-1 (Unlimited)"
|
||||
set_global_assignment -name RBCGEN_CRITICAL_WARNING_TO_ERROR On
|
||||
set_global_assignment -name MAX_NUMBER_OF_REGISTERS_FROM_UNINFERRED_RAMS "-1 (Unlimited)"
|
||||
set_global_assignment -name AUTO_PARALLEL_SYNTHESIS On
|
||||
set_global_assignment -name PRPOF_ID Off
|
||||
set_global_assignment -name DISABLE_DSP_NEGATE_INFERENCING Off
|
||||
set_global_assignment -name REPORT_PARAMETER_SETTINGS_PRO On
|
||||
set_global_assignment -name REPORT_SOURCE_ASSIGNMENTS_PRO On
|
||||
set_global_assignment -name ENABLE_STATE_MACHINE_INFERENCE Off
|
||||
set_global_assignment -name FLEX10K_ENABLE_LOCK_OUTPUT Off
|
||||
set_global_assignment -name AUTO_MERGE_PLLS On
|
||||
set_global_assignment -name IGNORE_MODE_FOR_MERGE Off
|
||||
set_global_assignment -name TXPMA_SLEW_RATE Low
|
||||
set_global_assignment -name ADCE_ENABLED Auto
|
||||
set_global_assignment -name ROUTER_TIMING_OPTIMIZATION_LEVEL Normal
|
||||
set_global_assignment -name ROUTER_CLOCKING_TOPOLOGY_ANALYSIS Off
|
||||
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER 1.0
|
||||
set_global_assignment -name ROUTER_EFFORT_MULTIPLIER 1.0
|
||||
set_global_assignment -name FIT_ATTEMPTS_TO_SKIP 0.0
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS Off
|
||||
set_global_assignment -name ECO_ALLOW_ROUTING_CHANGES Off
|
||||
set_global_assignment -name DEVICE AUTO
|
||||
set_global_assignment -name BASE_PIN_OUT_FILE_ON_SAMEFRAME_DEVICE Off
|
||||
set_global_assignment -name ENABLE_JTAG_BST_SUPPORT Off
|
||||
set_global_assignment -name MAX7000_ENABLE_JTAG_BST_SUPPORT On
|
||||
set_global_assignment -name ENABLE_NCEO_OUTPUT Off
|
||||
set_global_assignment -name RESERVE_NCEO_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name CYCLONEII_RESERVE_NCEO_AFTER_CONFIGURATION "Use as programming pin"
|
||||
set_global_assignment -name STRATIXIII_UPDATE_MODE Standard
|
||||
set_global_assignment -name STRATIX_UPDATE_MODE Standard
|
||||
set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "Single Image"
|
||||
set_global_assignment -name CVP_MODE Off
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" -family "Arria V"
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" -family "Arria 10"
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" -family "Stratix V"
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" -family "Arria V GZ"
|
||||
set_global_assignment -name STRATIXV_CONFIGURATION_SCHEME "Passive Serial" -family "Cyclone V"
|
||||
set_global_assignment -name VID_OPERATION_MODE "PMBus Slave"
|
||||
set_global_assignment -name USE_CONF_DONE AUTO
|
||||
set_global_assignment -name USE_PWRMGT_SCL AUTO
|
||||
set_global_assignment -name USE_PWRMGT_SDA AUTO
|
||||
set_global_assignment -name USE_PWRMGT_ALERT AUTO
|
||||
set_global_assignment -name USE_INIT_DONE AUTO
|
||||
set_global_assignment -name USE_CVP_CONFDONE AUTO
|
||||
set_global_assignment -name USE_SEU_ERROR AUTO
|
||||
set_global_assignment -name RESERVE_AVST_CLK_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_AVST_VALID_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_AVST_DATA15_THROUGH_DATA0_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_AVST_DATA31_THROUGH_DATA16_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name STRATIXIII_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name MAX10FPGA_CONFIGURATION_SCHEME "Internal Configuration"
|
||||
set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "Active Serial"
|
||||
set_global_assignment -name STRATIXII_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name CYCLONEII_CONFIGURATION_SCHEME "Active Serial"
|
||||
set_global_assignment -name APEX20K_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name STRATIX_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name CYCLONE_CONFIGURATION_SCHEME "Active Serial"
|
||||
set_global_assignment -name MERCURY_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name FLEX6K_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name FLEX10K_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name APEXII_CONFIGURATION_SCHEME "Passive Serial"
|
||||
set_global_assignment -name USER_START_UP_CLOCK Off
|
||||
set_global_assignment -name ENABLE_UNUSED_RX_CLOCK_WORKAROUND Off
|
||||
set_global_assignment -name PRESERVE_UNUSED_XCVR_CHANNEL Off
|
||||
set_global_assignment -name IGNORE_HSSI_COLUMN_POWER_WHEN_PRESERVING_UNUSED_XCVR_CHANNELS On
|
||||
set_global_assignment -name AUTO_RESERVE_CLKUSR_FOR_CALIBRATION On
|
||||
set_global_assignment -name DEVICE_INITIALIZATION_CLOCK INIT_INTOSC
|
||||
set_global_assignment -name ENABLE_VREFA_PIN Off
|
||||
set_global_assignment -name ENABLE_VREFB_PIN Off
|
||||
set_global_assignment -name ALWAYS_ENABLE_INPUT_BUFFERS Off
|
||||
set_global_assignment -name ENABLE_ASMI_FOR_FLASH_LOADER Off
|
||||
set_global_assignment -name ENABLE_DEVICE_WIDE_RESET Off
|
||||
set_global_assignment -name ENABLE_DEVICE_WIDE_OE Off
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "As output driving ground"
|
||||
set_global_assignment -name ENABLE_INIT_DONE_OUTPUT Off
|
||||
set_global_assignment -name INIT_DONE_OPEN_DRAIN On
|
||||
set_global_assignment -name RESERVE_NWS_NRS_NCS_CS_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_RDYNBUSY_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DATA31_THROUGH_DATA16_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DATA15_THROUGH_DATA8_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DATA7_THROUGH_DATA1_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DATA0_AFTER_CONFIGURATION "As input tri-stated"
|
||||
set_global_assignment -name RESERVE_DATA1_AFTER_CONFIGURATION "As input tri-stated"
|
||||
set_global_assignment -name RESERVE_DATA7_THROUGH_DATA2_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DATA7_THROUGH_DATA5_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_FLASH_NCE_AFTER_CONFIGURATION "As input tri-stated"
|
||||
set_global_assignment -name RESERVE_OTHER_AP_PINS_AFTER_CONFIGURATION "Use as regular IO"
|
||||
set_global_assignment -name RESERVE_DCLK_AFTER_CONFIGURATION "Use as programming pin"
|
||||
set_global_assignment -name ENABLE_CONFIGURATION_PINS On
|
||||
set_global_assignment -name ENABLE_JTAG_PIN_SHARING Off
|
||||
set_global_assignment -name ENABLE_NCE_PIN Off
|
||||
set_global_assignment -name ENABLE_BOOT_SEL_PIN On
|
||||
set_global_assignment -name CRC_ERROR_CHECKING Off
|
||||
set_global_assignment -name INTERNAL_SCRUBBING Off
|
||||
set_global_assignment -name PR_ERROR_OPEN_DRAIN On
|
||||
set_global_assignment -name PR_READY_OPEN_DRAIN On
|
||||
set_global_assignment -name ENABLE_CVP_CONFDONE Off
|
||||
set_global_assignment -name CVP_CONFDONE_OPEN_DRAIN On
|
||||
set_global_assignment -name ENABLE_NCONFIG_FROM_CORE On
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria II GZ"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria V"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone 10 LP"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "MAX 10"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone IV GX"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Stratix IV"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone IV E"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria 10"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "IO Paths and Minimum TPD Paths" -family "MAX V"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Stratix V"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "IO Paths and Minimum TPD Paths" -family "MAX II"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria V GZ"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Cyclone V"
|
||||
set_global_assignment -name OPTIMIZE_HOLD_TIMING "All Paths" -family "Arria II GX"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria V"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "MAX 10"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone IV E"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Stratix IV"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria 10"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING Off -family "MAX V"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Stratix V"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria V GZ"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING Off -family "MAX II"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria II GX"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Arria II GZ"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone IV GX"
|
||||
set_global_assignment -name OPTIMIZE_MULTI_CORNER_TIMING On -family "Cyclone V"
|
||||
set_global_assignment -name BLOCK_RAM_TO_MLAB_CELL_CONVERSION On
|
||||
set_global_assignment -name BLOCK_RAM_AND_MLAB_EQUIVALENT_POWER_UP_CONDITIONS Auto
|
||||
set_global_assignment -name BLOCK_RAM_AND_MLAB_EQUIVALENT_PAUSED_READ_CAPABILITIES Care
|
||||
set_global_assignment -name PROGRAMMABLE_POWER_TECHNOLOGY_SETTING Automatic -family "Stratix IV"
|
||||
set_global_assignment -name PROGRAMMABLE_POWER_TECHNOLOGY_SETTING Automatic -family "Arria 10"
|
||||
set_global_assignment -name PROGRAMMABLE_POWER_TECHNOLOGY_SETTING Automatic -family "Stratix V"
|
||||
set_global_assignment -name PROGRAMMABLE_POWER_TECHNOLOGY_SETTING Automatic -family "Arria V GZ"
|
||||
set_global_assignment -name PROGRAMMABLE_POWER_MAXIMUM_HIGH_SPEED_FRACTION_OF_USED_LAB_TILES 1.0
|
||||
set_global_assignment -name GUARANTEE_MIN_DELAY_CORNER_IO_ZERO_HOLD_TIME On
|
||||
set_global_assignment -name OPTIMIZE_POWER_DURING_FITTING "Normal compilation"
|
||||
set_global_assignment -name OPTIMIZE_SSN Off
|
||||
set_global_assignment -name OPTIMIZE_TIMING "Normal compilation"
|
||||
set_global_assignment -name ECO_OPTIMIZE_TIMING Off
|
||||
set_global_assignment -name ECO_REGENERATE_REPORT Off
|
||||
set_global_assignment -name OPTIMIZE_IOC_REGISTER_PLACEMENT_FOR_TIMING Normal
|
||||
set_global_assignment -name FIT_ONLY_ONE_ATTEMPT Off
|
||||
set_global_assignment -name FINAL_PLACEMENT_OPTIMIZATION Automatically
|
||||
set_global_assignment -name FITTER_AGGRESSIVE_ROUTABILITY_OPTIMIZATION Automatically
|
||||
set_global_assignment -name SEED 1
|
||||
set_global_assignment -name PERIPHERY_TO_CORE_PLACEMENT_AND_ROUTING_OPTIMIZATION OFF
|
||||
set_global_assignment -name RESERVE_ROUTING_OUTPUT_FLEXIBILITY Off
|
||||
set_global_assignment -name SLOW_SLEW_RATE Off
|
||||
set_global_assignment -name PCI_IO Off
|
||||
set_global_assignment -name TURBO_BIT On
|
||||
set_global_assignment -name WEAK_PULL_UP_RESISTOR Off
|
||||
set_global_assignment -name ENABLE_BUS_HOLD_CIRCUITRY Off
|
||||
set_global_assignment -name AUTO_GLOBAL_MEMORY_CONTROLS Off
|
||||
set_global_assignment -name MIGRATION_CONSTRAIN_CORE_RESOURCES On
|
||||
set_global_assignment -name QII_AUTO_PACKED_REGISTERS Auto
|
||||
set_global_assignment -name AUTO_PACKED_REGISTERS_MAX Auto
|
||||
set_global_assignment -name NORMAL_LCELL_INSERT On
|
||||
set_global_assignment -name CARRY_OUT_PINS_LCELL_INSERT On
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Arria V"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Cyclone 10 LP"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "MAX 10"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Stratix IV"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Cyclone IV E"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Arria 10"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "MAX V"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Stratix V"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "MAX II"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Arria V GZ"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Arria II GX"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Arria II GZ"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Cyclone IV GX"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS On -family "Cyclone V"
|
||||
set_global_assignment -name AUTO_DELAY_CHAINS_FOR_HIGH_FANOUT_INPUT_PINS OFF
|
||||
set_global_assignment -name XSTL_INPUT_ALLOW_SE_BUFFER Off
|
||||
set_global_assignment -name TREAT_BIDIR_AS_OUTPUT Off
|
||||
set_global_assignment -name AUTO_TURBO_BIT ON
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC_FOR_AREA Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_COMBO_LOGIC Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_LOG_FILE Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_DUPLICATION Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_MAP_LOGIC_TO_MEMORY_FOR_AREA Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_REGISTER_RETIMING Off
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_ASYNCHRONOUS_SIGNAL_PIPELINING Off
|
||||
set_global_assignment -name IO_PLACEMENT_OPTIMIZATION On
|
||||
set_global_assignment -name ALLOW_LVTTL_LVCMOS_INPUT_LEVELS_TO_OVERDRIVE_INPUT_BUFFER Off
|
||||
set_global_assignment -name OVERRIDE_DEFAULT_ELECTROMIGRATION_PARAMETERS Off
|
||||
set_global_assignment -name FITTER_EFFORT "Auto Fit"
|
||||
set_global_assignment -name FITTER_AUTO_EFFORT_DESIRED_SLACK_MARGIN 0ns
|
||||
set_global_assignment -name PHYSICAL_SYNTHESIS_EFFORT Normal
|
||||
set_global_assignment -name ROUTER_LCELL_INSERTION_AND_LOGIC_DUPLICATION Auto
|
||||
set_global_assignment -name ROUTER_REGISTER_DUPLICATION Auto
|
||||
set_global_assignment -name STRATIXGX_ALLOW_CLOCK_FANOUT_WITH_ANALOG_RESET Off
|
||||
set_global_assignment -name AUTO_GLOBAL_CLOCK On
|
||||
set_global_assignment -name AUTO_GLOBAL_OE On
|
||||
set_global_assignment -name AUTO_GLOBAL_REGISTER_CONTROLS On
|
||||
set_global_assignment -name FITTER_EARLY_TIMING_ESTIMATE_MODE Realistic
|
||||
set_global_assignment -name STRATIXGX_ALLOW_GIGE_UNDER_FULL_DATARATE_RANGE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_RX_CORECLK_FROM_NON_RX_CLKOUT_SOURCE_IN_DOUBLE_DATA_WIDTH_MODE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_GIGE_IN_DOUBLE_DATA_WIDTH_MODE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_PARALLEL_LOOPBACK_IN_DOUBLE_DATA_WIDTH_MODE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_XAUI_IN_SINGLE_DATA_WIDTH_MODE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_XAUI_WITH_CORECLK_SELECTED_AT_RATE_MATCHER Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_XAUI_WITH_RX_CORECLK_FROM_NON_TXPLL_SOURCE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITH_CORECLK_SELECTED_AT_RATE_MATCHER Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITHOUT_8B10B Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_GIGE_WITH_RX_CORECLK_FROM_NON_TXPLL_SOURCE Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_POST8B10B_LOOPBACK Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_REVERSE_PARALLEL_LOOPBACK Off
|
||||
set_global_assignment -name STRATIXGX_ALLOW_USE_OF_GXB_COUPLED_IOS Off
|
||||
set_global_assignment -name GENERATE_GXB_RECONFIG_MIF Off
|
||||
set_global_assignment -name GENERATE_GXB_RECONFIG_MIF_WITH_PLL Off
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_WEAK_PULLUP "As input tri-stated with weak pull-up"
|
||||
set_global_assignment -name ENABLE_HOLD_BACK_OFF On
|
||||
set_global_assignment -name CONFIGURATION_VCCIO_LEVEL Auto
|
||||
set_global_assignment -name FORCE_CONFIGURATION_VCCIO Off
|
||||
set_global_assignment -name SYNCHRONIZER_IDENTIFICATION Auto
|
||||
set_global_assignment -name ENABLE_BENEFICIAL_SKEW_OPTIMIZATION On
|
||||
set_global_assignment -name OPTIMIZE_FOR_METASTABILITY On
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Arria V"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Cyclone 10 LP"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "MAX 10"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN Off -family "Cyclone IV E"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Arria 10"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Stratix V"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Arria V GZ"
|
||||
set_global_assignment -name CRC_ERROR_OPEN_DRAIN On -family "Cyclone V"
|
||||
set_global_assignment -name MAX_GLOBAL_CLOCKS_ALLOWED "-1 (Unlimited)"
|
||||
set_global_assignment -name MAX_REGIONAL_CLOCKS_ALLOWED "-1 (Unlimited)"
|
||||
set_global_assignment -name MAX_PERIPHERY_CLOCKS_ALLOWED "-1 (Unlimited)"
|
||||
set_global_assignment -name MAX_CLOCKS_ALLOWED "-1 (Unlimited)"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Arria 10"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Arria V"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Stratix V"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_40MHz -family "Cyclone IV GX"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Arria V GZ"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_100MHz -family "Cyclone V"
|
||||
set_global_assignment -name ACTIVE_SERIAL_CLOCK FREQ_40MHz -family "Arria II GX"
|
||||
set_global_assignment -name M144K_BLOCK_READ_CLOCK_DUTY_CYCLE_DEPENDENCY Off
|
||||
set_global_assignment -name STRATIXIII_MRAM_COMPATIBILITY On
|
||||
set_global_assignment -name FORCE_FITTER_TO_AVOID_PERIPHERY_PLACEMENT_WARNINGS Off
|
||||
set_global_assignment -name AUTO_C3_M9K_BIT_SKIP Off
|
||||
set_global_assignment -name PR_DONE_OPEN_DRAIN On
|
||||
set_global_assignment -name NCEO_OPEN_DRAIN On
|
||||
set_global_assignment -name ENABLE_CRC_ERROR_PIN Off
|
||||
set_global_assignment -name ENABLE_PR_PINS Off
|
||||
set_global_assignment -name RESERVE_PR_PINS Off
|
||||
set_global_assignment -name CONVERT_PR_WARNINGS_TO_ERRORS Off
|
||||
set_global_assignment -name PR_PINS_OPEN_DRAIN Off
|
||||
set_global_assignment -name CLAMPING_DIODE Off
|
||||
set_global_assignment -name TRI_STATE_SPI_PINS Off
|
||||
set_global_assignment -name UNUSED_TSD_PINS_GND Off
|
||||
set_global_assignment -name IMPLEMENT_MLAB_IN_16_BIT_DEEP_MODE Off
|
||||
set_global_assignment -name FORM_DDR_CLUSTERING_CLIQUE Off
|
||||
set_global_assignment -name ALM_REGISTER_PACKING_EFFORT Medium
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION On -family "Arria V"
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION Off -family "Stratix IV"
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION On -family "Arria 10"
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION On -family "Stratix V"
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION On -family "Arria V GZ"
|
||||
set_global_assignment -name ADVANCED_PHYSICAL_OPTIMIZATION On -family "Cyclone V"
|
||||
set_global_assignment -name RELATIVE_NEUTRON_FLUX 1.0
|
||||
set_global_assignment -name SEU_FIT_REPORT Off
|
||||
set_global_assignment -name HYPER_RETIMER Off -family "Arria 10"
|
||||
set_global_assignment -name HYPER_RETIMER_FAST_FORWARD_ADD_PIPELINING_MAX "-1"
|
||||
set_global_assignment -name HYPER_RETIMER_FAST_FORWARD_ASYNCH_CLEAR Auto
|
||||
set_global_assignment -name HYPER_RETIMER_FAST_FORWARD_USER_PRESERVE_RESTRICTION Auto
|
||||
set_global_assignment -name HYPER_RETIMER_FAST_FORWARD_DSP_BLOCKS On
|
||||
set_global_assignment -name HYPER_RETIMER_FAST_FORWARD_RAM_BLOCKS On
|
||||
set_global_assignment -name EDA_SIMULATION_TOOL "<None>"
|
||||
set_global_assignment -name EDA_TIMING_ANALYSIS_TOOL "<None>"
|
||||
set_global_assignment -name EDA_BOARD_DESIGN_TIMING_TOOL "<None>"
|
||||
set_global_assignment -name EDA_BOARD_DESIGN_SYMBOL_TOOL "<None>"
|
||||
set_global_assignment -name EDA_BOARD_DESIGN_SIGNAL_INTEGRITY_TOOL "<None>"
|
||||
set_global_assignment -name EDA_BOARD_DESIGN_BOUNDARY_SCAN_TOOL "<None>"
|
||||
set_global_assignment -name EDA_BOARD_DESIGN_TOOL "<None>"
|
||||
set_global_assignment -name EDA_FORMAL_VERIFICATION_TOOL "<None>"
|
||||
set_global_assignment -name EDA_RESYNTHESIS_TOOL "<None>"
|
||||
set_global_assignment -name ON_CHIP_BITSTREAM_DECOMPRESSION On
|
||||
set_global_assignment -name COMPRESSION_MODE Off
|
||||
set_global_assignment -name CLOCK_SOURCE Internal
|
||||
set_global_assignment -name CONFIGURATION_CLOCK_FREQUENCY "10 MHz"
|
||||
set_global_assignment -name CONFIGURATION_CLOCK_DIVISOR 1
|
||||
set_global_assignment -name ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE On
|
||||
set_global_assignment -name FLEX6K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE Off
|
||||
set_global_assignment -name FLEX10K_ENABLE_LOW_VOLTAGE_MODE_ON_CONFIG_DEVICE On
|
||||
set_global_assignment -name MAX7000S_JTAG_USER_CODE FFFF
|
||||
set_global_assignment -name STRATIX_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name APEX20K_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name MERCURY_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name FLEX10K_JTAG_USER_CODE 7F
|
||||
set_global_assignment -name MAX7000_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name MAX7000_USE_CHECKSUM_AS_USERCODE Off
|
||||
set_global_assignment -name USE_CHECKSUM_AS_USERCODE On
|
||||
set_global_assignment -name SECURITY_BIT Off
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone 10 LP"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE On -family "MAX 10"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone IV E"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Stratix IV"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE On -family "MAX V"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE On -family "MAX II"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Arria II GX"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Arria II GZ"
|
||||
set_global_assignment -name USE_CONFIGURATION_DEVICE Off -family "Cyclone IV GX"
|
||||
set_global_assignment -name CYCLONEIII_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name STRATIXII_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE_TYPE "PV3102 or EM1130"
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE0_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE1_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE2_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE3_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE4_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE5_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE6_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_SLAVE_DEVICE7_ADDRESS 0000000
|
||||
set_global_assignment -name PWRMGT_VOLTAGE_OUTPUT_FORMAT "Auto discovery"
|
||||
set_global_assignment -name PWRMGT_DIRECT_FORMAT_COEFFICIENT_M 0
|
||||
set_global_assignment -name PWRMGT_DIRECT_FORMAT_COEFFICIENT_B 0
|
||||
set_global_assignment -name PWRMGT_DIRECT_FORMAT_COEFFICIENT_R 0
|
||||
set_global_assignment -name APEX20K_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name MERCURY_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name FLEX6K_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name FLEX10K_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name CYCLONE_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name STRATIX_CONFIGURATION_DEVICE Auto
|
||||
set_global_assignment -name APEX20K_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name STRATIX_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name MERCURY_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name FLEX10K_CONFIG_DEVICE_JTAG_USER_CODE FFFFFFFF
|
||||
set_global_assignment -name EPROM_USE_CHECKSUM_AS_USERCODE Off
|
||||
set_global_assignment -name AUTO_INCREMENT_CONFIG_DEVICE_JTAG_USER_CODE On
|
||||
set_global_assignment -name DISABLE_NCS_AND_OE_PULLUPS_ON_CONFIG_DEVICE Off
|
||||
set_global_assignment -name GENERATE_TTF_FILE Off
|
||||
set_global_assignment -name GENERATE_RBF_FILE Off
|
||||
set_global_assignment -name GENERATE_HEX_FILE Off
|
||||
set_global_assignment -name HEXOUT_FILE_START_ADDRESS 0
|
||||
set_global_assignment -name HEXOUT_FILE_COUNT_DIRECTION Up
|
||||
set_global_assignment -name RESERVE_ALL_UNUSED_PINS_NO_OUTPUT_GND "As output driving an unspecified signal"
|
||||
set_global_assignment -name RELEASE_CLEARS_BEFORE_TRI_STATES Off
|
||||
set_global_assignment -name AUTO_RESTART_CONFIGURATION On
|
||||
set_global_assignment -name HARDCOPYII_POWER_ON_EXTRA_DELAY Off
|
||||
set_global_assignment -name STRATIXII_MRAM_COMPATIBILITY Off
|
||||
set_global_assignment -name CYCLONEII_M4K_COMPATIBILITY On
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Arria V"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Cyclone 10 LP"
|
||||
set_global_assignment -name ENABLE_OCT_DONE On -family "MAX 10"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Cyclone IV E"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Arria 10"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Stratix V"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Arria V GZ"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Arria II GX"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Cyclone IV GX"
|
||||
set_global_assignment -name ENABLE_OCT_DONE Off -family "Cyclone V"
|
||||
set_global_assignment -name USE_CHECKERED_PATTERN_AS_UNINITIALIZED_RAM_CONTENT OFF
|
||||
set_global_assignment -name ARRIAIIGX_RX_CDR_LOCKUP_FIX_OVERRIDE Off
|
||||
set_global_assignment -name ENABLE_AUTONOMOUS_PCIE_HIP Off
|
||||
set_global_assignment -name ENABLE_ADV_SEU_DETECTION Off
|
||||
set_global_assignment -name POR_SCHEME "Instant ON"
|
||||
set_global_assignment -name EN_USER_IO_WEAK_PULLUP On
|
||||
set_global_assignment -name EN_SPI_IO_WEAK_PULLUP On
|
||||
set_global_assignment -name POF_VERIFY_PROTECT Off
|
||||
set_global_assignment -name ENABLE_SPI_MODE_CHECK Off
|
||||
set_global_assignment -name FORCE_SSMCLK_TO_ISMCLK On
|
||||
set_global_assignment -name FALLBACK_TO_EXTERNAL_FLASH Off
|
||||
set_global_assignment -name EXTERNAL_FLASH_FALLBACK_ADDRESS 0
|
||||
set_global_assignment -name GENERATE_PMSF_FILES On
|
||||
set_global_assignment -name START_TIME 0ns
|
||||
set_global_assignment -name SIMULATION_MODE TIMING
|
||||
set_global_assignment -name AUTO_USE_SIMULATION_PDB_NETLIST Off
|
||||
set_global_assignment -name ADD_DEFAULT_PINS_TO_SIMULATION_OUTPUT_WAVEFORMS On
|
||||
set_global_assignment -name SETUP_HOLD_DETECTION Off
|
||||
set_global_assignment -name SETUP_HOLD_DETECTION_INPUT_REGISTERS_BIDIR_PINS_DISABLED Off
|
||||
set_global_assignment -name CHECK_OUTPUTS Off
|
||||
set_global_assignment -name SIMULATION_COVERAGE On
|
||||
set_global_assignment -name SIMULATION_COMPLETE_COVERAGE_REPORT_PANEL On
|
||||
set_global_assignment -name SIMULATION_MISSING_1_VALUE_COVERAGE_REPORT_PANEL On
|
||||
set_global_assignment -name SIMULATION_MISSING_0_VALUE_COVERAGE_REPORT_PANEL On
|
||||
set_global_assignment -name GLITCH_DETECTION Off
|
||||
set_global_assignment -name GLITCH_INTERVAL 1ns
|
||||
set_global_assignment -name SIMULATOR_GENERATE_SIGNAL_ACTIVITY_FILE Off
|
||||
set_global_assignment -name SIMULATION_WITH_GLITCH_FILTERING_WHEN_GENERATING_SAF On
|
||||
set_global_assignment -name SIMULATION_BUS_CHANNEL_GROUPING Off
|
||||
set_global_assignment -name SIMULATION_VDB_RESULT_FLUSH On
|
||||
set_global_assignment -name VECTOR_COMPARE_TRIGGER_MODE INPUT_EDGE
|
||||
set_global_assignment -name SIMULATION_NETLIST_VIEWER Off
|
||||
set_global_assignment -name SIMULATION_INTERCONNECT_DELAY_MODEL_TYPE TRANSPORT
|
||||
set_global_assignment -name SIMULATION_CELL_DELAY_MODEL_TYPE TRANSPORT
|
||||
set_global_assignment -name SIMULATOR_GENERATE_POWERPLAY_VCD_FILE Off
|
||||
set_global_assignment -name SIMULATOR_PVT_TIMING_MODEL_TYPE AUTO
|
||||
set_global_assignment -name SIMULATION_WITH_AUTO_GLITCH_FILTERING AUTO
|
||||
set_global_assignment -name DRC_TOP_FANOUT 50
|
||||
set_global_assignment -name DRC_FANOUT_EXCEEDING 30
|
||||
set_global_assignment -name DRC_GATED_CLOCK_FEED 30
|
||||
set_global_assignment -name HARDCOPY_FLOW_AUTOMATION MIGRATION_ONLY
|
||||
set_global_assignment -name ENABLE_DRC_SETTINGS Off
|
||||
set_global_assignment -name CLK_RULE_CLKNET_CLKSPINES_THRESHOLD 25
|
||||
set_global_assignment -name DRC_DETAIL_MESSAGE_LIMIT 10
|
||||
set_global_assignment -name DRC_VIOLATION_MESSAGE_LIMIT 30
|
||||
set_global_assignment -name DRC_DEADLOCK_STATE_LIMIT 2
|
||||
set_global_assignment -name MERGE_HEX_FILE Off
|
||||
set_global_assignment -name GENERATE_SVF_FILE Off
|
||||
set_global_assignment -name GENERATE_ISC_FILE Off
|
||||
set_global_assignment -name GENERATE_JAM_FILE Off
|
||||
set_global_assignment -name GENERATE_JBC_FILE Off
|
||||
set_global_assignment -name GENERATE_JBC_FILE_COMPRESSED On
|
||||
set_global_assignment -name GENERATE_CONFIG_SVF_FILE Off
|
||||
set_global_assignment -name GENERATE_CONFIG_ISC_FILE Off
|
||||
set_global_assignment -name GENERATE_CONFIG_JAM_FILE Off
|
||||
set_global_assignment -name GENERATE_CONFIG_JBC_FILE Off
|
||||
set_global_assignment -name GENERATE_CONFIG_JBC_FILE_COMPRESSED On
|
||||
set_global_assignment -name GENERATE_CONFIG_HEXOUT_FILE Off
|
||||
set_global_assignment -name ISP_CLAMP_STATE_DEFAULT "Tri-state"
|
||||
set_global_assignment -name HPS_EARLY_IO_RELEASE Off
|
||||
set_global_assignment -name SIGNALPROBE_ALLOW_OVERUSE Off
|
||||
set_global_assignment -name SIGNALPROBE_DURING_NORMAL_COMPILATION Off
|
||||
set_global_assignment -name POWER_DEFAULT_TOGGLE_RATE 12.5%
|
||||
set_global_assignment -name POWER_DEFAULT_INPUT_IO_TOGGLE_RATE 12.5%
|
||||
set_global_assignment -name POWER_USE_PVA On
|
||||
set_global_assignment -name POWER_USE_INPUT_FILE "No File"
|
||||
set_global_assignment -name POWER_USE_INPUT_FILES Off
|
||||
set_global_assignment -name POWER_VCD_FILTER_GLITCHES On
|
||||
set_global_assignment -name POWER_REPORT_SIGNAL_ACTIVITY Off
|
||||
set_global_assignment -name POWER_REPORT_POWER_DISSIPATION Off
|
||||
set_global_assignment -name POWER_USE_DEVICE_CHARACTERISTICS TYPICAL
|
||||
set_global_assignment -name POWER_AUTO_COMPUTE_TJ On
|
||||
set_global_assignment -name POWER_TJ_VALUE 25
|
||||
set_global_assignment -name POWER_USE_TA_VALUE 25
|
||||
set_global_assignment -name POWER_USE_CUSTOM_COOLING_SOLUTION Off
|
||||
set_global_assignment -name POWER_BOARD_TEMPERATURE 25
|
||||
set_global_assignment -name POWER_HPS_ENABLE Off
|
||||
set_global_assignment -name POWER_HPS_PROC_FREQ 0.0
|
||||
set_global_assignment -name ENABLE_SMART_VOLTAGE_ID Off
|
||||
set_global_assignment -name IGNORE_PARTITIONS Off
|
||||
set_global_assignment -name AUTO_EXPORT_INCREMENTAL_COMPILATION Off
|
||||
set_global_assignment -name RAPID_RECOMPILE_ASSIGNMENT_CHECKING On
|
||||
set_global_assignment -name OUTPUT_IO_TIMING_ENDPOINT "Near End"
|
||||
set_global_assignment -name RTLV_REMOVE_FANOUT_FREE_REGISTERS On
|
||||
set_global_assignment -name RTLV_SIMPLIFIED_LOGIC On
|
||||
set_global_assignment -name RTLV_GROUP_RELATED_NODES On
|
||||
set_global_assignment -name RTLV_GROUP_COMB_LOGIC_IN_CLOUD Off
|
||||
set_global_assignment -name RTLV_GROUP_COMB_LOGIC_IN_CLOUD_TMV Off
|
||||
set_global_assignment -name RTLV_GROUP_RELATED_NODES_TMV On
|
||||
set_global_assignment -name EQC_CONSTANT_DFF_DETECTION On
|
||||
set_global_assignment -name EQC_DUPLICATE_DFF_DETECTION On
|
||||
set_global_assignment -name EQC_BBOX_MERGE On
|
||||
set_global_assignment -name EQC_LVDS_MERGE On
|
||||
set_global_assignment -name EQC_RAM_UNMERGING On
|
||||
set_global_assignment -name EQC_DFF_SS_EMULATION On
|
||||
set_global_assignment -name EQC_RAM_REGISTER_UNPACK On
|
||||
set_global_assignment -name EQC_MAC_REGISTER_UNPACK On
|
||||
set_global_assignment -name EQC_SET_PARTITION_BB_TO_VCC_GND On
|
||||
set_global_assignment -name EQC_STRUCTURE_MATCHING On
|
||||
set_global_assignment -name EQC_AUTO_BREAK_CONE On
|
||||
set_global_assignment -name EQC_POWER_UP_COMPARE Off
|
||||
set_global_assignment -name EQC_AUTO_COMP_LOOP_CUT On
|
||||
set_global_assignment -name EQC_AUTO_INVERSION On
|
||||
set_global_assignment -name EQC_AUTO_TERMINATE On
|
||||
set_global_assignment -name EQC_SUB_CONE_REPORT Off
|
||||
set_global_assignment -name EQC_RENAMING_RULES On
|
||||
set_global_assignment -name EQC_PARAMETER_CHECK On
|
||||
set_global_assignment -name EQC_AUTO_PORTSWAP On
|
||||
set_global_assignment -name EQC_DETECT_DONT_CARES On
|
||||
set_global_assignment -name EQC_SHOW_ALL_MAPPED_POINTS Off
|
||||
set_global_assignment -name EDA_INPUT_GND_NAME GND -section_id ?
|
||||
set_global_assignment -name EDA_INPUT_VCC_NAME VCC -section_id ?
|
||||
set_global_assignment -name EDA_INPUT_DATA_FORMAT NONE -section_id ?
|
||||
set_global_assignment -name EDA_SHOW_LMF_MAPPING_MESSAGES Off -section_id ?
|
||||
set_global_assignment -name EDA_RUN_TOOL_AUTOMATICALLY Off -section_id ?
|
||||
set_global_assignment -name RESYNTHESIS_RETIMING FULL -section_id ?
|
||||
set_global_assignment -name RESYNTHESIS_OPTIMIZATION_EFFORT Normal -section_id ?
|
||||
set_global_assignment -name RESYNTHESIS_PHYSICAL_SYNTHESIS Normal -section_id ?
|
||||
set_global_assignment -name USE_GENERATED_PHYSICAL_CONSTRAINTS On -section_id ?
|
||||
set_global_assignment -name VCCPD_VOLTAGE 3.3V -section_id ?
|
||||
set_global_assignment -name EDA_USER_COMPILED_SIMULATION_LIBRARY_DIRECTORY "<None>" -section_id ?
|
||||
set_global_assignment -name EDA_LAUNCH_CMD_LINE_TOOL Off -section_id ?
|
||||
set_global_assignment -name EDA_ENABLE_IPUTF_MODE On -section_id ?
|
||||
set_global_assignment -name EDA_NATIVELINK_PORTABLE_FILE_PATHS Off -section_id ?
|
||||
set_global_assignment -name EDA_NATIVELINK_GENERATE_SCRIPT_ONLY Off -section_id ?
|
||||
set_global_assignment -name EDA_WAIT_FOR_GUI_TOOL_COMPLETION Off -section_id ?
|
||||
set_global_assignment -name EDA_TRUNCATE_LONG_HIERARCHY_PATHS Off -section_id ?
|
||||
set_global_assignment -name EDA_FLATTEN_BUSES Off -section_id ?
|
||||
set_global_assignment -name EDA_MAP_ILLEGAL_CHARACTERS Off -section_id ?
|
||||
set_global_assignment -name EDA_GENERATE_TIMING_CLOSURE_DATA Off -section_id ?
|
||||
set_global_assignment -name EDA_GENERATE_POWER_INPUT_FILE Off -section_id ?
|
||||
set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS NOT_USED -section_id ?
|
||||
set_global_assignment -name EDA_RTL_SIM_MODE NOT_USED -section_id ?
|
||||
set_global_assignment -name EDA_MAINTAIN_DESIGN_HIERARCHY OFF -section_id ?
|
||||
set_global_assignment -name EDA_GENERATE_FUNCTIONAL_NETLIST On -section_id ?
|
||||
set_global_assignment -name EDA_WRITE_DEVICE_CONTROL_PORTS Off -section_id ?
|
||||
set_global_assignment -name EDA_SIMULATION_VCD_OUTPUT_TCL_FILE Off -section_id ?
|
||||
set_global_assignment -name EDA_SIMULATION_VCD_OUTPUT_SIGNALS_TO_TCL_FILE "All Except Combinational Logic Element Outputs" -section_id ?
|
||||
set_global_assignment -name EDA_ENABLE_GLITCH_FILTERING Off -section_id ?
|
||||
set_global_assignment -name EDA_WRITE_NODES_FOR_POWER_ESTIMATION OFF -section_id ?
|
||||
set_global_assignment -name EDA_SETUP_HOLD_DETECTION_INPUT_REGISTERS_BIDIR_PINS_DISABLED Off -section_id ?
|
||||
set_global_assignment -name EDA_WRITER_DONT_WRITE_TOP_ENTITY Off -section_id ?
|
||||
set_global_assignment -name EDA_VHDL_ARCH_NAME structure -section_id ?
|
||||
set_global_assignment -name EDA_IBIS_MODEL_SELECTOR Off -section_id ?
|
||||
set_global_assignment -name EDA_IBIS_EXTENDED_MODEL_SELECTOR Off -section_id ?
|
||||
set_global_assignment -name EDA_IBIS_MUTUAL_COUPLING Off -section_id ?
|
||||
set_global_assignment -name EDA_FORMAL_VERIFICATION_ALLOW_RETIMING Off -section_id ?
|
||||
set_global_assignment -name EDA_BOARD_BOUNDARY_SCAN_OPERATION PRE_CONFIG -section_id ?
|
||||
set_global_assignment -name EDA_GENERATE_RTL_SIMULATION_COMMAND_SCRIPT Off -section_id ?
|
||||
set_global_assignment -name EDA_GENERATE_GATE_LEVEL_SIMULATION_COMMAND_SCRIPT Off -section_id ?
|
||||
set_global_assignment -name EDA_IBIS_SPECIFICATION_VERSION 4p2 -section_id ?
|
||||
set_global_assignment -name SIM_VECTOR_COMPARED_CLOCK_OFFSET 0ns -section_id ?
|
||||
set_global_assignment -name SIM_VECTOR_COMPARED_CLOCK_DUTY_CYCLE 50 -section_id ?
|
||||
set_global_assignment -name APEX20K_CLIQUE_TYPE LAB -section_id ? -entity ?
|
||||
set_global_assignment -name MAX7K_CLIQUE_TYPE LAB -section_id ? -entity ?
|
||||
set_global_assignment -name MERCURY_CLIQUE_TYPE LAB -section_id ? -entity ?
|
||||
set_global_assignment -name FLEX6K_CLIQUE_TYPE LAB -section_id ? -entity ?
|
||||
set_global_assignment -name FLEX10K_CLIQUE_TYPE LAB -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_PRESERVE_HIGH_SPEED_TILES On -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_IGNORE_SOURCE_FILE_CHANGES Off -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_ALWAYS_USE_QXP_NETLIST Off -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_IMPORT_ASSIGNMENTS On -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_IMPORT_EXISTING_ASSIGNMENTS REPLACE_CONFLICTING -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_IMPORT_EXISTING_LOGICLOCK_REGIONS UPDATE_CONFLICTING -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_IMPORT_PROMOTE_ASSIGNMENTS On -section_id ? -entity ?
|
||||
set_global_assignment -name ALLOW_MULTIPLE_PERSONAS Off -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_ASD_REGION_ID 1 -section_id ? -entity ?
|
||||
set_global_assignment -name CROSS_BOUNDARY_OPTIMIZATIONS Off -section_id ? -entity ?
|
||||
set_global_assignment -name PROPAGATE_CONSTANTS_ON_INPUTS On -section_id ? -entity ?
|
||||
set_global_assignment -name PROPAGATE_INVERSIONS_ON_INPUTS On -section_id ? -entity ?
|
||||
set_global_assignment -name REMOVE_LOGIC_ON_UNCONNECTED_OUTPUTS On -section_id ? -entity ?
|
||||
set_global_assignment -name MERGE_EQUIVALENT_INPUTS On -section_id ? -entity ?
|
||||
set_global_assignment -name MERGE_EQUIVALENT_BIDIRS On -section_id ? -entity ?
|
||||
set_global_assignment -name ABSORB_PATHS_FROM_OUTPUTS_TO_INPUTS On -section_id ? -entity ?
|
||||
set_global_assignment -name PARTITION_ENABLE_STRICT_PRESERVATION Off -section_id ? -entity ?
|
||||
@@ -0,0 +1,3 @@
|
||||
Quartus_Version = Version 24.1std.0 Build 1077 03/04/2025 SC Standard Edition
|
||||
Version_Index = 587478272
|
||||
Creation_Time = Wed Oct 8 19:19:35 2025
|
||||
Binary file not shown.
@@ -0,0 +1,2 @@
|
||||
{ "Error" "ECPT_LICENSE_NOT_SET" "" "License file is not specified." { } { } 0 292025 "License file is not specified." 0 0 "Design Software" 0 -1 1759943600162 ""}
|
||||
{ "Error" "EFLOW_ERROR_COUNT" "Full Compilation 1 0 s " "Quartus Prime Full Compilation was unsuccessful. 1 error, 0 warnings" { } { } 0 293001 "Quartus Prime %1!s! was unsuccessful. %2!d! error%3!s!, %4!d! warning%5!s!" 0 0 "Design Software" 0 -1 1759943600798 ""}
|
||||
@@ -1,3 +1,4 @@
|
||||
include $(VHDL_HOME)/defs.mk
|
||||
PRJDIR := ./project
|
||||
|
||||
PRJ := mips_sys
|
||||
@@ -7,5 +8,5 @@ DEVICE := "xc4vsx35-ff668-10"
|
||||
NETLIST_DIR := $(VHDL_HOME)/lib/CPUs/MIPS/syn/ise101
|
||||
NETLISTS := $(NETLIST_DIR)/mips_top.ngc
|
||||
|
||||
include $(VHDL_HOME)/make/ise.mk
|
||||
include $(VHDL_MAKE_HOME)/ise.mk
|
||||
|
||||
|
||||
Reference in New Issue
Block a user