Author SHA1 Message Date
jens 1df213b6a7 Updated GTKW 2022-09-08 16:08:14 +02:00
jens 55ac1b23c6 Updated bootloader.dis 2022-09-08 12:11:39 +02:00
jens f168a4f183 Updated tb_mips_top.wopt.templ 2022-09-08 11:29:15 +02:00
jens b21e3c580b Unified RAM memory content signals 2022-09-08 11:27:39 +02:00
jens 08e1a114c4 Use genwopt 2022-09-08 11:16:13 +02:00
jens f9539b5992 Added genwopt target 2022-09-08 11:15:29 +02:00
jens 3b5ccc5280 Reafctored defs.mk 2022-09-08 09:08:48 +02:00
jens 609e7bf64d Disabled TLB and run for 150 us 2022-09-08 09:07:32 +02:00
jens 518af7c679 Moved defs.mk 2022-09-08 08:57:26 +02:00
jens 132bbf0991 tb_mips_top: Use hello.elf 2022-09-07 19:10:50 +02:00
jens 9e346d7894 MIPS: merged from BRANCH_MIPS_TLB 2022-09-07 19:05:11 +02:00
48 changed files with 5546 additions and 24977 deletions
+7 -8
View File
@@ -11,14 +11,13 @@ 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) $(EXTRA_OPTS)
RUN_OPTS += --stop-time=$(RUN_TIME)
GHDL_OPTS += --work=$(WORK_LIB) --workdir=$(WORK_DIR) --std=$(LANG_STD) --ieee=$(IEEE_STD)
# -------------------------------------------------
@@ -94,6 +93,12 @@ 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
@@ -101,12 +106,6 @@ 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 -1
View File
@@ -1,5 +1,5 @@
# -----------------------------------------------------------
include $(VHDL_HOME)/defs.mk
include $(VHDL_HOME)/make/defs.mk
# -----------------------------------------------------------
include package_other.inc
+1 -1
View File
@@ -1,5 +1,5 @@
# -----------------------------------------------------------
include $(VHDL_HOME)/defs.mk
include $(VHDL_HOME)/make/defs.mk
# -----------------------------------------------------------
include package1.inc
include package2.inc
+1
View File
@@ -1,2 +1,3 @@
LIB_PATH := $(VHDL_HOME)/lib
VHDL_MAKE_HOME := $(VHDL_HOME)/Common/make
+2 -2
View File
@@ -1,4 +1,4 @@
.gitignore
build/
*.wopt
.gitignore
build/
+14 -20
View File
@@ -1,37 +1,31 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Mon Sep 12 21:25:14 2022
[*] Sat Jul 2 11:01:23 2022
[*]
[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
[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
[savefile] "/home/jens/work/projects/vhdl/lib/CPUs/JCpu/ghdl/tb_cpu_embedded.gtkw"
[timestart] 0
[size] 1854 1136
[pos] -1 -1
[pos] -51 -51
*-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
top.tb_cpu_embedded.uut.rst
top.tb_cpu_embedded.uut.clk
uut.clk
uut.rst
@22
#{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]
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]
@28
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
uut.xmem_we
@29
top.tb_cpu_embedded.uut.int_in
uut.xmem_re
[pattern_trace] 1
[pattern_trace] 0
-1
View File
@@ -11,7 +11,6 @@ SRCS += ../src/tb_cpu_embedded.vhd
# Compile
TARGET := tb_cpu_embedded
ENTITY := tb_cpu_embedded
WAVE_FORMAT := ghw
include $(VHDL_MAKE_HOME)/ghdl.mk
@@ -1,199 +0,0 @@
$ 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
-1
View File
@@ -1 +0,0 @@
<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.
+9 -4
View File
@@ -2,6 +2,7 @@
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
@@ -10,20 +11,24 @@ 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_biu.vhd
$(PKG_NAME)_SRCS += $(MOD_PATH)/mips_cop.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_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
+24 -86
View File
@@ -1,35 +1,29 @@
[*]
[*] GTKWave Analyzer v3.3.104 (w)1999-2020 BSI
[*] Tue Sep 13 09:25:38 2022
[*] Thu Sep 8 14:06:03 2022
[*]
[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
[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
[treeopen] top.
[treeopen] top.tb_mips_top.
[treeopen] top.tb_mips_top.uut.
[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.
[treeopen] top.tb_mips_top.uut.inst_pipeline.id_stage.
[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_width] 233
[signals_width] 228
[sst_expanded] 1
[sst_vpaned_height] 667
[sst_vpaned_height] 488
@200
-MIPS_R13
-MIPS_R14
@28
top.tb_mips_top.uut.cpu_clk
top.tb_mips_top.uut.inst_pipeline.clk_1
top.tb_mips_top.uut.inst_pipeline.clk_2
top.tb_mips_top.uut.clk_i
top.tb_mips_top.uut.stb_o
@22
@@ -39,6 +33,8 @@ 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]
@@ -52,19 +48,18 @@ 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
@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.sdu.dmem_dep
@29
top.tb_mips_top.uut.inst_pipeline.sdu.imem_dep
@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]
@@ -75,62 +70,5 @@ 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
+2 -2
View File
@@ -32,8 +32,8 @@ SRCS += ../src/tb_mips_top.vhd
# Compile
TARGET := tb_mips_top
ENTITY := tb_mips_top
RUN_TIME ?= 250us
WAVE_FORMAT ?= ghw
RUN_TIME := 150us
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.
+236 -390
View File
@@ -27,426 +27,282 @@ 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
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
);
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);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
MDAT_I : in unsigned(31 downto 0);
MDAT_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;
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
ctrl_in : in biu_ctrl_in_t;
ctrl_out : out biu_ctrl_out_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 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;
-------------------------------------------------
signal RST : std_logic;
signal CPU_CLK : 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;
-- busmaster signals
signal bus_din : word_t;
signal bus_din_rdy : std_logic;
signal bus_din_we : 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_dout : word_t;
signal bus_dout_vld : std_logic;
signal bus_dout_re : 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 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;
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_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;
signal read_cycle : std_logic;
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;
begin
read_cyc_register:
process(cpu_clk)
CPU_CLK <= clk;
RST <= RST_I;
biu_busy_state:
process(clk)
begin
if rising_edge(cpu_clk) then
if rising_edge(clk) then
if RST_I = '1' then
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);
busy <= '1';
elsif (i_tlb_rdy and i_cache_rdy and d_cache_rdy and d_tlb_rdy) = '1' then
busy <= '0';
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;
cpu_imem_rdy <= not icache_busy;
busy <= CYC_O_dmem_rd or dcache_busy or (write_fifo_full);
cpu_dmem_rdy <= not busy;
inst_icache : icache
inst_busmaster : entity work.busmaster_async
GENERIC MAP
(
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
DATA_WIDTH => 32,
FIFO_DEPTH => 16
)
PORT MAP
(
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
-- 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
);
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
inst_i_tlb : entity work.tlb
GENERIC MAP
(
addr_width => 4,
data_width => 32,
do_last_read_update => true
NUM_ENTRIES => TLB_NUM_ENTRIES,
CACHE_KSEG1 => false,
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
USE_TLB => WITH_TLB
)
PORT MAP
(
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
-- 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
);
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
inst_icache: entity work.icache
GENERIC MAP
(
addr_width => 4,
data_width => 69,
do_last_read_update => false,
add_extra_read_register => true
CACHE_SIZE => ICACHE_SIZE,
LINE_SIZE => ICACHE_LINE
)
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
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
);
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;
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 => '-');
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');
bout_fifo_we_in <= '1' when dmem_mem_wr_gnt = '1' else '0';
-- Instantiate synchronous FIFO
inst_write_fifo: entity work.fifo_sync
inst_d_tlb : entity work.tlb
GENERIC MAP
(
addr_width => 4,
data_width => 68,
do_last_read_update => true
NUM_ENTRIES => TLB_NUM_ENTRIES,
CACHE_KSEG1 => false,
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
USE_TLB => WITH_TLB
)
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
-- 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
);
inst_dcache: entity work.dcache
GENERIC MAP
(
CACHE_SIZE => DCACHE_SIZE,
LINE_SIZE => DCACHE_LINE,
WRITE_FIFO_SIZE => WRITE_FIFO_SIZE
)
PORT MAP
(
rst => RST,
clk => CPU_CLK,
rdy => d_cache_rdy,
-- CPU control/data
query_in => ctrl_in.dcache_qry,
query_out => ctrl_out.dcache_qry,
-- Cache control
ctrl_in => ctrl_in.dcache,
-- busmaster data
bus_din => bus_dout,
bus_din_rdy => d_bus_din_rdy,
bus_din_vld => bus_dout_vld,
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
);
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;
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(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)
process(clk)
begin
if rising_edge(cpu_clk) then
if rising_edge(clk) then
if RST_I = '1' then
s <= init;
else
@@ -456,61 +312,51 @@ bus_state_next:
end process;
bus_state:
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
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)
begin
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';
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';
bus_idle <= '0';
sn <= s;
case s is
when init =>
sn <= ready;
when ready =>
bus_idle <= '1';
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
if i_bus_cmd_cycle_en = '1' then
sn <= icache_bus_access;
elsif CYC_O_dcache = '1' then
elsif d_bus_cmd_cycle_en = '1' then
sn <= dcache_bus_access;
end if;
when icache_bus_access =>
icache_mem_gnt <= '1';
if CYC_O_icache = '0' then
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
sn <= ready;
end if;
when dcache_bus_access =>
dcache_mem_gnt <= '1';
if CYC_O_dcache = '0' then
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
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;
@@ -518,9 +364,9 @@ bus_state:
end process;
bus_timeout_counter:
process(cpu_clk)
process(clk)
begin
if rising_edge(cpu_clk) then
if rising_edge(clk) then
if bus_idle = '0' then
if bus_timeout_cnt /= 0 then
bus_timeout_cnt <= bus_timeout_cnt - 1;
@@ -535,15 +381,15 @@ bus_timeout_counter:
end process;
bus_err:
process(cpu_clk)
process(clk)
begin
if rising_edge(cpu_clk) then
if rising_edge(clk) then
if RST_I = '1' then
cpu_imem_err <= '0';
cpu_dmem_err <= '0';
imem_err <= '0';
dmem_err <= '0';
elsif bus_timeout = '1' then
cpu_imem_err <= icache_mem_gnt;
cpu_dmem_err <= dcache_mem_gnt or dmem_mem_wr_gnt or dmem_mem_rd_gnt;
imem_err <= icache_bus_gnt;
dmem_err <= dcache_bus_gnt;
end if;
end if;
end process;
+340
View File
@@ -0,0 +1,340 @@
--------------------------------------------------------------------------
-- 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;
File diff suppressed because it is too large Load Diff
+533 -297
View File
@@ -26,33 +26,46 @@ 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 := 2048; -- words
line_size : natural := 8 -- words
CACHE_SIZE : natural := 1024; -- words
LINE_SIZE : natural := 8; -- words
WRITE_FIFO_SIZE : natural := 4
);
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
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
);
END dcache;
@@ -83,27 +96,26 @@ 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 - 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 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 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;
tv_p : unsigned(tag_parity_width-1 downto 0);
tag : unsigned(tag_width-1 downto 0);
valid : std_logic;
tag : unsigned(tag_width-1 downto 0);
idx : unsigned(lg2(TLB_NUM_ENTRIES) 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.tv_p := x(3 downto 1);
result.tag := x(tag_width+3 downto 4);
result.tag := x(tag_width downto 1);
result.idx := x(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1);
return result;
end to_dcache_entry;
@@ -111,170 +123,314 @@ 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(3 downto 1) := x.tv_p;
result(tag_width+3 downto 4) := x.tag;
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;
return result;
end to_tag_ram_data;
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_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;
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);
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 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;
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;
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 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);
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;
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);
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);
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;
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 debug : debug_t;
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 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 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 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 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;
begin
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);
-- 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;
cpu_hit_we <= cpu_we2 and cache_hit;
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;
data_in_register:
process(CLK_I)
begin
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;
request_pa <= request_va;
write_hit <= cache_req_wr and cache_hit; -- and not tlb_query_in.exc;
fill_address_register:
process(CLK_I)
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)
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";
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;
end if;
end if;
end process;
request_address_register:
process(CLK_I)
process(clk)
begin
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';
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;
end if;
end if;
end process;
instant_raw_logic:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if rising_edge(clk) then
instant_raw <= '0';
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;
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;
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
(
@@ -283,10 +439,10 @@ inst_tag_ram : dpram_2w2r2c_ra
)
PORT MAP
(
clk_a => CLK_I,
clk_b => CLK_I,
clk_a => clk,
clk_b => clk,
re_a => '1',
re_b => '1',
re_b => ram_read_en,
we_a => tag_ram_we,
we_b => '0',
addr_a => tag_ram_addr_wr,
@@ -304,35 +460,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_I,
clk_b => CLK_I,
clk_a => clk,
clk_b => clk,
re_a => '1',
re_b => '1',
we_a => cpu_data_ram_we(i),
re_b => ram_read_en,
we_a => data_ram_we(i),
we_b => ctrl_data_ram_we(i),
addr_a => ctrl_data_ram_addr,
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),
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),
dout_a => open,
dout_b => cpu_data_ram_dout(8*(i+1)-1 downto 8*i)
dout_b => data_ram_dout(8*(i+1)-1 downto 8*i)
);
end generate;
cache_invalidate_request:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
if rising_edge(clk) then
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
invalidate_req <= '1';
invalidate_all <= ctrl.inv_all or RST_I;
invalidate_all <= ctrl_in.inv_all or rst;
tag_reg_inv <= tag_inv;
elsif invalidate_ack = '1' then
invalidate_req <= '0';
@@ -342,102 +498,144 @@ cache_invalidate_request:
end process;
cache_state_next:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
s <= init;
if rising_edge(clk) then
if rst = '1' then
cache_ctrl_state <= init;
cache_busy_state <= init;
else
s <= sn;
cache_ctrl_state <= cache_ctrl_state_next;
cache_busy_state <= cache_busy_state_next;
end if;
end if;
end process;
MRDY_O <= fill_count_en;
ADDR_O <= request_addr;
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;
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_entry_out <= to_dcache_entry(tag_ram_dout);
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
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;
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)
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';
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)
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';
CYC_O <= '0';
STB_O <= '0';
ram_write_en <= '0';
bus_cmd_cycle_en <= '0';
bus_cmd_we <= '0';
was_miss <= '0';
invalidate_en <= '0';
invalidate_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.tv_p <= (others => '0');
cache_entry_in.tag <= fill_tag;
cache_entry_in.valid <= '0';
sn <= s;
mem_fetch_ack <= '0';
read_write_buffer <= '0';
case s is
cache_entry_in.tag <= to_tag(request_pa);
cache_entry_in.valid <= '0';
cache_ctrl_state_next <= cache_ctrl_state;
case cache_ctrl_state is
when init =>
sn <= ready;
cache_ctrl_state_next <= ready;
when ready =>
if invalidate_req = '1' then
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;
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';
end if;
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;
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';
@@ -447,68 +645,106 @@ cache_state:
cache_entry_in.tag <= (others => '0');
if flush_count_rdy = '1' then
tag_ram_we <= '0';
sn <= rd_cache;
cache_ctrl_state_next <= invalidate_post;
end if;
when mem_request =>
CYC_O <= '1';
if SRDY_I = '1' then
sn <= mem_access;
end if;
when mem_access =>
fill_count_en <= '1';
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';
CYC_O <= '1';
STB_O <= '1';
ram_write_en <= '1';
fill_count_en <= '1';
if request_count_rdy = '1' then
STB_O <= '0';
sn <= mem_data;
bus_cmd_we <= '0';
cache_ctrl_state_next <= mem_read_data;
end if;
when mem_data =>
CYC_O <= '1';
fill_count_en <= '1';
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';
fill_count_en <= '1';
ram_write_en <= '1';
if fill_count_rdy = '1' then
tag_ram_we <= '1';
cache_entry_in.valid <= '1';
sn <= rd_cache;
cache_ctrl_state_next <= rd_cache;
end if;
when rd_cache =>
was_miss <= '1';
sn <= ready;
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;
when others =>
sn <= ready;
cache_ctrl_state_next <= ready;
end case;
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;
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;
request_counter:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if rising_edge(clk) then
if request_count_en = '0' then
request_count_rdy <= '0';
request_count <= 2**word_index_width-1;
else
if SRDY_I = '1' then
if bus_cmd_rdy = '1' then
if request_count /= 0 then
request_count <= request_count - 1;
else
@@ -520,14 +756,14 @@ request_counter:
end process;
fill_counter:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if rising_edge(clk) then
if fill_count_en = '0' then
fill_count_rdy <= '0';
fill_count <= 2**word_index_width-1;
else
if ACK_I_r = '1' then
if bus_din_vld = '1' then
if fill_count /= 0 then
fill_count <= fill_count - 1;
else
+276
View File
@@ -0,0 +1,276 @@
--------------------------------------------------------------------------
-- 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;
+409 -264
View File
@@ -26,30 +26,40 @@ 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 := 2048; -- words
line_size : natural := 8 -- words
CACHE_SIZE : natural := 1024; -- words
LINE_SIZE : natural := 8 -- 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
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
);
END icache;
@@ -65,7 +75,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);
@@ -97,27 +107,26 @@ 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 - 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 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 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;
tv_p : unsigned(tag_parity_width-1 downto 0);
tag : unsigned(tag_width-1 downto 0);
valid : std_logic;
tag : unsigned(tag_width-1 downto 0);
tlb_idx : unsigned(lg2(TLB_NUM_ENTRIES)-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.tv_p := x(3 downto 1);
result.tag := x(tag_width+3 downto 4);
result.tag := x(tag_width downto 1);
result.tlb_idx := x(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1);
return result;
end to_icache_entry;
@@ -125,150 +134,222 @@ 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(3 downto 1) := x.tv_p;
result(tag_width+3 downto 4) := x.tag;
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;
return result;
end to_tag_ram_data;
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_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;
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);
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 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 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;
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 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;
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 DAT_I_r : word_t;
signal ACK_I_r : std_logic;
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;
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 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;
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 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 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;
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);
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 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;
signal fill_word_index : unsigned(word_index_width-1 downto 0);
signal req_word_index : unsigned(word_index_width-1 downto 0);
begin
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);
-- 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;
-- 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';
data_in_register:
process(CLK_I)
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)
begin
if rising_edge(CLK_I) then
ACK_I_r <= ACK_I;
if ACK_I = '1' then
DAT_I_r <= DAT_I;
if rising_edge(clk) then
if cache_rdy = '1' then
cache_req_rd <= query_in.en;
end if;
end if;
end process;
-------------------------------------------------
fill_address_register:
process(CLK_I)
process(clk)
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";
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;
end if;
end if;
end process;
request_address_register:
process(CLK_I)
bus_request_address_register:
process(clk)
begin
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;
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;
cpu_request_register:
process(CLK_I)
single_read_register:
process(clk)
begin
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';
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 cache_ack = '1' then
cache_req <= '0';
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;
cache_invalidate_request:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
if rising_edge(clk) then
if rst = '1' or ctrl_in.inv_all = '1' or ctrl_in.inv_at = '1' then
invalidate_req <= '1';
invalidate_all <= ctrl.inv_all or RST_I;
invalidate_all <= ctrl_in.inv_all or rst;
tag_reg_inv <= tag_inv;
elsif invalidate_ack = '1' then
invalidate_req <= '0';
@@ -285,12 +366,12 @@ inst_tag_ram : dpram_2w2r2c_ra
)
PORT MAP
(
clk_a => CLK_I,
clk_b => CLK_I,
clk_a => clk,
clk_b => clk,
re_a => '1',
re_b => '1',
we_a => tag_ram_we,
we_b => '0',
re_b => ram_read_en,
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,
@@ -302,15 +383,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_I,
clk_b => CLK_I,
re_b => data_ram_re,
clk_a => clk,
clk_b => clk,
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,
@@ -318,172 +399,236 @@ inst_data_ram : dpram_1w1r2c_ra
);
cache_state_next:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if RST_I = '1' then
s <= init;
if rising_edge(clk) then
if rst = '1' then
cache_ctrl_state <= init;
cache_busy_state <= init;
else
s <= sn;
cache_ctrl_state <= cache_ctrl_state_next;
cache_busy_state <= cache_busy_state_next;
end if;
end if;
end process;
MRDY_O <= fill_count_en;
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
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;
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_dout <= single_read_reg when single_read_en = '1' else data_ram_data_rd;
query_out.data <= cache_dout;
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 <= 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;
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;
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;
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)
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)
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';
CYC_O <= '0';
STB_O <= '0';
ram_write_en <= '0';
bus_cmd_cycle_en <= '0';
bus_cmd_we <= '0';
was_miss <= '0';
invalidate_en <= '0';
invalidate_ack <= '0';
flush_load_en <= '0';
flush_count_en <= '0';
flush_addr_preset <= (others=>'0'); -- all
flush_count_preset <= 2**cache_index_width-1;
mem_fetch_ack <= '0';
cache_entry_in.tv_p <= (others => '0');
cache_entry_in.tag <= fill_tag;
cache_entry_in.tag <= to_tag(request_pa);
cache_entry_in.valid <= '0';
sn <= s;
cache_ctrl_state_next <= cache_ctrl_state;
case s is
case cache_ctrl_state is
when init =>
sn <= ready;
cache_ctrl_state_next <= ready;
when ready =>
if invalidate_req = '1' then
sn <= invalidate_init;
cache_ctrl_state_next <= invalidate;
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;
elsif cache_req = '1' then
if cache_hit = '0' then
sn <= mem_request;
CYC_O <= '1';
else
cache_busy <= '0';
cache_ack <= '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;
end if;
end if;
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 =>
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';
CYC_O <= '1';
STB_O <= '1';
if request_count_rdy = '1' then
STB_O <= '0';
sn <= mem_data;
bus_cmd_we <= '0';
cache_ctrl_state_next <= mem_read_data;
end if;
when mem_data =>
CYC_O <= '1';
fill_count_en <= '1';
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';
fill_count_en <= '1';
ram_write_en <= '1';
if fill_count_rdy = '1' then
tag_ram_we <= '1';
cache_entry_in.valid <= '1';
sn <= rd_cache;
cache_ctrl_state_next <= 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';
sn <= ready;
cache_ctrl_state_next <= ready;
when others =>
sn <= ready;
cache_ctrl_state_next <= ready;
end case;
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;
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;
request_counter:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if rising_edge(clk) then
if request_count_en = '0' then
request_count_rdy <= '0';
request_count <= 2**word_index_width-1;
else
if SRDY_I = '1' then
if bus_cmd_rdy = '1' then
if request_count /= 0 then
request_count <= request_count - 1;
else
@@ -495,14 +640,14 @@ request_counter:
end process;
fill_counter:
process(CLK_I)
process(clk)
begin
if rising_edge(CLK_I) then
if rising_edge(clk) then
if fill_count_en = '0' then
fill_count_rdy <= '0';
fill_count <= 2**word_index_width-1;
else
if ACK_I_r = '1' then
if bus_din_vld = '1' then
if fill_count /= 0 then
fill_count <= fill_count - 1;
else
+375 -297
View File
@@ -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_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
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
);
end pipeline;
@@ -146,87 +146,78 @@ 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_taken : STD_LOGIC;
signal branch_ce : STD_LOGIC;
signal cpu_run : 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 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 stage_rst : unsigned(3 downto 0);
signal pipe_rst : 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 c0_ctrl_in.exc_pending or ID_stage.exc or EX_stage.exc or MEM_stage.exc;
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.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.nop;
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.exc or WB_stage.exc or ctrl_in.exc_pending;
sdu.stall_all <= sdu.dmem_dep;
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or c0_ctrl_in.exc_exit;
sdu.ID_stall <= sdu.stall_all or sdu.imem_dep or sdu.mul_dep or ctrl_in.exc_exit;
sdu.EX_stall <= sdu.stall_all;
sdu.MEM_stall <= sdu.stall_all;
sdu.WB_stall <= sdu.stall_all;
sdu.WB_stall <= '0';
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
sdu.imem_dep <= not imem_rdy;
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
sdu.imem_dep <= not icache_qry_in.rdy;
sdu.dmem_dep <= not dcache_qry_in.rdy and MEM_stage.ctrl.dmem_en;
---------------------------------------------------------------------------
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;
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;
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
--------------------------------------------------------------------------
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;
ctrl_out.sdu <= sdu;
ctrl_out.exc_req <= WB_stage.exc and not WB_stage.exc_last;
ctrl_out.exc_ack <= '1';
cop_ir <= ID_stage.IR;
cop_ir_en <= ID_stage.ctrl.cop_instr_en;
cop_dout <= dmem_din when MEM_stage.ctrl.dmem_en = '1' else MEM_stage.ex_result;
cop_dout <= EX_stage.reg_b;
--------------------------------------------------------------------------
-- Muldiv
@@ -250,90 +241,191 @@ inst_muldiv: muldiv
--------------------------------------------------------------------------
-- IF stage
--------------------------------------------------------------------------
imem_addr <= pc.curr;
proc_stage_pc_next:
process(clk)
pipe_rst <= stage_rst(0);
proc_stage_reset:
process(clk_1)
begin
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;
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;
end if;
end process;
proc_stage_branch:
process(EX_stage, bcu_flags)
--------------------------------------------------------------------------
-- 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)
begin
pc.branch_take <= '0';
if EX_stage.ctrl.branch = '1' then
if ID_stage.ctrl.branch = '1' then
case EX_stage.ctrl.bc_src is
case ID_stage.ctrl.bc_src is
when bc_eq_ne =>
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq;
when bc_lez_gtz =>
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
pc.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz);
when bc_ltz_gez =>
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.ltz;
when others => null;
end case;
end if;
end process;
proc_stage_branch_taken:
process(clk)
proc_stage_branch_not:
process(EX_stage)
begin
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;
elsif sdu.ID_stall = '0' then
branch_taken <= '0';
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;
end if;
end if;
end if;
end process;
proc_stage_pc_branch:
process(clk)
proc_stage_pc_branch_alt:
process(clk_2)
begin
if rising_edge(clk) then
if sdu.ID_stall = '0' and ID_stage.ctrl.branch = '1' then
if rising_edge(clk_2) then
if cpu_run = '1' then
pc.pc_branch <= pc.curr + ID_stage.bimm18;
end if;
end if;
end process;
proc_stage_pc:
process(pc, branch_taken)
proc_stage_pc_curr_alt:
process(clk_1)
begin
if pc.branch_take = '1' or branch_taken = '1' then
pc.curr <= pc.pc_branch;
else
pc.curr <= pc.nxt;
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;
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(imem_data);
ID_stage.IR <= to_01(icache_qry_in.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);
@@ -346,13 +438,25 @@ proc_stage_pc:
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, c0_ctrl_in, pc)
process(ID_stage, ctrl_in, pc)
begin
ID_stage.events <= events_clr;
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);
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;
end process;
proc_stage_hdu:
@@ -366,19 +470,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.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';
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';
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;
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;
end process;
@@ -390,18 +494,12 @@ 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.data;
data := MEM_stage.result;
elsif hdu.alu_fwd_a_wb then
data := WB_stage.data;
data := WB_stage.result;
end if;
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;
ID_stage.reg_a <= to_mips_01(data) after 1 ns;
end process;
@@ -413,18 +511,12 @@ 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.data;
data := MEM_stage.result;
elsif hdu.alu_fwd_b_wb then
data := WB_stage.data;
data := WB_stage.result;
end if;
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;
ID_stage.reg_b <= to_mips_01(data) after 1 ns;
end process;
@@ -449,7 +541,7 @@ proc_imm_mux:
end case;
ID_stage.imm <= data;
ID_stage.imm <= data after 1 ns;
end process;
@@ -462,11 +554,11 @@ inst_reg_dual: reg_dual
)
PORT MAP
(
clk_w => clk,
we => WB_stage.wreg_we,
clk_w => clk_1,
we => WB_stage.reg_we,
en => '1',
wptr => WB_stage.reg_wptr,
din => WB_stage.data,
din => WB_stage.result,
rptr_a => ID_stage.reg_a_rptr,
rptr_b => ID_stage.reg_b_rptr,
dout_a => reg_a,
@@ -479,13 +571,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)
process(clk_1)
begin
if rising_edge(clk) then
if rst = '1' then
EX_stage.nop <= '1';
if rising_edge(clk_1) then
if stage_rst(1) = '1' then
EX_stage.op <= op_nop;
EX_stage.IR <= (others => '0');
EX_stage.ctrl <= ctrl_lines_default;
@@ -493,22 +585,20 @@ 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';
@@ -526,6 +616,15 @@ 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
@@ -540,30 +639,28 @@ 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)
process(clk_1)
begin
if rising_edge(clk) then
if rst = '1' then
dmem_en <= '0';
if rising_edge(clk_1) then
if pipe_rst = '1' then
EX_stage.dmem_en <= '0';
elsif sdu.EX_stall = '0' then
EX_events_mem <= events_clr;
dmem_en <= '0';
EX_stage.dmem_en <= '0';
if ID_stage.ctrl.dmem_en = '1' then
dmem_en <= '1';
EX_stage.dmem_en <= '1';
if ID_stage.ctrl.except_en = '1' then
if ID_stage.ctrl.word2_en = '1' then
if vaddr(0) = '1' then
if ID_stage.va(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;
dmem_en <= '0';
EX_stage.dmem_en <= '0';
end if;
elsif vaddr(1 downto 0) /= "00" then
elsif ID_stage.va(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;
dmem_en <= '0';
EX_stage.dmem_en <= '0';
end if;
end if;
end if;
@@ -572,28 +669,23 @@ proc_stage_EX_mem_except:
end process;
proc_stage_DMEM_ADDR:
process(clk)
process(clk_1)
begin
if rising_edge(clk) then
if rising_edge(clk_1) then
if sdu.EX_stall = '0' then
if c0_ctrl_in.EB = '1' then
if ctrl_in.EB = '1' then
if ID_stage.ctrl.word2_en = '0' then
EX_stage.pa_off <= not vaddr(1 downto 0);
EX_stage.pa_off <= not ID_stage.va(1 downto 0);
else
EX_stage.pa_off <= not vaddr(1) & vaddr(0);
EX_stage.pa_off <= not ID_stage.va(1) & ID_stage.va(0);
end if;
else
EX_stage.pa_off <= vaddr(1 downto 0);
EX_stage.pa_off <= ID_stage.va(1 downto 0);
end if;
end if;
end if;
end process;
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.events <= EX_events_DTLB or 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);
--------------------------------------------------------------------------
@@ -611,19 +703,19 @@ proc_wptr_mux:
reg_wptr := extract_rt(EX_stage.IR);
end case;
EX_stage.wreg_we <= EX_stage.reg_write;
EX_stage.reg_we <= EX_stage.reg_write after 1 ns;
if reg_wptr = "00000" then
EX_stage.wreg_we <= '0';
EX_stage.reg_we <= '0' after 1 ns;
end if;
EX_stage.reg_wptr <= reg_wptr;
EX_stage.reg_wptr <= reg_wptr after 1 ns;
case EX_stage.ctrl.wptr_srcsel is
when wptr_src_imm =>
EX_stage.reg_wptr <= reg_wptr;
EX_stage.reg_wptr <= reg_wptr after 1 ns;
when wptr_src_const =>
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length);
EX_stage.wreg_we <= '1';
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
EX_stage.reg_we <= '1' after 1 ns;
when others => null;
end case;
@@ -631,76 +723,62 @@ 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)
process(clk_1)
variable data : word_t;
begin
if rising_edge(clk) then
if sdu.EX_stall = '0' then
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 =>
data := ID_stage.reg_b;
case ID_stage.ctrl.alu.op2_src is
when alu_src_imm =>
data := ID_stage.imm;
when alu_src_reg =>
data := ID_stage.reg_b;
when others => null;
when alu_src_imm =>
data := ID_stage.imm;
end case;
when others => null;
end case;
EX_stage.alu_op2 <= data;
end if;
EX_stage.alu_op2 <= data;
end if;
end process;
shifter_sa_mux:
process(clk)
process(clk_1)
variable data : shamt_t;
variable data_inv : shamt_t;
begin
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
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
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;
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 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 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;
@@ -733,43 +811,31 @@ 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)
process(clk_1)
begin
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');
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');
MEM_stage.events_in <= events_clr;
elsif sdu.MEM_stall = '0' then
MEM_stage.nop <= sdu.MEM_nop;
MEM_stage.events_in <= EX_stage.events;
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.wreg_we <= EX_stage.wreg_we;
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.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;
@@ -777,44 +843,40 @@ 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.ex_result <= MEM_stage.data;
MEM_stage.result_in <= MEM_stage.result;
end if;
else
MEM_stage.ex_result <= EX_stage.reg_b;
MEM_stage.result_in <= 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.ex_result <= cop_din;
MEM_stage.result_in <= cop_din;
end if;
elsif EX_stage.ctrl.dmem_en = '0' then
MEM_stage.ex_result <= EX_stage.result;
MEM_stage.result_in <= EX_stage.result;
end if;
if sdu.MEM_nop = '1' then
MEM_stage.op <= op_nop;
MEM_stage.wreg_we <= '0';
MEM_stage.reg_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, dmem_din)
process(MEM_stage, dcache_qry_in.data)
variable temp1 : word_t;
variable temp2 : word_t;
variable data : word_t;
variable be : unsigned(3 downto 0);
begin
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);
data := MEM_stage.result_in;
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;
@@ -828,16 +890,16 @@ proc_stage_MEM_mux:
data(31 downto 24) := temp2(31 downto 24);
end if;
end if;
MEM_stage.data <= data;
MEM_stage.result <= data after 1 ns;
end process;
proc_stage_MEM_except:
process(MEM_stage, c0_ctrl_in)
process(MEM_stage, ctrl_in)
begin
MEM_stage.events <= MEM_stage.events_in;
MEM_stage.events.Int <= c0_ctrl_in.int;
MEM_stage.events.NMI <= c0_ctrl_in.NMI;
MEM_stage.events.Int <= ctrl_in.int;
MEM_stage.events.NMI <= ctrl_in.NMI;
end process;
MEM_stage.exc <= event_is_active(MEM_stage.events);
@@ -846,34 +908,50 @@ proc_stage_MEM_except:
-- WB stage
--------------------------------------------------------------------------
proc_stage_WB_p:
process(clk)
process(clk_1)
variable branch_delay : std_logic;
begin
if rising_edge(clk) then
if rst = '1' then
WB_stage.nop <= '1';
if rising_edge(clk_1) then
if stage_rst(3) = '1' then
WB_stage.op <= op_nop;
WB_stage.wreg_we <= '1';
WB_stage.reg_we <= '1';
WB_stage.reg_wptr <= (others => '0');
WB_stage.data <= (others => '0');
WB_stage.events <= events_clr;
WB_stage.bd <= '0';
WB_stage.epc <= (others => '0');
WB_stage.events <= events_clr;
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.wreg_we <= MEM_stage.wreg_we;
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
WB_stage.data <= MEM_stage.data;
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;
if MEM_stage.exc = '1' then
WB_stage.events <= MEM_stage.events;
WB_stage.reg_we <= MEM_stage.reg_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;
end if;
if sdu.WB_nop = '1' then
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
WB_stage.reg_we <= '0';
end if;
if WB_stage.exc = '0' then
WB_stage.va <= MEM_stage.va;
end if;
end if;
end if;
end process;
+17 -17
View File
@@ -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(data_width_arg : natural) return fill_mask_rom_t is
function gen_fill_mask_rom(width : natural) return fill_mask_rom_t is
variable result : fill_mask_rom_t;
begin
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');
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');
end loop;
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');
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');
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;
dout <= dout_filled after 5 ns;
--------------------------------------------------------------------------
end Behavioral;
+340
View File
@@ -0,0 +1,340 @@
--------------------------------------------------------------------------
-- 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;
+168 -109
View File
@@ -31,14 +31,16 @@ 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
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
);
Port
(
debug : out unsigned(1 downto 0);
debug : out chip_debug_t;
eb : in STD_LOGIC;
nmi : in STD_LOGIC;
cpu_clk : in STD_LOGIC;
@@ -67,42 +69,32 @@ architecture rtl of mips_top is
COMPONENT pipeline is
Port
(
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
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
);
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;
@@ -111,8 +103,14 @@ 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_c0_ctrl_out : cop0_ctrl_in_t;
signal pipe_c0_ctrl_in : cop0_ctrl_out_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;
--------------------------------------------------------------------------
-- Coprocessor
@@ -147,53 +145,48 @@ architecture rtl of mips_top is
COMPONENT biu
GENERIC
(
icache_size : natural;
icache_line : natural;
dcache_size : natural;
dcache_line : natural
icache_size : natural;
icache_line : natural;
dcache_size : natural;
dcache_line : natural;
WRITE_FIFO_SIZE : natural;
WITH_TLB : boolean;
TRANSLATE_KSEG0_1 : boolean
);
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);
DAT_I : in unsigned(31 downto 0);
DAT_O : out unsigned(31 downto 0);
MDAT_I : in unsigned(31 downto 0);
MDAT_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;
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
ctrl_in : in biu_ctrl_in_t;
ctrl_out : out biu_ctrl_out_t
);
END COMPONENT;
begin
-------------------------------------------------------------------
debug(0) <= imem_err;
debug(1) <= dmem_err;
process(CLK_I)
process(cpu_clk)
variable reset_delay : unsigned (31 downto 0);
begin
if rising_edge(CLK_I) then
if rising_edge(cpu_clk) then
if RST_I = '1' then
reset_delay := (others => '0');
biu_rst <= '1';
@@ -207,7 +200,7 @@ begin
if reset_delay(31) = '1' then
cpu_rst <= '0';
end if;
if reset_delay(16) = '1' then
if reset_delay(16) = '1' and biu_busy = '0' then
cpu_run <= '1';
end if;
end if;
@@ -217,28 +210,29 @@ begin
inst_pipeline: pipeline
PORT MAP
(
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
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
);
pipe_ctrl_in <= cop0_ctrl_out.pipe;
inst_cop: cop
GENERIC MAP
(
@@ -256,49 +250,114 @@ inst_cop: cop
int => INT,
ir_en => pipe_cop_ir_en,
ir => pipe_cop_ir,
ctrl_in => pipe_c0_ctrl_out,
ctrl_out => pipe_c0_ctrl_in,
ctrl_in => cop0_ctrl_in,
ctrl_out => cop0_ctrl_out,
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
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
)
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,
DAT_I => DAT_I,
DAT_O => DAT_O,
MDAT_I => DAT_I,
MDAT_O => DAT_O,
WE_O => WE_O,
SEL_O => SEL_O,
CYC_O => CYC_O,
STB_O => STB_O,
MRDY_O => MRDY_O,
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
ctrl_in => biu_ctrl_in,
ctrl_out => biu_ctrl_out
);
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;
+212 -48
View File
@@ -26,12 +26,18 @@ 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 := 13;
constant WORD_WIDTH : integer := 32;
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;
--Types
subtype instr_name_t is string(1 to 12);
@@ -45,9 +51,17 @@ 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,
@@ -159,11 +173,14 @@ 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;
branch_take : std_logic;
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;
end record;
type alu_outsel_t is
@@ -227,6 +244,12 @@ 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
@@ -239,6 +262,12 @@ 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;
@@ -249,25 +278,108 @@ 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 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;
type tlb_flags_t is record
N : std_logic;
D : std_logic;
V : std_logic;
end record;
type cop0_ctrl_out_t is 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
EB : STD_LOGIC;
exc_inject : STD_LOGIC;
exc_commit : STD_LOGIC;
@@ -277,6 +389,29 @@ 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;
@@ -337,76 +472,93 @@ package mips_types is
type ID_t is record
nop : STD_LOGIC;
exc : std_logic;
IR : word_t;
op : op_t;
pcn : word_t;
IR : word_t;
epc : word_t;
pcn : 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;
IR : word_t;
op : op_t;
pcn : word_t;
IR : word_t;
epc : word_t;
pcn : 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;
wreg_we : STD_LOGIC;
reg_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;
pcn : word_t;
epc : word_t;
pcn : word_t;
reg_a : word_t;
reg_b : word_t;
result : word_t;
result_in : word_t;
ctrl : ctrl_lines_t;
ex_result : word_t;
reg_wptr : reg_ptr_t;
wreg_we : STD_LOGIC;
data : word_t;
reg_we : STD_LOGIC;
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;
wreg_we : STD_LOGIC;
data : word_t;
bd : STD_LOGIC;
reg_we : STD_LOGIC;
va : word_t;
bcu_flags : bcu_flags_t;
end record;
@@ -422,9 +574,7 @@ 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 lg2(x : natural) return natural;
function po2(x : natural) return natural;
function "or" (a, b : tlb_flags_t) return tlb_flags_t;
end mips_types;
@@ -585,9 +735,6 @@ 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);
@@ -611,6 +758,12 @@ 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;
@@ -633,6 +786,12 @@ 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;
@@ -653,23 +812,28 @@ 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 lg2(x : natural) return natural is
function "or" (a, b : tlb_flags_t) return tlb_flags_t is
variable result : tlb_flags_t;
begin
return natural(ceil(log2(real(x))));
end lg2;
--------------------------------------------------------------------------
function po2(x : natural) return natural is
begin
return 2**lg2(x);
end po2;
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";
--------------------------------------------------------------------------
end mips_types;
+68
View File
@@ -0,0 +1,68 @@
--------------------------------------------------------------------------
-- 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;
+410
View File
@@ -0,0 +1,410 @@
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;
+265
View File
@@ -0,0 +1,265 @@
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;
+211
View File
@@ -0,0 +1,211 @@
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;
+171 -31
View File
@@ -25,6 +25,7 @@
LIBRARY ieee;
use IEEE.STD_LOGIC_1164.ALL;
USE ieee.numeric_std.ALL;
USE std.textio.ALL;
library work;
use work.mips_types.all;
@@ -33,21 +34,18 @@ 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 := 18; -- bits
constant FLASH_ADDR_WIDTH : integer := 18; -- bits
signal debug : unsigned(1 downto 0);
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';
-- Master
signal nmi : STD_LOGIC := '0';
@@ -118,9 +116,45 @@ 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_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);
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);
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
------------------------------------------------------------------
@@ -133,6 +167,46 @@ 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
@@ -157,6 +231,7 @@ mem_mux:
mem_area <= mem_sram;
end if;
end process;
end generate;
signal_mux:
process(mem_area, CYC_O)
@@ -204,8 +279,10 @@ signal_mux:
uut: entity work.mips_top
GENERIC MAP
(
icache_size => 1024, -- words
dcache_size => 1024 -- words
icache_size => 256, -- words
dcache_size => 256, -- words
WITH_TLB => WITH_TLB,
TRANSLATE_KSEG0_1 => KSEG_01_TRANSLATED
)
PORT MAP
(
@@ -229,7 +306,6 @@ uut: entity work.mips_top
);
INT(1) <= int_uart;
INT(5) <= int_timer;
INT(2) <= '1';
inst_rom : entity work.rom_wb
PORT MAP
@@ -361,16 +437,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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) after 10 ns;
sram_d(7 downto 0) <= sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) after 10 ns;
sram_d(15 downto 8) <= sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) after 10 ns;
sram_d(23 downto 16) <= sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
sram_d(31 downto 24) <= sram_data(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) after 10 ns;
end if;
end if;
end if;
@@ -382,26 +458,31 @@ SRAM_WRITE:
if rising_edge(sram_wr_n) then
if sram_cs_n = '0' then
if sram_be_n(0) = '0' then
sram_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(7 downto 0) <= sram_d(7 downto 0);
sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(15 downto 8) <= sram_d(15 downto 8);
sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(23 downto 16) <= sram_d(23 downto 16);
sram_data(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_memory_content(to_integer(sram_a(SRAM_ADDR_WIDTH-1 downto 2)))(31 downto 24) <= sram_d(31 downto 24);
sram_data(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 app;
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";
variable instr : integer;
variable index : natural;
variable temp : signed(31 downto 0);
@@ -412,7 +493,7 @@ FLASH_READ:
while not endfile(load_flash) loop
read(load_flash, instr);
temp := to_signed(instr, word_t'length);
flash_memory_content(index) <= unsigned(temp);
flash_data(index) <= unsigned(temp);
index := index + 1;
end loop;
else
@@ -421,22 +502,78 @@ 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_memory_content(index)(7 downto 0) after tpd;
flash_d(7 downto 0) <= flash_data(index)(7 downto 0) after tpd;
end if;
if flash_be_n(1) = '0' then
flash_d(15 downto 8) <= flash_memory_content(index)(15 downto 8) after tpd;
flash_d(15 downto 8) <= flash_data(index)(15 downto 8) after tpd;
end if;
if flash_be_n(2) = '0' then
flash_d(23 downto 16) <= flash_memory_content(index)(23 downto 16) after tpd;
flash_d(23 downto 16) <= flash_data(index)(23 downto 16) after tpd;
end if;
if flash_be_n(3) = '0' then
flash_d(31 downto 24) <= flash_memory_content(index)(31 downto 24) after tpd;
flash_d(31 downto 24) <= flash_data(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
@@ -446,10 +583,13 @@ STIMULUS: process
wait for 3*CLK_PERIOD;
wait until rising_edge(clk);
rst <= '0';
nmi <= '0';
wait for 1200000*CLK_PERIOD;
wait until rising_edge(clk);
wait for 1500 us;
tb_fin <= '1';
wait until rising_edge(clk);
tb_fin <= '0';
wait;
-1
View File
@@ -1,4 +1,3 @@
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 "24.1std.0 Standard Edition"
set_global_assignment -name LAST_QUARTUS_VERSION "21.1.1 Lite 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,5 +320,4 @@ 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.
@@ -1,806 +0,0 @@
# -------------------------------------------------------------------------- #
#
# 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 ?
@@ -1,3 +0,0 @@
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
@@ -1,2 +0,0 @@
{ "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 -2
View File
@@ -1,4 +1,3 @@
include $(VHDL_HOME)/defs.mk
PRJDIR := ./project
PRJ := mips_sys
@@ -8,5 +7,5 @@ DEVICE := "xc4vsx35-ff668-10"
NETLIST_DIR := $(VHDL_HOME)/lib/CPUs/MIPS/syn/ise101
NETLISTS := $(NETLIST_DIR)/mips_top.ngc
include $(VHDL_MAKE_HOME)/ise.mk
include $(VHDL_HOME)/make/ise.mk