Compare commits
25
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4666087f93 | ||
|
|
b72ba39983 | ||
|
|
fa38290367 | ||
|
|
90b9112c5b | ||
|
|
007c2ade02 | ||
|
|
537b5d3fd4 | ||
|
|
03f21b37d4 | ||
|
|
4c7100a5a7 | ||
|
|
41939cf290 | ||
|
|
8a6d599836 | ||
|
|
02e35db54c | ||
|
|
cb32a5aeed | ||
|
|
f5bf4fdb81 | ||
|
|
41513a9de0 | ||
|
|
feb60baa33 | ||
|
|
4ba64fdb3b | ||
|
|
81698e2391 | ||
|
|
6c7780bee9 | ||
|
|
a927b88db3 | ||
|
|
a3b0766258 | ||
|
|
e59d0f2904 | ||
|
|
e5a31bdf7c | ||
|
|
6dfac747b6 | ||
|
|
9870f78e51 | ||
|
|
eacfe7f9d2 |
@@ -0,0 +1,48 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# Packages
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_async.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_biu.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_biu
|
||||
do {tb_mips_biu.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -0,0 +1,160 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_biu/clk
|
||||
add wave -noupdate -format Logic /tb_biu/rst
|
||||
add wave -noupdate -format Logic /tb_biu/int_o
|
||||
add wave -noupdate -format Logic /tb_biu/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/stb_o
|
||||
add wave -noupdate -format Logic /tb_biu/we_o
|
||||
add wave -noupdate -format Literal /tb_biu/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/ack_i
|
||||
add wave -noupdate -format Logic /tb_biu/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_biu/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/mdat_o
|
||||
add wave -noupdate -format Literal /tb_biu/index_in
|
||||
add wave -noupdate -format Logic /tb_biu/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_biu/index_out
|
||||
add wave -noupdate -format Logic /tb_biu/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/entry_hi_out
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_err
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_err
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_en
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_addr
|
||||
add wave -noupdate -format Literal /tb_biu/cpu_dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/ctrl_out
|
||||
add wave -noupdate -divider BIU
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk_i
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_imem_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_imem_din_reg
|
||||
add wave -noupdate -format Logic /tb_biu/cpu_dmem_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/cpu_dmem_din_reg
|
||||
add wave -noupdate -format Literal /tb_biu/op_descr
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_err
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/imem_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/imem_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/imem_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_err
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dmem_we
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/dmem_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/dmem_addr
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/rst_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/srdy_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/stb_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/mdat_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/ack_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/mdat_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/we_o
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/ctrl_out
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/s
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_idle
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/bus_timeout_cnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_timeout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/rst
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_din
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_dout_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/i_bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/i_bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/d_bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/d_bus_cmd
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/icache_bus_gnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/dcache_bus_gnt
|
||||
add wave -noupdate -divider BUS-Master
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/clk
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/rst
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/din
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/din_rdy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/dout_vld
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/dout_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/ack_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/mdat_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/srdy_i
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/stb_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/addr_o
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/inst_busmaster/sel_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/we_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cyc_o
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_biu/inst_biu/inst_busmaster/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_en
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_biu/inst_biu/inst_busmaster/read_cnt
|
||||
add wave -noupdate -format Logic /tb_biu/inst_biu/inst_busmaster/write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {3126068 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {10500 ns}
|
||||
@@ -0,0 +1,24 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_cam.vhd"
|
||||
vsim -t 1ps -lib work tb_cam
|
||||
do {tb_mips_cam.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 80us
|
||||
@@ -0,0 +1,69 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_cam/clk_o
|
||||
add wave -noupdate -format Logic /tb_cam/rst_o
|
||||
add wave -noupdate -format Logic /tb_cam/cam_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_addr
|
||||
add wave -noupdate -format Logic /tb_cam/cam_vld
|
||||
add wave -noupdate -format Logic /tb_cam/cam_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_wtag
|
||||
add wave -noupdate -format Logic /tb_cam/cam_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_rtag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/cam_hit
|
||||
add wave -noupdate -format Logic /tb_cam/cam_hit_vld
|
||||
add wave -noupdate -divider CAM
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/state
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/debug
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/num_entries
|
||||
add wave -noupdate -format Literal /tb_cam/inst_cam/data_width
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rst
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clk
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rdy
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/re
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/we
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/hit
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/cam_ram_result
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_addr
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/clear_count_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/clear_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/vld_cam
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/pipe3
|
||||
add wave -noupdate -divider Track-RAM
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/over_write
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/track_ram_we
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/rdy
|
||||
add wave -noupdate -format Logic /tb_cam/inst_cam/we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_cam/inst_cam/track_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_cam/inst_cam/inst_track_ram/ram
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {34938145 ps} 0}
|
||||
configure wave -namecolwidth 137
|
||||
configure wave -valuecolwidth 214
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {84 us}
|
||||
@@ -0,0 +1,45 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_sync.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_dcache.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_dcache
|
||||
do {tb_mips_dcache.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -0,0 +1,263 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/int_o
|
||||
add wave -noupdate -format Logic /tb_dcache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/we_o
|
||||
add wave -noupdate -format Literal /tb_dcache/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_dcache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/tlb_index_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/tlb_pa
|
||||
add wave -noupdate -format Literal -expand /tb_dcache/tlb_flags
|
||||
add wave -noupdate -format Logic /tb_dcache/tlb_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/cpu_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/dcache_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cyc_complete
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_entry_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_hit
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/tlb_blk_flags
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_pfn
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/tlb_blk_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_tlb/flags
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_dcache/inst_dcache/debug
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/cache_ctrl_state
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din_reg
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/request_pa
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/addr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tlb_exc
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/tlb_exc_type
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/read_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/we_reg
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_dcache/inst_dcache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/cache_hit_inv
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_ram_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/data_reg
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/be_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/ctrl_data_ram_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/ctrl_data_ram_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_dout_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/hit_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/fill_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/inst_tag_ram/ram
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/write_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_dcache/write_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/read_write_buffer
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_dcache/write_through_en
|
||||
add wave -noupdate -divider Bus-Master
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/din
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/dout_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/addr_o
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_busmaster_sync/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/we_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/inst_busmaster_sync/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_en
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_dcache/inst_busmaster_sync/read_cnt
|
||||
add wave -noupdate -format Logic /tb_dcache/inst_busmaster_sync/write
|
||||
add wave -noupdate -format Logic /tb_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_dcache/int_o
|
||||
add wave -noupdate -format Logic /tb_dcache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_dcache/stb_o
|
||||
add wave -noupdate -format Logic /tb_dcache/we_o
|
||||
add wave -noupdate -format Literal /tb_dcache/sel_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ack_i
|
||||
add wave -noupdate -format Logic /tb_dcache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_dcache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/mdat_o
|
||||
add wave -noupdate -format Logic /tb_dcache/ce
|
||||
add wave -noupdate -format Literal /tb_dcache/index_in
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_dcache/index_out
|
||||
add wave -noupdate -format Logic /tb_dcache/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_dcache/tlb_index_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/tlb_pa
|
||||
add wave -noupdate -format Literal -expand /tb_dcache/tlb_flags
|
||||
add wave -noupdate -format Logic /tb_dcache/tlb_hit
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal /tb_dcache/cpu_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/cpu_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/dcache_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_dcache/bus_cmd
|
||||
add wave -noupdate -format Logic /tb_dcache/bus_cyc_complete
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {743514 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {3533088 ps}
|
||||
@@ -0,0 +1,45 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/ram_wb.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_sim.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/gray_counter.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_sync.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async_ctrl.vhd"
|
||||
vcom -explicit -93 "../../../FIFO/src/fifo_async.vhd"
|
||||
|
||||
# MIPS Cache
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
|
||||
# MIPS TLB
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
# Busmaster
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_sync.vhd"
|
||||
vcom -explicit -93 "../src/tb_mips_icache.vhd"
|
||||
|
||||
vsim -t 1ps -lib work tb_icache
|
||||
do {tb_mips_icache.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 10us
|
||||
@@ -0,0 +1,162 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_icache/clk
|
||||
add wave -noupdate -format Logic /tb_icache/rst
|
||||
add wave -noupdate -format Logic /tb_icache/int_o
|
||||
add wave -noupdate -format Logic /tb_icache/cyc_o
|
||||
add wave -noupdate -format Logic /tb_icache/stb_o
|
||||
add wave -noupdate -format Logic /tb_icache/we_o
|
||||
add wave -noupdate -format Literal /tb_icache/sel_o
|
||||
add wave -noupdate -format Logic /tb_icache/ack_i
|
||||
add wave -noupdate -format Logic /tb_icache/mrdy_o
|
||||
add wave -noupdate -format Logic /tb_icache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/mdat_o
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/ce
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/index_in
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/entry_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_lo_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_hi_in
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/index_out
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/entry_re
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_lo_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/entry_hi_out
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_entry_we
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_hit
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/tlb_blk_flags
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_pfn
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/tlb_blk_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_icache/inst_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_icache/inst_tlb/flags
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/cpu_din_reg
|
||||
add wave -noupdate -format Logic /tb_icache/cpu_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/request_pa
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/dout
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/cache_ctrl_state
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/single_read_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/ctrl_in
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/bus_din
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/cache_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_match
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/data_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_rd_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/tag_ram_data_wr
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/fill_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/flush_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/request_count
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/ram_read_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/was_miss
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_icache/fill_word_index
|
||||
add wave -noupdate -format Logic /tb_icache/inst_icache/tlb_exc
|
||||
add wave -noupdate -format Literal /tb_icache/inst_icache/tlb_exc_type
|
||||
add wave -noupdate -divider Busmaster
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/clk
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/rst
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/din
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/din_rdy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/dout
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/dout_vld
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/dout_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/ack_i
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/addr_o
|
||||
add wave -noupdate -format Literal /tb_icache/inst_busmaster_sync/sel_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/we_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cyc_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/stb_o
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_icache/inst_busmaster_sync/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_en
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_icache/inst_busmaster_sync/read_cnt
|
||||
add wave -noupdate -format Logic /tb_icache/inst_busmaster_sync/write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {1549212 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {1322906 ps} {1804473 ps}
|
||||
@@ -0,0 +1,27 @@
|
||||
## NOTE: Do not edit this file.
|
||||
##
|
||||
vlib work
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r1wc_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ro_sim.vhd"
|
||||
|
||||
|
||||
# FIFOS
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
|
||||
vcom -explicit -93 "../src/tb_mips_tlb.vhd"
|
||||
vsim -t 1ps -lib work tb_tlb
|
||||
do {tb_mips_tlb.wdo}
|
||||
view wave
|
||||
view structure
|
||||
view signals
|
||||
run 200us
|
||||
@@ -0,0 +1,74 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -format Logic /tb_tlb/clk_o
|
||||
add wave -noupdate -format Logic /tb_tlb/rst_o
|
||||
add wave -noupdate -format Logic /tb_tlb/ce
|
||||
add wave -noupdate -format Logic /tb_tlb/tlb_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/tlb_ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_tlb/tlb_query_out
|
||||
add wave -noupdate -divider TLB
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/hit_idx
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/num_entries
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/rst
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/clk
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/qry_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/stat_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/pa
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/cam_hit_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/vaddr_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_res
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_umc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/entry_lo_umuc
|
||||
add wave -noupdate -divider REG:LO
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_reg_entry_lo/dout_b
|
||||
add wave -noupdate -divider CAM
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/clk
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/state
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/state_next
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/tag_wr
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/tag_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe3
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe0_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe1_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe2_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/pipe3_rd
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/busy
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/cam_ram_re
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/cam_ram_addr_rd
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/track_ram_we
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/track_ram_dout
|
||||
add wave -noupdate -format Literal /tb_tlb/inst_uut/inst_cam_va/clear_addr
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/clear_count_rdy
|
||||
add wave -noupdate -format Logic /tb_tlb/inst_uut/inst_cam_va/over_write
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_tlb/inst_uut/inst_cam_va/inst_track_ram/ram
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {3385000 ps} 0}
|
||||
configure wave -namecolwidth 150
|
||||
configure wave -valuecolwidth 111
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 1
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 0
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {10940666 ps}
|
||||
@@ -2,7 +2,14 @@
|
||||
##
|
||||
vlib work
|
||||
|
||||
# Packages
|
||||
vcom -explicit -93 "../src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../misc/utils_pkg.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_types.vhd"
|
||||
|
||||
# RAMS
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r1wc_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_1w1r2c_ra_sim.vhd"
|
||||
vcom -explicit -93 "../../../rams/dpram_2w2r2c_ro_sim.vhd"
|
||||
@@ -34,11 +41,10 @@ vcom -explicit -93 "../../../misc/async_port_wb.vhd"
|
||||
vcom -explicit -93 "../src/async_defs.vhd"
|
||||
|
||||
# ROM
|
||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||
vcom -explicit -93 "../src/bootloader_flash.ROM.vhd"
|
||||
vcom -explicit -93 "../../../misc/rom_wb.vhd"
|
||||
|
||||
# MIPS
|
||||
vcom -explicit -93 "../src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_instr.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_reg.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_shifter.vhd"
|
||||
@@ -47,6 +53,9 @@ vcom -explicit -93 "../src/core/mips_muldiv.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cop.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_icache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_dcache.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_tlb.vhd"
|
||||
vcom -explicit -93 "../../../JBUS/src/busmaster_async.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_biu.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_bcu.vhd"
|
||||
vcom -explicit -93 "../src/core/mips_pipeline.vhd"
|
||||
|
||||
@@ -0,0 +1,454 @@
|
||||
onerror {resume}
|
||||
quietly WaveActivateNextPane {} 0
|
||||
add wave -noupdate -divider {TOP interface}
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/nmi
|
||||
add wave -noupdate -format Logic /tb_mips_top/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/cyc_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/dat_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/sel_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/mrdy_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/int
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_shifter/dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/biu_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/cpu_run
|
||||
add wave -noupdate -divider BIU
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/bus_timeout_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_timeout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/bus_idle
|
||||
add wave -noupdate -divider Busmaster
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/rst
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_cycle_finished
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_cycle_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/din_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/dout_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/dout_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/rst_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/clk_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/mdat_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/mdat_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/addr_o
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/sel_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cyc_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/read_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cycle_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/cmd_read_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/read_cnt
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/write
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_busmaster/jbus_cycle_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_busmaster/jbus_state
|
||||
add wave -noupdate -divider {External components}
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpi_0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/gpo_0
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_uart/tx_empty
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_uart/uart_status_port
|
||||
add wave -noupdate -format Logic /tb_mips_top/rx
|
||||
add wave -noupdate -format Logic /tb_mips_top/tx
|
||||
add wave -noupdate -format Literal -radix ascii /tb_mips_top/inst_uart/reg_uart_tx
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_uart/reg_uart_rx
|
||||
add wave -noupdate -divider SRAM
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_wr_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||
add wave -noupdate -divider FLASH
|
||||
add wave -noupdate -format Literal /tb_mips_top/mem_area
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_page_mode_en
|
||||
add wave -noupdate -divider {Interrupt Timer}
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cnt
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/timer_cmp
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_inten
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_ovl
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_irq_ack
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_gpio/timer_cmp_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_gpio/reg_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_flash_port/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/srdy_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/we_o
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/we_i_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/inst_flash_port/addr_i_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/page_mode_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_flash_port/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/flash_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_cs_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_we_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/flash_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/flash_be_n
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_a
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/sram_d
|
||||
add wave -noupdate -format Logic /tb_mips_top/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_cs_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_wr_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/sram_oe_n
|
||||
add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/page_mode_en_r
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/do_page_read
|
||||
add wave -noupdate -format Logic /tb_mips_top/inst_sram_port/rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/inst_sram_port/s
|
||||
add wave -noupdate -divider ALU
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||
add wave -noupdate -format Literal -expand /tb_mips_top/uut/inst_pipeline/sdu
|
||||
add wave -noupdate -divider PC
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage.ctrl.branch
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/branch_ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/pc
|
||||
add wave -noupdate -divider COP0
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/ir_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ir
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/icache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dcache_info
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_id
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/cop_pipe_ex
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/ctrl_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/itlb_exc
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/dtlb_exc
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/tlb_sel
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/itlb_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/itlb_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dtlb_entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/dtlb_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/entry_hi
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/entry_lo
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/ex_reg_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/regs
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/eflags
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_save
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_cop/status_rest
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/random
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_cop/index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_cop/exc_state
|
||||
add wave -noupdate -divider Pipestages
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
||||
add wave -noupdate -format Logic -label .stall_all /tb_mips_top/uut/inst_pipeline/sdu.stall_all
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/id_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ex_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/mem_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/mem_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||
add wave -noupdate -format Logic -radix hexadecimal /tb_mips_top/uut/inst_pipeline/wb_stage.exc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/dtlb_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/dtlb_qry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/itlb_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/itlb_qry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/icache_qry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/icache_qry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/cache_ctrl_state
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/query_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/request_pa
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/single_read_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/bus_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_din_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/data_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_rd_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_data_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/ram_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/invalidate_req
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/inst_tag_ram/ram
|
||||
add wave -noupdate -divider I-TLB
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_i_tlb/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/hit
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/vld_r
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/vaddr_reg
|
||||
add wave -noupdate -divider I-TLB-CAM
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cache_busy_state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cache_ctrl_state
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_through_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_req_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_req_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_va
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/request_pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_set
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/read_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_din_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_din_vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout_vld
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_dout_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_cycle_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/bus_cmd_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/bus_cyc_complete
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit_inv
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_dout
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/be_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/ctrl_data_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/data_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/single_read_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_dout_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_all
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/invalidate_req
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/ram_write_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/req_word_index
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/hit_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_data_avail
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/read_write_buffer
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/write_through_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_sel_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_data_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_addr_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_sel_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_data_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/write_fifo_addr_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/inst_tag_ram/ram
|
||||
add wave -noupdate -divider D-TLB
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/ce
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_biu/inst_d_tlb/query_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_d_tlb/blk_hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/blk_entry_lo
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/pa
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_d_tlb/hit
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_ctrl_entry_lo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_ctrl_entry_lo_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_qry_entry_lo_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/reg_qry_entry_lo_addr
|
||||
add wave -noupdate -format Literal -label reg_entry_lo_mem -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_d_tlb/inst_reg_entry_lo/reg_mem
|
||||
add wave -noupdate -divider D-TLB-CAM
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clk
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clk_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/vld
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/tag_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/tag_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/hit_vld
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/debug
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/state_next
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe0
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe1
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe2
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe3
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe0_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe1_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe2_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/pipe3_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/busy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/vld_cam
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_result
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/cam_ram_addr_rd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_re
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_we
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_addr_wr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_addr_rd
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/track_ram_dout
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_data
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_addr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/clear_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_i_tlb/inst_cam_va/over_write
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {Cursor {24310024 ps} 0}
|
||||
configure wave -namecolwidth 188
|
||||
configure wave -valuecolwidth 154
|
||||
configure wave -justifyvalue left
|
||||
configure wave -signalnamewidth 1
|
||||
configure wave -snapdistance 10
|
||||
configure wave -datasetprefix 0
|
||||
configure wave -rowmargin 4
|
||||
configure wave -childrowmargin 2
|
||||
configure wave -gridoffset 0
|
||||
configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {24134231 ps} {24477503 ps}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,513 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
|
||||
ENTITY dcache IS
|
||||
Generic
|
||||
(
|
||||
cache_size : natural := 2048; -- 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_we : in STD_LOGIC;
|
||||
cpu_be : in unsigned(3 downto 0);
|
||||
cpu_addr : in word_t;
|
||||
cpu_din : in word_t;
|
||||
cpu_dout : out word_t;
|
||||
cpu_busy : out STD_LOGIC
|
||||
);
|
||||
END dcache;
|
||||
|
||||
ARCHITECTURE behavior OF dcache IS
|
||||
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
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 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);
|
||||
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);
|
||||
|
||||
return result;
|
||||
end to_dcache_entry;
|
||||
|
||||
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;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal request_addr : unsigned(addr_width-1 downto 0);
|
||||
signal fill_addr : unsigned(addr_width-1 downto 0);
|
||||
|
||||
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;
|
||||
|
||||
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 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);
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
cpu_hit_we <= cpu_we2 and cache_hit;
|
||||
|
||||
fill_address_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
process(CLK_I)
|
||||
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';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instant_raw_logic:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) 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;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
we_b => '0',
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
din_a => tag_ram_din,
|
||||
din_b => tag_ram_din,
|
||||
dout_a => tag_ram_dout_inv,
|
||||
dout_b => tag_ram_dout
|
||||
);
|
||||
|
||||
gen_data_ram:
|
||||
for i in 0 to 3 generate
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => '1',
|
||||
we_a => cpu_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(8*(i+1)-1 downto 8*i),
|
||||
dout_a => open,
|
||||
dout_b => cpu_data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_state_next:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
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 <= to_unsigned(flush_count, cache_index_width) 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_entry_out <= to_dcache_entry(tag_ram_dout);
|
||||
cache_entry_out_inv <= to_dcache_entry(tag_ram_dout_inv);
|
||||
|
||||
cpu_data_ram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (fill_cache_index & fill_word_index);
|
||||
ctrl_data_ram_addr <= fill_cache_index & fill_word_index;
|
||||
ctrl_data_ram_we <= (others => fill_count_en and ACK_I);
|
||||
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, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, cpu_we_reg, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
else
|
||||
if cache_req = '1' then
|
||||
if cache_hit = '0' and cpu_we_reg = '0' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= instant_raw;
|
||||
cache_ack <= not instant_raw;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= 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');
|
||||
sn <= rd_cache;
|
||||
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 =>
|
||||
fill_count_en <= '1';
|
||||
request_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.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)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -1,488 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY IEEE;
|
||||
USE IEEE.STD_LOGIC_1164.ALL;
|
||||
USE IEEE.NUMERIC_STD.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
|
||||
ENTITY icache IS
|
||||
Generic
|
||||
(
|
||||
cache_size : natural := 2048; -- 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
|
||||
);
|
||||
END icache;
|
||||
|
||||
ARCHITECTURE behavior OF icache IS
|
||||
|
||||
COMPONENT dpram_1w1r2c_ra
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT (
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : 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);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
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 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);
|
||||
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);
|
||||
|
||||
return result;
|
||||
end to_icache_entry;
|
||||
|
||||
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;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
type cache_state_t is (init, ready, invalidate, flush, mem_request, mem_access, mem_data, rd_cache, upd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_req : std_logic;
|
||||
signal cache_ack : std_logic;
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_miss : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal cache_miss_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 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 was_miss : std_logic;
|
||||
signal invalidate_all : std_logic;
|
||||
signal invalidate_ack : std_logic;
|
||||
signal invalidate_en : std_logic;
|
||||
signal invalidate_req : std_logic;
|
||||
|
||||
alias 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);
|
||||
|
||||
begin
|
||||
|
||||
ram_read_en <= cpu_en or was_miss;
|
||||
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);
|
||||
|
||||
|
||||
fill_address_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
end if;
|
||||
elsif cache_busy = '0' then
|
||||
fill_addr <= cpu_addr(addr_width-1 downto 2) & "00";
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
process(CLK_I)
|
||||
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
|
||||
cache_req <= '0';
|
||||
elsif cpu_en = '1' then
|
||||
if cache_busy = '0' then
|
||||
cache_req <= '1';
|
||||
end if;
|
||||
elsif cache_ack = '1' then
|
||||
cache_req <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' or ctrl.inv_all = '1' or ctrl.inv_at = '1' then
|
||||
invalidate_req <= '1';
|
||||
invalidate_all <= ctrl.inv_all or RST_I;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_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,
|
||||
din_b => tag_ram_data_wr,
|
||||
dout_a => tag_ram_data_rd_inv,
|
||||
dout_b => tag_ram_data_rd
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we,
|
||||
addr_a => data_ram_addr_wr,
|
||||
addr_b => data_ram_addr_rd,
|
||||
din_a => data_ram_data_wr,
|
||||
dout_b => data_ram_data_rd
|
||||
);
|
||||
|
||||
cache_state_next:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
MRDY_O <= fill_count_en;
|
||||
ADDR_O <= fill_tag & fill_cache_index & req_word_index & "00";
|
||||
|
||||
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_miss <= not (tag_match and cache_entry_out.valid);
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(tag_ram_data_rd_inv);
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_miss_inv <= not (tag_match_inv and cache_entry_out_inv.valid);
|
||||
|
||||
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 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;
|
||||
data_ram_we <= fill_count_en and ACK_I;
|
||||
|
||||
cache_state:
|
||||
process(s, cache_req, cache_miss, cache_miss_inv, flush_count_rdy, fill_count_rdy, request_count_rdy, fill_tag, SRDY_I, invalidate_req, invalidate_all)
|
||||
begin
|
||||
cache_busy <= cache_req;
|
||||
cache_ack <= '0';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= fill_tag;
|
||||
cache_entry_in.valid <= '0';
|
||||
sn <= s;
|
||||
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
sn <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif cache_req = '1' then
|
||||
if cache_miss = '1' then
|
||||
sn <= mem_request;
|
||||
CYC_O <= '1';
|
||||
else
|
||||
cache_busy <= '0';
|
||||
cache_ack <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when invalidate =>
|
||||
sn <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
sn <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_miss_inv = '0' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when mem_request =>
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
request_count_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
end if;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if ctrl.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)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -56,21 +56,24 @@ architecture Behavioral of alu is
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||
eq <= '1' when op1_in = op2_in else '0' after 1 ns;
|
||||
sa <= op1_in(op1_in'left);
|
||||
sb <= op2_in(op2_in'left);
|
||||
sr <= sum_res(sum_res'left);
|
||||
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0' after 2 ns;
|
||||
z <= '1' when op1_in = (data_width-1 downto 0 => '0') else '0';
|
||||
|
||||
flags.uvf <= (not ctrl.add) and ((sa and (not sb) and (not sr)) or ((not sa) and sb and sr));
|
||||
flags.ovf <= ctrl.add and ((sa and sb and (not sr)) or ((not sa) and (not sb) and sr));
|
||||
-- lts <= (not eq) and (((not c) and sa and sb) or (((not sr) and sa) or (sa and (not sb)) or (sr and (not sb))));
|
||||
lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
||||
|
||||
-- lts <= not eq and ((not c and sa) or (not sb and sa) or (not sb and sr));
|
||||
lts <= '1' when signed(op1_in) < signed(op2_in) else '0';
|
||||
|
||||
-- ltu <= (not eq) and (not c);
|
||||
ltu <= '1' when op1_in < op2_in else '0';
|
||||
|
||||
ltu <= (not eq) and (not c);
|
||||
flags.lts <= lts;
|
||||
flags.ltu <= ltu;
|
||||
flags.c <= c;
|
||||
flags.lts <= lts after 1 ns;
|
||||
flags.ltu <= ltu after 1 ns;
|
||||
flags.c <= c after 1 ns;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
proc_op_and:
|
||||
|
||||
@@ -45,7 +45,7 @@ architecture Behavioral of bcu is
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
flags.eq <= '1' when op1_in = op2_in else '0' after 3 ns;
|
||||
flags.eq <= '1' when ((op1_in xor op2_in) = (data_width-1 downto 0 => '0')) else '0' after 1 ns;
|
||||
flags.ltz <= op1_in(op1_in'left) after 1 ns;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
@@ -0,0 +1,399 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
entity biu is
|
||||
Generic
|
||||
(
|
||||
ICACHE_SIZE : natural := 2048; -- words
|
||||
ICACHE_LINE : natural := 8; -- words
|
||||
DCACHE_SIZE : natural := 2048; -- words
|
||||
DCACHE_LINE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4; -- words
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
clk : in STD_LOGIC;
|
||||
busy : out STD_LOGIC;
|
||||
|
||||
imem_err : out STD_LOGIC;
|
||||
dmem_err : out STD_LOGIC;
|
||||
|
||||
RST_I : in STD_LOGIC;
|
||||
CLK_I : in STD_LOGIC;
|
||||
ACK_I : in STD_LOGIC;
|
||||
SRDY_I : in STD_LOGIC;
|
||||
ADDR_O : out unsigned(31 downto 0);
|
||||
MDAT_I : in unsigned(31 downto 0);
|
||||
MDAT_O : out unsigned(31 downto 0);
|
||||
WE_O : out STD_LOGIC;
|
||||
SEL_O : out unsigned(3 downto 0);
|
||||
CYC_O : out STD_LOGIC;
|
||||
STB_O : out STD_LOGIC;
|
||||
MRDY_O : out STD_LOGIC;
|
||||
|
||||
ctrl_in : in biu_ctrl_in_t;
|
||||
ctrl_out : out biu_ctrl_out_t
|
||||
|
||||
);
|
||||
end biu;
|
||||
|
||||
architecture behavior of biu is
|
||||
|
||||
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;
|
||||
|
||||
type timeout_cnt_t is range 0 to 1E5-1;
|
||||
signal bus_timeout_cnt : timeout_cnt_t;
|
||||
signal bus_timeout : std_logic;
|
||||
|
||||
-------------------------------------------------
|
||||
signal RST : std_logic;
|
||||
signal CPU_CLK : std_logic;
|
||||
|
||||
-- busmaster signals
|
||||
signal bus_din : word_t;
|
||||
signal bus_din_rdy : std_logic;
|
||||
signal bus_din_we : std_logic;
|
||||
|
||||
signal bus_dout : word_t;
|
||||
signal bus_dout_vld : std_logic;
|
||||
signal bus_dout_re : 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;
|
||||
|
||||
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 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
|
||||
|
||||
CPU_CLK <= clk;
|
||||
RST <= RST_I;
|
||||
|
||||
biu_busy_state:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
busy <= '1';
|
||||
elsif (i_tlb_rdy and i_cache_rdy and d_cache_rdy and d_tlb_rdy) = '1' then
|
||||
busy <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_busmaster : entity work.busmaster_async
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => 32,
|
||||
FIFO_DEPTH => 16
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
|
||||
cmd_cycle_finished => bus_cyc_complete,
|
||||
cmd_cycle_en => bus_cmd_cycle_en,
|
||||
|
||||
cmd_rdy => bus_cmd_rdy,
|
||||
cmd_we => bus_cmd_we,
|
||||
cmd_in => bus_cmd,
|
||||
|
||||
din_rdy => bus_din_rdy,
|
||||
din_we => bus_din_we,
|
||||
din => bus_din,
|
||||
|
||||
dout => bus_dout,
|
||||
dout_vld => bus_dout_vld,
|
||||
dout_re => bus_dout_re,
|
||||
|
||||
-- JBUS Master signals
|
||||
RST_I => RST_I,
|
||||
CLK_I => CLK_I,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_i_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => i_tlb_rdy,
|
||||
|
||||
ctrl_in => ctrl_in.itlb_ctrl,
|
||||
ctrl_out => ctrl_out.itlb_ctrl,
|
||||
|
||||
query_in => ctrl_in.itlb_qry,
|
||||
query_out => ctrl_out.itlb_qry
|
||||
|
||||
);
|
||||
|
||||
inst_icache: entity work.icache
|
||||
GENERIC MAP
|
||||
(
|
||||
CACHE_SIZE => ICACHE_SIZE,
|
||||
LINE_SIZE => ICACHE_LINE
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
rdy => i_cache_rdy,
|
||||
|
||||
-- CPU control/data
|
||||
query_in => ctrl_in.icache_qry,
|
||||
query_out => ctrl_out.icache_qry,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => ctrl_in.icache,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_dout,
|
||||
bus_din_rdy => i_bus_din_rdy,
|
||||
bus_din_vld => bus_dout_vld,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => i_bus_cmd_rdy,
|
||||
bus_cmd_we => i_bus_cmd_we,
|
||||
bus_cmd_cycle_en => i_bus_cmd_cycle_en,
|
||||
bus_cmd_out => i_bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_d_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES,
|
||||
CACHE_KSEG1 => false,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1,
|
||||
USE_TLB => WITH_TLB
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CPU_CLK,
|
||||
ce => '1',
|
||||
|
||||
rdy => 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
|
||||
);
|
||||
|
||||
|
||||
bus_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, i_bus_cmd_cycle_en, d_bus_cmd_cycle_en, i_bus_cmd_we, i_bus_cmd, d_bus_cmd_we, d_bus_cmd, bus_cyc_complete, i_bus_din_rdy, d_bus_din_rdy, bus_cmd_rdy)
|
||||
begin
|
||||
|
||||
icache_bus_gnt <= '0';
|
||||
dcache_bus_gnt <= '0';
|
||||
|
||||
i_bus_cmd_rdy <= '0';
|
||||
d_bus_cmd_rdy <= '0';
|
||||
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
bus_cmd <= i_bus_cmd;
|
||||
bus_dout_re <= '0';
|
||||
bus_idle <= '0';
|
||||
|
||||
sn <= s;
|
||||
case s is
|
||||
when init =>
|
||||
sn <= ready;
|
||||
when ready =>
|
||||
bus_idle <= '1';
|
||||
if i_bus_cmd_cycle_en = '1' then
|
||||
sn <= icache_bus_access;
|
||||
elsif d_bus_cmd_cycle_en = '1' then
|
||||
sn <= dcache_bus_access;
|
||||
end if;
|
||||
when icache_bus_access =>
|
||||
icache_bus_gnt <= '1';
|
||||
i_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= i_bus_cmd_cycle_en;
|
||||
bus_cmd_we <= i_bus_cmd_we;
|
||||
bus_dout_re <= i_bus_din_rdy;
|
||||
if i_bus_cmd_cycle_en = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when dcache_bus_access =>
|
||||
dcache_bus_gnt <= '1';
|
||||
d_bus_cmd_rdy <= bus_cmd_rdy;
|
||||
bus_cmd_cycle_en <= d_bus_cmd_cycle_en;
|
||||
bus_cmd <= d_bus_cmd;
|
||||
bus_cmd_we <= d_bus_cmd_we;
|
||||
bus_dout_re <= d_bus_din_rdy;
|
||||
if d_bus_cmd_cycle_en = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
else
|
||||
bus_timeout <= '1';
|
||||
end if;
|
||||
else
|
||||
bus_timeout_cnt <= timeout_cnt_t'high;
|
||||
bus_timeout <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if RST_I = '1' then
|
||||
imem_err <= '0';
|
||||
dmem_err <= '0';
|
||||
elsif bus_timeout = '1' then
|
||||
imem_err <= icache_bus_gnt;
|
||||
dmem_err <= dcache_bus_gnt;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
end behavior;
|
||||
@@ -1,552 +0,0 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: JIPS top file
|
||||
--
|
||||
-- Copyright (C) 2008 J. Ahrensfeld
|
||||
--
|
||||
-- This program is free software: you can redistribute it and/or modify
|
||||
-- it under the terms of the GNU General Public License as published by
|
||||
-- the Free Software Foundation, either version 3 of the License, or
|
||||
-- (at your option) any later version.
|
||||
--
|
||||
-- This program is distributed in the hope that it will be useful,
|
||||
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
-- GNU General Public License for more details.
|
||||
--
|
||||
-- You should have received a copy of the GNU General Public License
|
||||
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
|
||||
entity biu is
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 2048; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 2048; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
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);
|
||||
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
|
||||
);
|
||||
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 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;
|
||||
|
||||
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 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;
|
||||
|
||||
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 read_cycle : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
read_cyc_register:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_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);
|
||||
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 after 4.5 ns;
|
||||
busy <= CYC_O_dmem_rd or dcache_busy or (write_fifo_full);
|
||||
cpu_dmem_rdy <= not busy after 4.5 ns;
|
||||
|
||||
inst_icache : icache
|
||||
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
|
||||
)
|
||||
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
|
||||
);
|
||||
|
||||
SRDY_I_dcache <= bout_rdy and dcache_mem_gnt;
|
||||
|
||||
dcached <= '1' when cpu_dmem_addr(31 downto 29) /= "101" else '0';
|
||||
cpu_dmem_din <= dcache_dout when uncached_access = '0' else DAT_I_dmem_rd;
|
||||
dcache_en <= dcached and cpu_dmem_en and dcache_en2; -- or write_fifo_full);
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bin_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 32,
|
||||
do_last_read_update => true
|
||||
)
|
||||
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
|
||||
);
|
||||
|
||||
bin_fifo_din <= DAT_I;
|
||||
DAT <= bin_fifo_dout;
|
||||
ACK <= not bin_fifo_empty;
|
||||
bin_fifo_we <= ACK_I;
|
||||
bin_fifo_re <= dmem_mem_rd_gnt or MRDY_O_icache or MRDY_O_dcache;
|
||||
|
||||
-- Instantiate synchronous FIFO
|
||||
inst_bout_fifo: entity work.fifo_async
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 69,
|
||||
do_last_read_update => false
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk_w => cpu_clk,
|
||||
clk_r => CLK_I,
|
||||
we => bout_fifo_we,
|
||||
re => bout_fifo_re,
|
||||
fifo_full => bout_fifo_full,
|
||||
fifo_empty => bout_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => bout_fifo_din,
|
||||
data_r => bout_fifo_dout
|
||||
);
|
||||
bout_rdy <= not bout_fifo_full;
|
||||
bout_fifo_re <= SRDY_I and not bin_fifo_full;
|
||||
|
||||
bout_fifo_we <= STB_O_dmem_wr or STB_O_dmem_rd or STB_O_dcache or STB_O_icache;
|
||||
|
||||
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
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => 4,
|
||||
data_width => 68,
|
||||
do_last_read_update => true
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST_I,
|
||||
clk => cpu_clk,
|
||||
we => write_fifo_we,
|
||||
re => write_fifo_re,
|
||||
fifo_full => write_fifo_full,
|
||||
fifo_empty => write_fifo_empty,
|
||||
fifo_afull => open,
|
||||
fifo_aempty => open,
|
||||
data_w => write_fifo_din,
|
||||
data_r => write_fifo_dout
|
||||
);
|
||||
|
||||
CYC_O_dmem_wr <= not write_fifo_empty;
|
||||
DAT_O_dmem_wr <= write_fifo_data_out;
|
||||
ADDR_O_dmem_wr <= write_fifo_addr_out;
|
||||
SEL_O_dmem_wr <= write_fifo_sel_out;
|
||||
|
||||
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)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
s <= init;
|
||||
else
|
||||
s <= sn;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_state:
|
||||
process(s, CYC_O_icache, CYC_O_dcache, CYC_O_dmem_wr, CYC_O_dmem_rd, bout_rdy, ACK)
|
||||
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';
|
||||
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
|
||||
sn <= icache_bus_access;
|
||||
elsif CYC_O_dcache = '1' then
|
||||
sn <= dcache_bus_access;
|
||||
end if;
|
||||
when icache_bus_access =>
|
||||
icache_mem_gnt <= '1';
|
||||
if CYC_O_icache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when dcache_bus_access =>
|
||||
dcache_mem_gnt <= '1';
|
||||
if CYC_O_dcache = '0' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when write_bus =>
|
||||
dmem_mem_wr_gnt <= '1';
|
||||
if CYC_O_dmem_wr = '1' then
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_wr <= '1';
|
||||
end if;
|
||||
else
|
||||
sn <= ready;
|
||||
end if;
|
||||
when read_bus =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if bout_rdy = '1' then
|
||||
STB_O_dmem_rd <= '1';
|
||||
sn <= read_finish;
|
||||
end if;
|
||||
when read_finish =>
|
||||
dmem_mem_rd_gnt <= '1';
|
||||
if ACK = '1' then
|
||||
sn <= ready;
|
||||
end if;
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
bus_timeout_counter:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if bus_idle = '0' then
|
||||
if bus_timeout_cnt /= 0 then
|
||||
bus_timeout_cnt <= bus_timeout_cnt - 1;
|
||||
else
|
||||
bus_timeout <= '1';
|
||||
end if;
|
||||
else
|
||||
bus_timeout_cnt <= timeout_cnt_t'high;
|
||||
bus_timeout <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_err:
|
||||
process(cpu_clk)
|
||||
begin
|
||||
if rising_edge(cpu_clk) then
|
||||
if RST_I = '1' then
|
||||
cpu_imem_err <= '0';
|
||||
cpu_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;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------------------------
|
||||
|
||||
end behavior;
|
||||
@@ -1,3 +1,26 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
|
||||
+594
-277
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,777 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY dcache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8; -- words
|
||||
WRITE_FIFO_SIZE : natural := 4
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in dcache_query_in_t;
|
||||
query_out : out dcache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
bus_dout : out word_t;
|
||||
bus_dout_vld : out std_logic;
|
||||
bus_dout_rdy : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
|
||||
);
|
||||
END dcache;
|
||||
|
||||
ARCHITECTURE behavior OF dcache IS
|
||||
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES)+1;
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type dcache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
idx : unsigned(lg2(TLB_NUM_ENTRIES) downto 0);
|
||||
end record;
|
||||
|
||||
function to_dcache_entry(x : tag_ram_data_t) return dcache_entry_t is
|
||||
variable result : dcache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.idx := x(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1);
|
||||
|
||||
return result;
|
||||
end to_dcache_entry;
|
||||
|
||||
function to_tag_ram_data(x : dcache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width+1 downto tag_width+1) := x.idx;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
|
||||
|
||||
function to_cache_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(cache_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(cache_index_width+word_index_width+1 downto word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_cache_index;
|
||||
|
||||
function to_tag(x : word_t) return unsigned is
|
||||
variable result : unsigned(tag_width-1 downto 0);
|
||||
begin
|
||||
result := x(tag_width+cache_index_width+word_index_width+1 downto cache_index_width+word_index_width+2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_tag;
|
||||
|
||||
|
||||
type cache_busy_state_t is (init, ready, busy);
|
||||
signal cache_busy_state, cache_busy_state_next : cache_busy_state_t;
|
||||
|
||||
type cache_ctrl_state_t is (init, ready, invalidate, invalidate_post, flush, bus_request, mem_read, mem_read_single, mem_read_data, mem_read_data_single, rd_cache, upd_cache, wait_write_thru);
|
||||
signal cache_ctrl_state, cache_ctrl_state_next : cache_ctrl_state_t;
|
||||
|
||||
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
|
||||
|
||||
-- Print info
|
||||
assert false report "addr_width = " & natural'image(addr_width) & "." severity note;
|
||||
assert false report "tag_width = " & natural'image(tag_width) & "." severity note;
|
||||
assert false report "word_index_width = " & natural'image(word_index_width) & "." severity note;
|
||||
assert false report "cache_index_width = " & natural'image(cache_index_width) & "." severity note;
|
||||
|
||||
cache_index_inv <= ctrl_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;
|
||||
|
||||
request_pa <= request_va;
|
||||
|
||||
write_hit <= cache_req_wr and cache_hit; -- and not tlb_query_in.exc;
|
||||
|
||||
debug.req_strobe <= req_strobe;
|
||||
debug.req_read <= cache_req_rd;
|
||||
debug.req_write <= cache_req_wr;
|
||||
debug.req_va <= request_va;
|
||||
debug.req_pa <= request_pa;
|
||||
debug.din_reg <= din_reg;
|
||||
debug.dout_reg <= cache_dout;
|
||||
debug.ready <= cache_rdy;
|
||||
|
||||
-------------------------------------------------
|
||||
-- ctrl
|
||||
-------------------------------------------------
|
||||
req_strobe <= cache_rdy and query_in.en;
|
||||
|
||||
request_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_req_rd <= '0';
|
||||
cache_req_wr <= '0';
|
||||
elsif cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en and not query_in.we;
|
||||
cache_req_wr <= query_in.en and query_in.we;
|
||||
cache_req <= query_in.en;
|
||||
if query_in.we = '1' then
|
||||
hit_cache_index <= to_cache_index(query_in.addr);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
din_reg <= query_in.data;
|
||||
be_reg <= query_in.be;
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
instant_raw_logic:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
instant_raw <= '0';
|
||||
if to_word_index(query_in.addr) = fill_word_index and to_cache_index(query_in.addr) = hit_cache_index then
|
||||
instant_raw <= write_hit and query_in.en and not query_in.we;
|
||||
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
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_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_din,
|
||||
din_b => tag_ram_din,
|
||||
dout_a => tag_ram_dout_inv,
|
||||
dout_b => tag_ram_dout
|
||||
);
|
||||
|
||||
gen_data_ram:
|
||||
for i in 0 to 3 generate
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_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 => 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 => data_ram_dout(8*(i+1)-1 downto 8*i)
|
||||
);
|
||||
end generate;
|
||||
|
||||
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
begin
|
||||
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_in.inv_all or rst;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
cache_rdy <= read_rdy and not instant_raw and write_rdy;
|
||||
write_rdy <= not (write_fifo_full and cache_req_wr);
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else to_mips_01(data_ram_dout);
|
||||
query_out.data <= cache_dout;
|
||||
|
||||
-- tag_match <= '1' when to_tag(request_pa) = cache_entry_out.tag else '0';
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
tag_match_inv <= '1' when tag_reg_inv = cache_entry_out_inv.tag else '0';
|
||||
cache_hit_inv <= tag_match_inv and cache_entry_out_inv.valid;
|
||||
|
||||
tag_ram_din <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when invalidate_en = '1' else to_cache_index(request_va);
|
||||
tag_ram_addr_rd <= to_cache_index(query_in.addr) when (was_miss = '0' and instant_raw = '0') else to_cache_index(request_va);
|
||||
|
||||
cache_entry_out <= to_dcache_entry(to_mips_01(tag_ram_dout));
|
||||
cache_entry_out_inv <= to_dcache_entry(to_mips_01(tag_ram_dout_inv));
|
||||
|
||||
ram_read_en <= query_in.en or was_miss or fill_count_en;
|
||||
data_ram_addr <= (to_cache_index(query_in.addr) & to_word_index(query_in.addr)) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (to_cache_index(request_va) & fill_word_index);
|
||||
ctrl_data_ram_addr <= to_cache_index(request_va) & fill_word_index;
|
||||
ctrl_data_ram_we <= (others => ram_write_en and bus_din_vld);
|
||||
data_ram_we <= be_reg when (write_hit = '1') else (others => '0');
|
||||
|
||||
write_through_en <= cache_rdy and cache_req_wr; -- and tlb_query_in.hit and not tlb_query_in.flags.D;
|
||||
|
||||
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
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
read_write_buffer <= '0';
|
||||
|
||||
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 =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' or write_data_avail = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
elsif write_through_en = '1' then
|
||||
cache_ctrl_state_next <= wait_write_thru;
|
||||
-- bus_cmd_cycle_en <= '1';
|
||||
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 wait_write_thru =>
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
if write_data_avail = '1' then
|
||||
read_write_buffer <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
else
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
end if;
|
||||
else
|
||||
cache_ctrl_state_next <= ready;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
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';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -0,0 +1,663 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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_util_pkg.all;
|
||||
use work.mips_types.all;
|
||||
use work.busmaster_types.all;
|
||||
|
||||
ENTITY icache IS
|
||||
Generic
|
||||
(
|
||||
CACHE_SIZE : natural := 1024; -- words
|
||||
LINE_SIZE : natural := 8 -- words
|
||||
);
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rdy : out STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
query_in : in icache_query_in_t;
|
||||
query_out : out icache_query_out_t;
|
||||
|
||||
-- Cache control
|
||||
ctrl_in : in cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
bus_din : in word_t;
|
||||
bus_din_rdy : out std_logic;
|
||||
bus_din_vld : in std_logic;
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy : in std_logic;
|
||||
bus_cmd_we : out std_logic;
|
||||
bus_cmd_cycle_en : out std_logic;
|
||||
bus_cmd_out : out bm_cmd_t;
|
||||
bus_cyc_complete : in std_logic
|
||||
);
|
||||
END icache;
|
||||
|
||||
ARCHITECTURE behavior OF icache IS
|
||||
|
||||
COMPONENT dpram_1w1r2c_ra
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT (
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : 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);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
COMPONENT dpram_2w2r2c_ra is
|
||||
GENERIC
|
||||
(
|
||||
addr_width : integer := 3;
|
||||
data_width : integer := 8
|
||||
);
|
||||
PORT
|
||||
(
|
||||
clk_a : in STD_LOGIC;
|
||||
clk_b : in STD_LOGIC;
|
||||
en_a : in STD_LOGIC;
|
||||
en_b : in STD_LOGIC;
|
||||
we_a : in STD_LOGIC;
|
||||
we_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);
|
||||
din_b : in unsigned (data_width-1 downto 0);
|
||||
dout_a : out unsigned (data_width-1 downto 0);
|
||||
dout_b : out unsigned (data_width-1 downto 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
constant addr_width : natural := 32;
|
||||
constant word_index_width : natural := lg2(LINE_SIZE);
|
||||
constant cache_index_width : natural := lg2(CACHE_SIZE) - word_index_width;
|
||||
constant tag_width : natural := addr_width - lg2(CACHE_SIZE) - 2;
|
||||
constant tag_ram_data_width : natural := 1 + tag_width + lg2(TLB_NUM_ENTRIES);
|
||||
constant tag_ram_addr_width : natural := cache_index_width;
|
||||
|
||||
subtype tag_ram_data_t is unsigned (tag_ram_data_width-1 downto 0);
|
||||
|
||||
type icache_entry_t is record
|
||||
valid : std_logic;
|
||||
tag : unsigned(tag_width-1 downto 0);
|
||||
tlb_idx : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
end record;
|
||||
|
||||
function to_icache_entry(x : tag_ram_data_t) return icache_entry_t is
|
||||
variable result : icache_entry_t;
|
||||
begin
|
||||
result.valid := x(0);
|
||||
result.tag := x(tag_width downto 1);
|
||||
result.tlb_idx := x(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1);
|
||||
|
||||
return result;
|
||||
end to_icache_entry;
|
||||
|
||||
function to_tag_ram_data(x : icache_entry_t) return tag_ram_data_t is
|
||||
variable result : tag_ram_data_t;
|
||||
begin
|
||||
result(0) := x.valid;
|
||||
result(tag_width downto 1) := x.tag;
|
||||
result(lg2(TLB_NUM_ENTRIES)+tag_width downto tag_width+1) := x.tlb_idx;
|
||||
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
function to_word_index(x : word_t) return unsigned is
|
||||
variable result : unsigned(word_index_width-1 downto 0);
|
||||
begin
|
||||
result := x(word_index_width+1 downto 2);
|
||||
|
||||
return result;
|
||||
|
||||
end to_word_index;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
type debug_t is record
|
||||
ready : std_logic;
|
||||
req_strobe : std_logic;
|
||||
req_read : std_logic;
|
||||
req_va : word_t;
|
||||
req_pa : word_t;
|
||||
dout_reg : word_t;
|
||||
end record;
|
||||
|
||||
signal debug : debug_t;
|
||||
|
||||
signal req_strobe : std_logic;
|
||||
signal cache_req_rd : std_logic;
|
||||
signal read_rdy : std_logic;
|
||||
signal cache_rdy : std_logic;
|
||||
signal cache_hit : std_logic;
|
||||
signal request_va : word_t;
|
||||
signal request_pa : word_t;
|
||||
signal request_nc : std_logic;
|
||||
|
||||
signal tag_match : std_logic;
|
||||
signal cache_hit_inv : std_logic;
|
||||
signal tag_match_inv : std_logic;
|
||||
|
||||
signal 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 : icache_entry_t;
|
||||
signal cache_entry_out : icache_entry_t;
|
||||
signal cache_entry_out_inv : icache_entry_t;
|
||||
signal data_ram_addr_rd : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_rd : word_t;
|
||||
signal data_ram_addr_wr : unsigned(lg2(CACHE_SIZE)-1 downto 0);
|
||||
signal data_ram_data_wr : word_t;
|
||||
signal data_ram_we : std_logic;
|
||||
signal single_read_reg : word_t;
|
||||
signal cache_dout : word_t;
|
||||
|
||||
signal 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
|
||||
|
||||
-- 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';
|
||||
|
||||
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) then
|
||||
if cache_rdy = '1' then
|
||||
cache_req_rd <= query_in.en;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-------------------------------------------------
|
||||
fill_address_register:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
request_va <= (others => '0');
|
||||
request_nc <= '0';
|
||||
elsif req_strobe = '1' then
|
||||
request_va <= query_in.addr;
|
||||
request_nc <= query_in.nc;
|
||||
fill_word_index <= to_word_index(query_in.addr);
|
||||
elsif bus_din_vld = '1' and fill_count_en = '1' then
|
||||
fill_word_index <= fill_word_index + 1;
|
||||
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;
|
||||
|
||||
cache_invalidate_request:
|
||||
process(clk)
|
||||
begin
|
||||
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_in.inv_all or rst;
|
||||
tag_reg_inv <= tag_inv;
|
||||
elsif invalidate_ack = '1' then
|
||||
invalidate_req <= '0';
|
||||
invalidate_all <= '0';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_2w2r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_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,
|
||||
din_b => tag_ram_data_wr,
|
||||
dout_a => tag_ram_data_rd_inv,
|
||||
dout_b => tag_ram_data_rd
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r2c_ra
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => lg2(CACHE_SIZE),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
clk_a => clk,
|
||||
clk_b => clk,
|
||||
en_a => '1',
|
||||
en_b => ram_read_en,
|
||||
we_a => data_ram_we,
|
||||
addr_a => data_ram_addr_wr,
|
||||
addr_b => data_ram_addr_rd,
|
||||
din_a => data_ram_data_wr,
|
||||
dout_b => data_ram_data_rd
|
||||
);
|
||||
|
||||
cache_state_next:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if rst = '1' then
|
||||
cache_ctrl_state <= init;
|
||||
cache_busy_state <= init;
|
||||
else
|
||||
cache_ctrl_state <= cache_ctrl_state_next;
|
||||
cache_busy_state <= cache_busy_state_next;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
bus_din_rdy <= fill_count_en or single_read_en;
|
||||
bus_cmd_out.addr <= to_tag(request_pa) & to_cache_index(request_pa) & req_word_index & "00";
|
||||
bus_cmd_out.rw <= '0';
|
||||
bus_cmd_out.sel <= (others => '1');
|
||||
|
||||
cache_rdy <= read_rdy;
|
||||
query_out.rdy <= cache_rdy;
|
||||
rdy <= cache_rdy;
|
||||
|
||||
cache_dout <= single_read_reg when single_read_en = '1' else data_ram_data_rd;
|
||||
query_out.data <= cache_dout;
|
||||
|
||||
cache_entry_out <= to_icache_entry(to_mips_01(tag_ram_data_rd));
|
||||
tag_match <= '1' when ((to_tag(request_pa) xor cache_entry_out.tag) = (tag_width-1 downto 0 => '0')) else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
|
||||
cache_entry_out_inv <= to_icache_entry(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;
|
||||
|
||||
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
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_count_rst <= '0';
|
||||
invalidate_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
ram_write_en <= '0';
|
||||
bus_cmd_cycle_en <= '0';
|
||||
bus_cmd_we <= '0';
|
||||
was_miss <= '0';
|
||||
invalidate_ack <= '0';
|
||||
mem_fetch_ack <= '0';
|
||||
|
||||
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 =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when ready =>
|
||||
if invalidate_req = '1' then
|
||||
cache_ctrl_state_next <= invalidate;
|
||||
invalidate_en <= '1';
|
||||
elsif mem_fetch_req = '1' then
|
||||
cache_ctrl_state_next <= bus_request;
|
||||
bus_cmd_cycle_en <= '1';
|
||||
end if;
|
||||
|
||||
when invalidate =>
|
||||
cache_ctrl_state_next <= rd_cache;
|
||||
invalidate_en <= '1';
|
||||
invalidate_ack <= '1';
|
||||
if invalidate_all = '1' then
|
||||
cache_ctrl_state_next <= flush;
|
||||
flush_count_rst <= '1';
|
||||
elsif cache_hit_inv = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
invalidate_en <= '1';
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
cache_ctrl_state_next <= invalidate_post;
|
||||
end if;
|
||||
|
||||
when invalidate_post =>
|
||||
was_miss <= '1';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when bus_request =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
if bus_cmd_rdy = '1' then
|
||||
cache_ctrl_state_next <= mem_read;
|
||||
if request_nc = '1' then
|
||||
cache_ctrl_state_next <= mem_read_single;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
when mem_read =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
request_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
bus_cmd_we <= '0';
|
||||
cache_ctrl_state_next <= mem_read_data;
|
||||
end if;
|
||||
|
||||
when mem_read_single =>
|
||||
mem_fetch_ack <= '1';
|
||||
bus_cmd_cycle_en <= '1';
|
||||
bus_cmd_we <= '1';
|
||||
cache_ctrl_state_next <= mem_read_data_single;
|
||||
|
||||
when mem_read_data =>
|
||||
bus_cmd_cycle_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
ram_write_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
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';
|
||||
cache_ctrl_state_next <= ready;
|
||||
|
||||
when others =>
|
||||
cache_ctrl_state_next <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if ctrl_in.inv_at = '1' then
|
||||
flush_count <= to_integer(cache_index_inv);
|
||||
elsif flush_count_rst = '1' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
elsif flush_count_en = '1' then
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_cmd_rdy = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if bus_din_vld = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
end behavior;
|
||||
@@ -27,32 +27,30 @@ use IEEE.numeric_std.ALL;
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_instr.all;
|
||||
use work.mips_util_pkg.all;
|
||||
|
||||
entity pipeline is
|
||||
Port
|
||||
(
|
||||
rst : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
ce : in STD_LOGIC;
|
||||
imem_err : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_err : in STD_LOGIC;
|
||||
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;
|
||||
@@ -161,18 +159,14 @@ architecture Behavioral of pipeline is
|
||||
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 stage_rst : unsigned(3 downto 0);
|
||||
signal pipe_rst : STD_LOGIC;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
signal pc : pc_t;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
begin
|
||||
|
||||
@@ -181,38 +175,49 @@ begin
|
||||
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 <= '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 <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or c0_ctrl_in.exc_commit);
|
||||
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) after 1 ns;
|
||||
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) after 1ns;
|
||||
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
|
||||
@@ -236,7 +241,6 @@ inst_muldiv: muldiv
|
||||
--------------------------------------------------------------------------
|
||||
-- IF stage
|
||||
--------------------------------------------------------------------------
|
||||
imem_addr <= pc.curr;
|
||||
|
||||
pipe_rst <= stage_rst(0);
|
||||
|
||||
@@ -252,80 +256,168 @@ proc_stage_reset:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_stage_pc:
|
||||
process(pc)
|
||||
--------------------------------------------------------------------------
|
||||
-- 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
|
||||
if pc.branch_take = '1' then
|
||||
pc.curr <= pc.pc_branch after 2 ns;
|
||||
else
|
||||
pc.curr <= pc.nxt after 2 ns;
|
||||
pc.branch_take <= '0';
|
||||
if ID_stage.ctrl.branch = '1' then
|
||||
|
||||
case ID_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor ID_stage.bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= ID_stage.ctrl.bc_not xor (ID_stage.bcu_flags.eq or ID_stage.bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
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_pc_branch:
|
||||
process(clk_1)
|
||||
proc_stage_branch_not:
|
||||
process(EX_stage)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if sdu.ID_stall = '0' then
|
||||
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_alt:
|
||||
process(clk_2)
|
||||
begin
|
||||
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_branch_ce:
|
||||
proc_stage_pc_curr_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if pipe_rst = '1' then
|
||||
branch_ce <= '1';
|
||||
else
|
||||
branch_ce <= c0_ctrl_in.exc_pending;
|
||||
if sdu.ID_stall = '0' and c0_ctrl_in.exc_inject = '0' then
|
||||
branch_ce <= '1';
|
||||
end if;
|
||||
end if;
|
||||
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_next:
|
||||
proc_stage_pc_revert_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) 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;
|
||||
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 if;
|
||||
end process;
|
||||
|
||||
proc_stage_branch:
|
||||
process(clk_2)
|
||||
proc_stage_branch_not_taken_alt:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_2) and branch_ce = '1' then
|
||||
pc.branch_take <= '0';
|
||||
if EX_stage.ctrl.branch = '1' then
|
||||
|
||||
case EX_stage.ctrl.bc_src is
|
||||
|
||||
when bc_eq_ne =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.eq;
|
||||
|
||||
when bc_lez_gtz =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor (bcu_flags.eq or bcu_flags.ltz);
|
||||
|
||||
when bc_ltz_gez =>
|
||||
pc.branch_take <= EX_stage.ctrl.bc_not xor bcu_flags.ltz;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
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;
|
||||
@@ -333,7 +425,7 @@ proc_stage_branch:
|
||||
--------------------------------------------------------------------------
|
||||
-- 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_branch:
|
||||
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,12 +470,12 @@ 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 after 1 ns;
|
||||
hdu.alu_fwd_a_mem <= raw_a_MEM after 1 ns;
|
||||
@@ -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' after 2 ns;
|
||||
else
|
||||
ID_stage.reg_a(i) <= '0' after 2 ns;
|
||||
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' after 2 ns;
|
||||
else
|
||||
ID_stage.reg_b(i) <= '0' after 2 ns;
|
||||
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 after 2 ns;
|
||||
ID_stage.imm <= data after 1 ns;
|
||||
|
||||
end process;
|
||||
|
||||
@@ -463,10 +555,10 @@ inst_reg_dual: reg_dual
|
||||
PORT MAP
|
||||
(
|
||||
clk_w => clk_1,
|
||||
we => WB_stage.wreg_we,
|
||||
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,6 +571,7 @@ inst_reg_dual: reg_dual
|
||||
EX_stage.reg_a_rptr <= extract_rs(EX_stage.IR);
|
||||
EX_stage.reg_b_rptr <= extract_rt(EX_stage.IR);
|
||||
EX_stage.result <= alu_result when EX_stage.ctrl.mul_access = '0' else mul_result;
|
||||
EX_stage.dtlb_qry <= dtlb_qry_in;
|
||||
|
||||
proc_stage_ID_EX_1:
|
||||
process(clk_1)
|
||||
@@ -493,18 +586,19 @@ proc_stage_ID_EX_1:
|
||||
EX_stage.pcn <= (others => '0');
|
||||
EX_stage.events_in <= events_clr;
|
||||
elsif sdu.EX_stall = '0' then
|
||||
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.nop <= sdu.EX_nop;
|
||||
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';
|
||||
@@ -522,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
|
||||
@@ -536,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_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if pipe_rst = '1' then
|
||||
dmem_en <= '0';
|
||||
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,25 +673,19 @@ proc_stage_DMEM_ADDR:
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
if sdu.EX_stall = '0' then
|
||||
EX_stage.va <= vaddr;
|
||||
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) after 1 ns;
|
||||
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) after 1ns;
|
||||
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);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
@@ -608,9 +703,9 @@ proc_wptr_mux:
|
||||
reg_wptr := extract_rt(EX_stage.IR);
|
||||
end case;
|
||||
|
||||
EX_stage.wreg_we <= EX_stage.reg_write after 1 ns;
|
||||
EX_stage.reg_we <= EX_stage.reg_write after 1 ns;
|
||||
if reg_wptr = "00000" then
|
||||
EX_stage.wreg_we <= '0' after 1 ns;
|
||||
EX_stage.reg_we <= '0' after 1 ns;
|
||||
end if;
|
||||
|
||||
EX_stage.reg_wptr <= reg_wptr after 1 ns;
|
||||
@@ -620,7 +715,7 @@ proc_wptr_mux:
|
||||
|
||||
when wptr_src_const =>
|
||||
EX_stage.reg_wptr <= to_unsigned(31, reg_ptr_t'length) after 1 ns;
|
||||
EX_stage.wreg_we <= '1' after 1 ns;
|
||||
EX_stage.reg_we <= '1' after 1 ns;
|
||||
|
||||
when others => null;
|
||||
end case;
|
||||
@@ -628,14 +723,6 @@ proc_wptr_mux:
|
||||
end process;
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_bcu_op:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) and sdu.EX_stall = '0' then
|
||||
bcu_op_a <= ID_stage.reg_a;
|
||||
bcu_op_b <= ID_stage.reg_b;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
EX_stage.alu_op1 <= EX_stage.reg_a;
|
||||
|
||||
@@ -685,9 +772,9 @@ shifter_sa_mux:
|
||||
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 2 ns;
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data_inv after 1 ns;
|
||||
else
|
||||
EX_stage.shift_ctrl.shamt_rnd <= data after 2 ns;
|
||||
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;
|
||||
@@ -724,18 +811,6 @@ 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
|
||||
--------------------------------------------------------------------------
|
||||
@@ -745,59 +820,61 @@ proc_stage_MEM_n:
|
||||
if rising_edge(clk_1) then
|
||||
if stage_rst(2) = '1' then
|
||||
MEM_stage.op <= op_nop;
|
||||
MEM_stage.wreg_we <= '0';
|
||||
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.events_in <= EX_stage.events;
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
MEM_stage.reg_a <= EX_stage.reg_a;
|
||||
MEM_stage.reg_b <= EX_stage.reg_b;
|
||||
MEM_stage.result_in <= EX_stage.result;
|
||||
MEM_stage.op <= EX_stage.op;
|
||||
MEM_stage.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;
|
||||
MEM_stage.pa_off <= EX_stage.pa_off;
|
||||
MEM_stage.reg_wptr <= EX_stage.reg_wptr;
|
||||
MEM_stage.nop <= sdu.MEM_nop;
|
||||
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;
|
||||
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(dmem_din, MEM_stage.pa_off, MEM_stage.ctrl.shift_offset, MEM_stage.ctrl.shift_byp);
|
||||
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
|
||||
@@ -813,16 +890,16 @@ proc_stage_MEM_mux:
|
||||
data(31 downto 24) := temp2(31 downto 24);
|
||||
end if;
|
||||
end if;
|
||||
MEM_stage.data <= data after 1 ns;
|
||||
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);
|
||||
@@ -832,33 +909,49 @@ proc_stage_MEM_except:
|
||||
--------------------------------------------------------------------------
|
||||
proc_stage_WB_p:
|
||||
process(clk_1)
|
||||
variable branch_delay : std_logic;
|
||||
|
||||
begin
|
||||
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.epc <= (others => '0');
|
||||
WB_stage.events <= events_clr;
|
||||
elsif sdu.WB_stall = '0' then
|
||||
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.exc <= '0';
|
||||
elsif sdu.WB_stall = '0' then
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
WB_stage.reg_a <= MEM_stage.reg_a;
|
||||
WB_stage.reg_b <= MEM_stage.reg_b;
|
||||
WB_stage.result <= MEM_stage.result;
|
||||
WB_stage.op <= MEM_stage.op;
|
||||
WB_stage.epc <= MEM_stage.epc;
|
||||
branch_delay := MEM_stage.ctrl.branch or MEM_stage.ctrl.jump or MEM_stage.ctrl.jump_long; -- Todo: works
|
||||
WB_stage.bd <= branch_delay;
|
||||
WB_stage.exc_last <= WB_stage.exc;
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
WB_stage.reg_we <= MEM_stage.reg_we;
|
||||
WB_stage.reg_wptr <= MEM_stage.reg_wptr;
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
if sdu.stall_all = '0' then
|
||||
WB_stage.exc <= MEM_stage.exc;
|
||||
if MEM_stage.exc = '1' then
|
||||
WB_stage.events <= MEM_stage.events;
|
||||
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;
|
||||
WB_stage.nop <= sdu.WB_nop;
|
||||
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;
|
||||
|
||||
@@ -1,3 +1,26 @@
|
||||
--------------------------------------------------------------------------
|
||||
-- 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;
|
||||
@@ -48,16 +71,16 @@ ARCHITECTURE behavior OF tlb IS
|
||||
signal hit_umuc : STD_LOGIC;
|
||||
signal entry_lo_res : tlb_entry_lo_t;
|
||||
signal qry_res : tlb_query_out_t;
|
||||
signal stat_res : tlb_status_t;
|
||||
|
||||
signal pa : word_t;
|
||||
signal hit : STD_LOGIC;
|
||||
signal valid : 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);
|
||||
@@ -151,22 +174,16 @@ begin
|
||||
clk_rd <= clk;
|
||||
rdy <= cam_rdy;
|
||||
|
||||
stat_res.exc_vld <= valid;
|
||||
stat_res.exc_miss <= not hit;
|
||||
stat_res.exc_dirty <= hit and qry_res.flags.D and query_in.write;
|
||||
stat_res.write <= query_in.write;
|
||||
|
||||
qry_res.paddr <= pa;
|
||||
qry_res.hit <= hit;
|
||||
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.exc <= stat_res.exc_miss or stat_res.exc_dirty;
|
||||
qry_res.vld <= valid;
|
||||
qry_res.idx <= (hit_umc or hit_umuc) & reg_qry_entry_lo_addr;
|
||||
qry_res.paddr <= pa;
|
||||
|
||||
query_out <= qry_res;
|
||||
ctrl_out.stat <= stat_res;
|
||||
|
||||
pa <= entry_lo_res.PFN & vaddr_reg(lg2(TLB_PAGE_SIZE)-1 downto 0);
|
||||
|
||||
@@ -180,6 +197,25 @@ begin
|
||||
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
|
||||
(
|
||||
@@ -243,34 +279,9 @@ inst_cam_va: entity work.cam
|
||||
|
||||
);
|
||||
|
||||
proc_entry_lo_umc:
|
||||
process(clk)
|
||||
variable index : integer;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
hit_umc <= '0';
|
||||
if query_in.vaddr(31 downto 29) = "100" then -- 80000000 to 9FFFFFFF
|
||||
hit_umc <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
proc_entry_lo_umuc:
|
||||
process(clk)
|
||||
variable index : integer;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
hit_umuc <= '0';
|
||||
if query_in.vaddr(31 downto 29) = "101" then -- A0000000 to BFFFFFFF
|
||||
hit_umuc <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
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:
|
||||
@@ -326,25 +337,5 @@ if USE_TLB = false generate
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
registered_output:
|
||||
process(clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
if query_in.vld = '1' then
|
||||
vaddr_reg <= query_in.vaddr;
|
||||
end if;
|
||||
valid <= 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;
|
||||
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
end behavior;
|
||||
|
||||
+167
-112
@@ -31,10 +31,12 @@ use work.mips_types.all;
|
||||
entity mips_top is
|
||||
Generic
|
||||
(
|
||||
icache_size : natural := 8192; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 4096; -- words
|
||||
dcache_line : natural := 8 -- words
|
||||
icache_size : natural := 8192; -- words
|
||||
icache_line : natural := 8; -- words
|
||||
dcache_size : natural := 4096; -- words
|
||||
dcache_line : natural := 8; -- words
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true
|
||||
);
|
||||
Port
|
||||
(
|
||||
@@ -67,44 +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_err : in STD_LOGIC;
|
||||
imem_rdy : in STD_LOGIC;
|
||||
imem_en : out STD_LOGIC;
|
||||
imem_addr : out word_t;
|
||||
imem_data : in word_t;
|
||||
dmem_err : in STD_LOGIC;
|
||||
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;
|
||||
@@ -113,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
|
||||
@@ -149,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.imem_err <= imem_err;
|
||||
debug.dmem_err <= 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';
|
||||
@@ -209,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;
|
||||
@@ -219,30 +210,29 @@ begin
|
||||
inst_pipeline: pipeline
|
||||
PORT MAP
|
||||
(
|
||||
rst => cpu_rst,
|
||||
clk => cpu_clk,
|
||||
ce => cpu_run,
|
||||
imem_err => imem_err,
|
||||
imem_rdy => imem_rdy,
|
||||
imem_en => imem_en,
|
||||
imem_addr => imem_addr,
|
||||
imem_data => imem_din,
|
||||
dmem_err => dmem_err,
|
||||
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
|
||||
(
|
||||
@@ -260,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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -608,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;
|
||||
|
||||
@@ -630,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;
|
||||
|
||||
@@ -650,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;
|
||||
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -0,0 +1,389 @@
|
||||
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_dcache IS
|
||||
END tb_dcache;
|
||||
|
||||
ARCHITECTURE behavior OF tb_dcache IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant TLB_NUM_ENTRIES : integer := 8;
|
||||
|
||||
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 ce : std_logic := '1';
|
||||
|
||||
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;
|
||||
|
||||
signal tlb_in : tlb_query_in_t;
|
||||
signal tlb_out : tlb_query_out_t;
|
||||
|
||||
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
signal tlb_va : word_t := (others => '-');
|
||||
|
||||
signal tlb_pa : word_t;
|
||||
signal tlb_flags : tlb_flags_t;
|
||||
signal tlb_hit : STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_en : STD_LOGIC := '0';
|
||||
signal cpu_we : STD_LOGIC := '0';
|
||||
signal cpu_addr : word_t := (others => '-');
|
||||
signal cpu_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_dout : word_t;
|
||||
signal cpu_rdy : STD_LOGIC;
|
||||
|
||||
-- Cache control
|
||||
signal dcache_ctrl_in : cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
signal bus_din : word_t := (others => '-');
|
||||
signal bus_din_rdy : std_logic := '0';
|
||||
signal bus_din_vld : std_logic := '0';
|
||||
|
||||
signal bus_dout : word_t := (others => '-');
|
||||
signal bus_dout_vld : std_logic := '0';
|
||||
signal bus_dout_rdy : std_logic := '0';
|
||||
|
||||
-- busmaster command
|
||||
signal bus_cmd_rdy : std_logic := '0';
|
||||
signal bus_cmd_we : std_logic := '0';
|
||||
signal bus_cmd_cycle_en : std_logic := '0';
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic := '0';
|
||||
|
||||
signal cpu_din_reg : word_t;
|
||||
signal cpu_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
ce => ce,
|
||||
|
||||
index_in => index_in,
|
||||
entry_we => entry_we,
|
||||
entry_lo_in => entry_lo_in,
|
||||
entry_hi_in => entry_hi_in,
|
||||
|
||||
index_out => index_out,
|
||||
entry_re => entry_re,
|
||||
entry_lo_out => entry_lo_out,
|
||||
entry_hi_out => entry_hi_out,
|
||||
|
||||
tlb_query_in => tlb_in,
|
||||
tlb_query_out => tlb_out
|
||||
);
|
||||
|
||||
dcache_ctrl_in.inv_addr <= X"BEEF_BABE";
|
||||
dcache_ctrl_in.inv_at <= '0';
|
||||
dcache_ctrl_in.inv_all <= '0';
|
||||
|
||||
inst_dcache: entity work.dcache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => 1024,
|
||||
line_size => 8
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
-- CPU control/data
|
||||
en => cpu_en,
|
||||
we => cpu_we,
|
||||
addr => cpu_addr,
|
||||
be => cpu_be,
|
||||
din => cpu_din,
|
||||
dout => cpu_dout,
|
||||
rdy => cpu_rdy,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => dcache_ctrl_in,
|
||||
tlb_query_in => tlb_out,
|
||||
tlb_query_out => tlb_in,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_din,
|
||||
bus_din_rdy => bus_din_rdy,
|
||||
bus_din_vld => bus_din_vld,
|
||||
|
||||
bus_dout => bus_dout,
|
||||
bus_dout_vld => bus_dout_vld,
|
||||
bus_dout_rdy => bus_dout_rdy,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => bus_cmd_rdy,
|
||||
bus_cmd_we => bus_cmd_we,
|
||||
bus_cmd_cycle_en => bus_cmd_cycle_en,
|
||||
bus_cmd_out => bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_busmaster_sync : entity work.busmaster_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
FIFO_DEPTH => 4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => 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_dout_rdy,
|
||||
din_we => bus_dout_vld,
|
||||
din => bus_dout,
|
||||
|
||||
dout => bus_din,
|
||||
dout_vld => bus_din_vld,
|
||||
dout_re => bus_din_rdy,
|
||||
|
||||
-- JBUS Master signals
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_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
|
||||
);
|
||||
|
||||
|
||||
cpu_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_din_vld <= '0';
|
||||
if en2 = '1' and cpu_rdy = '1' then
|
||||
cpu_din_reg <= cpu_dout;
|
||||
cpu_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
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
|
||||
|
||||
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
entry_hi_in.vpn <= vpn;
|
||||
entry_hi_in.asid <= asid;
|
||||
entry_hi_in.g <= g;
|
||||
|
||||
entry_lo_in.pfn <= pfn;
|
||||
entry_lo_in.n <= n;
|
||||
entry_lo_in.d <= d;
|
||||
entry_lo_in.v <= v;
|
||||
|
||||
entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_write;
|
||||
|
||||
procedure cpu_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '0';
|
||||
cpu_addr <= addr;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
|
||||
end procedure cpu_read;
|
||||
|
||||
procedure cpu_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '1';
|
||||
cpu_addr <= addr;
|
||||
cpu_din <= data;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
|
||||
end procedure cpu_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"00DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(1, "110000", X"0000_1", X"11DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(2, "110000", X"0000_2", X"22DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(3, "110000", X"0000_3", X"33DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(4, "110000", X"0000_4", X"44DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(5, "110000", X"0000_5", X"55DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(6, "110000", X"0000_6", X"66DE_C", '0', '0', '0', '1');
|
||||
cmd_entry_write(7, "110000", X"0000_7", X"77DE_C", '0', '0', '0', '1');
|
||||
|
||||
|
||||
cpu_read(X"BFC0_0200");
|
||||
cpu_read(X"BFC0_0180");
|
||||
|
||||
cpu_read(X"8000_0204");
|
||||
cpu_read(X"8000_0300");
|
||||
cpu_read(X"8000_0304");
|
||||
cpu_read(X"8000_0308");
|
||||
|
||||
cpu_read(X"9000_0208");
|
||||
cpu_read(X"9000_030C");
|
||||
cpu_read(X"9100_0310");
|
||||
cpu_read(X"9200_0314");
|
||||
|
||||
cpu_read(X"A000_020C");
|
||||
cpu_read(X"A000_0318");
|
||||
cpu_read(X"A100_031C");
|
||||
cpu_read(X"A200_0320");
|
||||
|
||||
cpu_read(X"B000_0210");
|
||||
cpu_read(X"B000_0324");
|
||||
cpu_read(X"B000_0328");
|
||||
cpu_read(X"B000_032C");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_read(X"0000_8500");
|
||||
cpu_read(X"0000_9520");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
cpu_read(X"0000_0410");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0408");
|
||||
cpu_write(X"0000_0404", X"5555_5555");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_write(X"0000_0404", X"6666_6666");
|
||||
cpu_read(X"0000_0434");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_write(X"0000_0400", X"1111_1111");
|
||||
cpu_write(X"0000_0404", X"2222_2222");
|
||||
cpu_write(X"0000_0408", X"3333_3333");
|
||||
cpu_write(X"0000_040C", X"4444_4444");
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -0,0 +1,363 @@
|
||||
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_icache IS
|
||||
END tb_icache;
|
||||
|
||||
ARCHITECTURE behavior OF tb_icache IS
|
||||
|
||||
constant DATA_WIDTH : integer := 32;
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant TLB_NUM_ENTRIES : integer := 8;
|
||||
|
||||
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 ce : std_logic := '1';
|
||||
|
||||
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;
|
||||
|
||||
signal tlb_in : tlb_query_in_t;
|
||||
signal tlb_out : tlb_query_out_t;
|
||||
|
||||
signal tlb_index_hit : unsigned(lg2(TLB_NUM_ENTRIES)-1 downto 0);
|
||||
signal tlb_va : word_t := (others => '-');
|
||||
|
||||
signal tlb_pa : word_t;
|
||||
signal tlb_flags : tlb_flags_t;
|
||||
signal tlb_hit : STD_LOGIC;
|
||||
|
||||
-- CPU control/data
|
||||
signal cpu_en : STD_LOGIC := '0';
|
||||
signal cpu_we : STD_LOGIC := '0';
|
||||
signal cpu_be : unsigned(3 downto 0) := (others => '1');
|
||||
signal cpu_addr : word_t := (others => '-');
|
||||
signal cpu_dout : word_t;
|
||||
signal cpu_din : word_t := X"BFC0_BABE";
|
||||
signal cpu_rdy : STD_LOGIC;
|
||||
|
||||
-- Cache control
|
||||
signal icache_ctrl_in : cache_ctrl_t;
|
||||
|
||||
-- busmaster data
|
||||
signal bus_din : word_t := (others => '-');
|
||||
signal bus_din_rdy : std_logic := '0';
|
||||
signal bus_din_vld : std_logic := '0';
|
||||
|
||||
signal bus_dout : word_t := (others => '-');
|
||||
signal bus_dout_vld : std_logic := '0';
|
||||
signal bus_dout_rdy : std_logic := '0';
|
||||
|
||||
-- busmaster command
|
||||
signal bus_cmd_rdy : std_logic := '0';
|
||||
signal bus_cmd_we : std_logic := '0';
|
||||
signal bus_cmd_cycle_en : std_logic := '0';
|
||||
signal bus_cmd : bm_cmd_t;
|
||||
signal bus_cyc_complete : std_logic := '0';
|
||||
|
||||
signal cpu_din_reg : word_t;
|
||||
signal cpu_din_vld : STD_LOGIC;
|
||||
|
||||
BEGIN
|
||||
|
||||
inst_tlb : entity work.tlb
|
||||
GENERIC MAP
|
||||
(
|
||||
NUM_ENTRIES => TLB_NUM_ENTRIES
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
ce => ce,
|
||||
|
||||
index_in => index_in,
|
||||
entry_we => entry_we,
|
||||
entry_lo_in => entry_lo_in,
|
||||
entry_hi_in => entry_hi_in,
|
||||
|
||||
index_out => index_out,
|
||||
entry_re => entry_re,
|
||||
entry_lo_out => entry_lo_out,
|
||||
entry_hi_out => entry_hi_out,
|
||||
|
||||
tlb_query_in => tlb_in,
|
||||
tlb_query_out => tlb_out
|
||||
);
|
||||
|
||||
icache_ctrl_in.inv_addr <= X"BEEF_BABE";
|
||||
icache_ctrl_in.inv_at <= '0';
|
||||
icache_ctrl_in.inv_all <= '0';
|
||||
|
||||
inst_icache: entity work.icache
|
||||
GENERIC MAP
|
||||
(
|
||||
cache_size => 1024,
|
||||
line_size => 8
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
rst => RST,
|
||||
clk => CLK,
|
||||
|
||||
-- CPU control/data
|
||||
en => cpu_en,
|
||||
addr => cpu_addr,
|
||||
dout => cpu_dout,
|
||||
rdy => cpu_rdy,
|
||||
|
||||
-- Cache control
|
||||
ctrl_in => icache_ctrl_in,
|
||||
tlb_query_in => tlb_out,
|
||||
tlb_query_out => tlb_in,
|
||||
|
||||
-- busmaster data
|
||||
bus_din => bus_din,
|
||||
bus_din_rdy => bus_din_rdy,
|
||||
bus_din_vld => bus_din_vld,
|
||||
|
||||
-- busmaster command
|
||||
bus_cmd_rdy => bus_cmd_rdy,
|
||||
bus_cmd_we => bus_cmd_we,
|
||||
bus_cmd_cycle_en => bus_cmd_cycle_en,
|
||||
bus_cmd_out => bus_cmd,
|
||||
bus_cyc_complete => bus_cyc_complete
|
||||
);
|
||||
|
||||
|
||||
inst_busmaster_sync : entity work.busmaster_sync
|
||||
GENERIC MAP
|
||||
(
|
||||
DATA_WIDTH => DATA_WIDTH,
|
||||
FIFO_DEPTH => 4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
-- System signals
|
||||
rst => RST,
|
||||
clk => 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_dout_rdy,
|
||||
din_we => bus_dout_vld,
|
||||
din => bus_dout,
|
||||
|
||||
dout => bus_din,
|
||||
dout_vld => bus_din_vld,
|
||||
dout_re => bus_din_rdy,
|
||||
|
||||
-- JBUS Master signals
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
MRDY_O => MRDY_O,
|
||||
ADDR_O => ADDR_O,
|
||||
MDAT_I => MDAT_I,
|
||||
MDAT_O => MDAT_O
|
||||
);
|
||||
|
||||
inst_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
|
||||
);
|
||||
|
||||
|
||||
cpu_din_register:
|
||||
process(clk)
|
||||
variable en2: std_logic;
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
cpu_din_vld <= '0';
|
||||
if en2 = '1' and cpu_rdy = '1' then
|
||||
cpu_din_reg <= cpu_dout;
|
||||
cpu_din_vld <= '1';
|
||||
end if;
|
||||
en2 := cpu_en;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
CLK_GEN: process
|
||||
begin
|
||||
wait for CLK_PERIOD/2;
|
||||
CLK <= not CLK;
|
||||
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
|
||||
|
||||
index_in <= to_unsigned(index, lg2(TLB_NUM_ENTRIES));
|
||||
|
||||
entry_hi_in.vpn <= vpn;
|
||||
entry_hi_in.asid <= asid;
|
||||
entry_hi_in.g <= g;
|
||||
|
||||
entry_lo_in.pfn <= pfn;
|
||||
entry_lo_in.n <= n;
|
||||
entry_lo_in.d <= d;
|
||||
entry_lo_in.v <= v;
|
||||
|
||||
entry_we <= '1';
|
||||
wait until rising_edge(CLK);
|
||||
entry_we <= '0';
|
||||
|
||||
end procedure cmd_entry_write;
|
||||
|
||||
procedure cpu_read(addr : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '0';
|
||||
cpu_addr <= addr;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
end procedure cpu_read;
|
||||
|
||||
procedure cpu_write(addr, data : unsigned) is
|
||||
begin
|
||||
|
||||
cpu_we <= '1';
|
||||
cpu_addr <= addr;
|
||||
cpu_din <= data;
|
||||
cpu_en <= '1';
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
cpu_en <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK);
|
||||
|
||||
end procedure cpu_write;
|
||||
|
||||
begin
|
||||
|
||||
wait for 6*CLK_PERIOD;
|
||||
RST <= '0';
|
||||
wait for 60*CLK_PERIOD;
|
||||
wait until rising_edge(CLK) and cpu_rdy = '1';
|
||||
|
||||
cmd_entry_write(0, "110000", X"0000_0", X"00DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(1, "110000", X"0000_1", X"11DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(2, "110000", X"0000_2", X"22DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(3, "110000", X"0000_3", X"33DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(4, "110000", X"0000_4", X"44DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(5, "110000", X"0000_5", X"55DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(6, "110000", X"0000_6", X"66DE_F", '0', '0', '0', '1');
|
||||
cmd_entry_write(7, "110000", X"0000_7", X"77DE_F", '0', '0', '0', '1');
|
||||
|
||||
cpu_read(X"BFC0_0200");
|
||||
cpu_read(X"BFC0_0180");
|
||||
|
||||
cpu_read(X"8000_0204");
|
||||
cpu_read(X"8000_0300");
|
||||
cpu_read(X"8000_0304");
|
||||
cpu_read(X"8000_0308");
|
||||
|
||||
cpu_read(X"9000_0208");
|
||||
cpu_read(X"9000_030C");
|
||||
cpu_read(X"9100_0310");
|
||||
cpu_read(X"9200_0314");
|
||||
|
||||
cpu_read(X"A000_020C");
|
||||
cpu_read(X"A000_0318");
|
||||
cpu_read(X"A100_031C");
|
||||
cpu_read(X"A200_0320");
|
||||
|
||||
cpu_read(X"B000_0210");
|
||||
cpu_read(X"B000_0324");
|
||||
cpu_read(X"B000_0328");
|
||||
cpu_read(X"B000_032C");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_read(X"0000_8500");
|
||||
cpu_read(X"0000_9520");
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
cpu_read(X"0000_1420");
|
||||
cpu_read(X"0000_2440");
|
||||
cpu_read(X"0000_3460");
|
||||
cpu_read(X"0000_4480");
|
||||
cpu_read(X"0000_54A0");
|
||||
cpu_read(X"0000_64C0");
|
||||
cpu_read(X"0000_74E0");
|
||||
cpu_write(X"0000_0400", X"AAAA_AAAA");
|
||||
|
||||
-- cmd_entry_write(0, "110000", X"0000_0", X"40DE_F", '0', '0', '1', '1');
|
||||
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
cpu_read(X"0000_0410");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0408");
|
||||
cpu_write(X"0000_0404", X"5555_5555");
|
||||
cpu_read(X"0000_0404");
|
||||
cpu_read(X"0000_0400");
|
||||
|
||||
wait;
|
||||
|
||||
end process;
|
||||
|
||||
END;
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
@@ -41,8 +42,10 @@ ARCHITECTURE behavior OF tb_mips_top IS
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant SRAM_ADDR_WIDTH : integer := 17; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 17; -- bits
|
||||
|
||||
signal debug : chip_debug_t;
|
||||
constant WITH_TLB : boolean := true;
|
||||
constant KSEG_01_TRANSLATED : boolean := true;
|
||||
signal debug : chip_debug_t;
|
||||
signal tb_fin : STD_LOGIC := '0';
|
||||
|
||||
-- Master
|
||||
signal nmi : STD_LOGIC := '0';
|
||||
@@ -115,7 +118,43 @@ ARCHITECTURE behavior OF tb_mips_top IS
|
||||
type word_array_t is array (natural range <>) of unsigned(31 downto 0);
|
||||
signal sram_data : word_array_t(0 to 2**SRAM_ADDR_WIDTH-1);
|
||||
signal flash_data : word_array_t(0 to 2**FLASH_ADDR_WIDTH-1);
|
||||
|
||||
subtype nibble_t is unsigned (3 downto 0);
|
||||
|
||||
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
|
||||
|
||||
------------------------------------------------------------------
|
||||
@@ -128,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
|
||||
@@ -152,6 +231,7 @@ mem_mux:
|
||||
mem_area <= mem_sram;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
@@ -199,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
|
||||
(
|
||||
@@ -394,14 +476,16 @@ SRAM_WRITE:
|
||||
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 "ucb.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.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);
|
||||
@@ -437,6 +521,62 @@ FLASH_READ:
|
||||
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,12 +586,13 @@ STIMULUS: process
|
||||
wait for 3*CLK_PERIOD;
|
||||
wait until rising_edge(clk);
|
||||
rst <= '0';
|
||||
wait for 778254*CLK_PERIOD;
|
||||
|
||||
wait for 1200000*CLK_PERIOD;
|
||||
|
||||
wait until rising_edge(clk);
|
||||
nmi <= '0';
|
||||
wait for 3000*CLK_PERIOD;
|
||||
tb_fin <= '1';
|
||||
wait until rising_edge(clk);
|
||||
nmi <= '0';
|
||||
tb_fin <= '0';
|
||||
|
||||
wait;
|
||||
|
||||
|
||||
@@ -5,8 +5,10 @@ vlib work
|
||||
vcom -explicit -93 "../src/sdram_config_sim.vhd"
|
||||
|
||||
# Packages
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_util_pkg.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_types.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_instr.vhd"
|
||||
vcom -explicit -93 "../../../lib/JBUS/src/busmaster_types.vhd"
|
||||
vcom -explicit -93 "../../../lib/FIFO/src/fifo_ctrl_pkg.vhd"
|
||||
vcom -explicit -93 "../../../lib/SDRAM/ddr_sdr_v1_5/src/sdram_types.vhd"
|
||||
vcom -explicit -93 "../../../lib/misc/utils_pkg.vhd"
|
||||
@@ -33,8 +35,11 @@ vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_bcu.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_pipeline.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_muldiv.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_cop.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_cam.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_tlb.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_dcache.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_icache.vhd"
|
||||
vcom -explicit -93 "../../../lib/JBUS/src/busmaster_async.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_biu.vhd"
|
||||
vcom -explicit -93 "../../../lib/CPUs/MIPS/src/core/mips_top.vhd"
|
||||
vcom -explicit -93 "../src/bootloader.ROM.vhd"
|
||||
|
||||
@@ -161,22 +161,6 @@ add wave -noupdate -format Logic /tb_mips_sys/uut/ack_i_vga
|
||||
add wave -noupdate -divider BUI
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/clk_o
|
||||
add wave -noupdate -format Literal -label .op -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/ex_stage.op
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/read_cycle
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/ack
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/dat
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bout_rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_re
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_we
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_full
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bin_fifo_empty
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/bus_idle
|
||||
add wave -noupdate -divider VGA-Slave
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_vga_frontend/rst_i
|
||||
@@ -286,14 +270,14 @@ add wave -noupdate -format Logic /tb_mips_sys/uut/ssram_bsy
|
||||
add wave -noupdate -divider {MIPS TOP}
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/clk_o
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/hdu
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/sdu
|
||||
add wave -noupdate -format Literal -expand /tb_mips_sys/uut/inst_mips_top/inst_pipeline/sdu
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_pipeline/cpu_run
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/inst_reg_dual/reg_mem
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_clockgen/cpu_clk_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/id_stage
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_pipeline/id_stage
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/sdu
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_clockgen/cpu_clk_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/ex_stage
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_pipeline/ex_stage
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/sdu
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_clockgen/cpu_clk_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_pipeline/mem_stage
|
||||
@@ -323,26 +307,18 @@ add wave -noupdate -format Literal /tb_mips_sys/uut/sys_sdr_dqs_q
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/sys_sdr_ras_qn
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/sys_sdr_we_qn
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/clk
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tlb_query_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tlb_query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_clockgen/cpu_clk_out
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/rst_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/clk_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/srdy_i
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/dat_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cyc_o
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/ctrl
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/s
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/sn
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tag_match
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/request_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/fill_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/tag_reg_inv
|
||||
@@ -365,52 +341,31 @@ add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_ic
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/invalidate_ack
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/req_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/req_cache_index
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/fill_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/fill_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/fill_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_icache/cpu_word_index
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/en
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/we
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/rdy
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/ctrl_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tlb_query_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tlb_query_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/debug
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_clockgen/cpu_clk_out
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/rst_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/clk_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/ack_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/srdy_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/mrdy_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/addr_o
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/dat_i
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/stb_o
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cyc_o
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/ctrl
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_en
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_we
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_be
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_din
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/s
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/sn
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_match
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_hit_inv
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_match_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/request_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/fill_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_index_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_reg_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_data_reg
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_be_reg
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_we_reg
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_we2
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_in
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cache_entry_out_inv
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_ram_din
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/tag_ram_we
|
||||
add wave -noupdate -format Literal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/fill_count
|
||||
@@ -428,19 +383,11 @@ add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dc
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/invalidate_en
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/invalidate_req
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/hit_cache_index
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_hit_we
|
||||
add wave -noupdate -format Logic /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/req_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/req_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/req_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/fill_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/fill_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/fill_word_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_tag
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_cache_index
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_sys/uut/inst_mips_top/inst_biu/inst_dcache/cpu_word_index
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 2} {9216870000 ps} 0} {{Cursor 100} {98503600 ps} 0} {{Cursor 3} {15592084279 ps} 0}
|
||||
WaveRestoreCursors {{Cursor 2} {4787725085 ps} 0} {{Cursor 100} {539632527 ps} 0} {{Cursor 3} {11823240 ps} 0}
|
||||
configure wave -namecolwidth 187
|
||||
configure wave -valuecolwidth 64
|
||||
configure wave -justifyvalue left
|
||||
@@ -454,4 +401,4 @@ configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {15591849308 ps} {15592330693 ps}
|
||||
WaveRestoreZoom {11675145 ps} {12107788 ps}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ ENTITY mips_sys IS
|
||||
GENERIC
|
||||
(
|
||||
sys_freq_in : real := 100.0;
|
||||
cpu_freq : real := 100.0;
|
||||
cpu_freq : real := 60.0;
|
||||
sdram_phaseshift : integer := 0;
|
||||
tsvga : vga_timespec_t := ts_vga_800_600_60
|
||||
|
||||
@@ -154,10 +154,10 @@ END mips_sys;
|
||||
|
||||
ARCHITECTURE behavior OF mips_sys IS
|
||||
|
||||
COMPONENT mips_top
|
||||
COMPONENT mips_top_netlist
|
||||
Port
|
||||
(
|
||||
debug : out chip_debug_t;
|
||||
debug : out unsigned(1 downto 0);
|
||||
eb : in STD_LOGIC;
|
||||
nmi : in STD_LOGIC;
|
||||
cpu_clk : in STD_LOGIC;
|
||||
@@ -487,7 +487,7 @@ ARCHITECTURE behavior OF mips_sys IS
|
||||
signal usb_inten : std_logic;
|
||||
signal phy_inten : std_logic;
|
||||
|
||||
signal debug : chip_debug_t;
|
||||
signal debug : unsigned(1 downto 0);
|
||||
|
||||
-- DDR SDRAM
|
||||
constant BURST_LEN : natural := 2;
|
||||
@@ -539,8 +539,8 @@ BEGIN
|
||||
sys_phy_mdio <= gpo_0(31);
|
||||
|
||||
eb <= sys_dip(7);
|
||||
sys_error(0) <= debug.imem_err;
|
||||
sys_error(1) <= debug.dmem_err;
|
||||
sys_error(0) <= debug(0);
|
||||
sys_error(1) <= debug(1);
|
||||
nmi <= not sys_rst_n_in;
|
||||
rst_in <= not sys_rst_n_in and sys_btn(0);
|
||||
sys_flash_byten <= '1';
|
||||
@@ -604,18 +604,34 @@ int_sample:
|
||||
end if;
|
||||
end 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 = 0xAC000000, Physical = 0x0C000000
|
||||
-- io_c : Virtual = 0x8C000000, Physical = 0x0C000000
|
||||
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
mem_area <= mem_dead;
|
||||
mem_mapped_io <= '0';
|
||||
mem_mapped_io <= '0';
|
||||
if ADDR_O(31 downto 28) = X"0" then
|
||||
mem_area <= mem_flash;
|
||||
elsif ADDR_O(31 downto 28) = X"1" then
|
||||
mem_area <= mem_emac;
|
||||
elsif ADDR_O(31 downto 28) = X"A" then
|
||||
mem_mapped_io <= '1';
|
||||
if ADDR_O(27 downto 26) = "00" then
|
||||
mem_area <= mem_sdram;
|
||||
elsif ADDR_O(27 downto 26) = "01" then
|
||||
mem_area <= mem_flash;
|
||||
mem_mapped_io <= '1';
|
||||
elsif ADDR_O(27 downto 26) = "10" then
|
||||
mem_area <= mem_flash;
|
||||
elsif ADDR_O(27 downto 26) = "11" then
|
||||
mem_mapped_io <= '1';
|
||||
if ADDR_O(18 downto 16) = "000" then
|
||||
mem_area <= mem_gpio;
|
||||
elsif ADDR_O(18 downto 16) = "001" then
|
||||
@@ -637,16 +653,55 @@ mem_mux:
|
||||
elsif ADDR_O(18 downto 16) = "101" then
|
||||
mem_area <= mem_emac;
|
||||
end if;
|
||||
elsif ADDR_O(27 downto 26) = "01" then
|
||||
mem_area <= mem_flash;
|
||||
end if;
|
||||
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
||||
end if;
|
||||
elsif (ADDR_O(31 downto 28) = X"1" and ADDR_O(15) = '0') then
|
||||
mem_area <= mem_rom;
|
||||
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
||||
mem_area <= mem_sdram;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- mem_mux:
|
||||
-- process(ADDR_O)
|
||||
-- begin
|
||||
-- mem_area <= mem_dead;
|
||||
-- mem_mapped_io <= '0';
|
||||
-- if ADDR_O(31 downto 28) = X"0" then
|
||||
-- mem_area <= mem_flash;
|
||||
-- elsif ADDR_O(31 downto 28) = X"1" then
|
||||
-- mem_area <= mem_emac;
|
||||
-- elsif ADDR_O(31 downto 28) = X"A" then
|
||||
-- mem_mapped_io <= '1';
|
||||
-- if ADDR_O(27 downto 26) = "00" then
|
||||
-- if ADDR_O(18 downto 16) = "000" then
|
||||
-- mem_area <= mem_gpio;
|
||||
-- elsif ADDR_O(18 downto 16) = "001" then
|
||||
-- if ADDR_O(9 downto 8) = "00" then
|
||||
-- mem_area <= mem_uart0;
|
||||
-- elsif ADDR_O(9 downto 8) = "01" then
|
||||
-- mem_area <= mem_uart1;
|
||||
-- elsif ADDR_O(9 downto 8) = "10" then
|
||||
-- mem_area <= mem_ps2_0;
|
||||
-- elsif ADDR_O(9 downto 8) = "11" then
|
||||
-- mem_area <= mem_ps2_1;
|
||||
-- end if;
|
||||
-- elsif ADDR_O(18 downto 16) = "010" then
|
||||
-- mem_area <= mem_usb;
|
||||
-- elsif ADDR_O(18 downto 16) = "011" then
|
||||
-- mem_area <= mem_vga;
|
||||
-- elsif ADDR_O(18 downto 16) = "100" then
|
||||
-- mem_area <= mem_ac97;
|
||||
-- elsif ADDR_O(18 downto 16) = "101" then
|
||||
-- mem_area <= mem_emac;
|
||||
-- end if;
|
||||
-- elsif ADDR_O(27 downto 26) = "01" then
|
||||
-- mem_area <= mem_flash;
|
||||
-- end if;
|
||||
-- elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
||||
-- mem_area <= mem_rom;
|
||||
-- elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
||||
-- mem_area <= mem_sdram;
|
||||
-- end if;
|
||||
-- end process;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
begin
|
||||
@@ -725,7 +780,7 @@ signal_mux:
|
||||
SDAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
||||
|
||||
------------------------------------------------------------------
|
||||
inst_mips_top: mips_top
|
||||
inst_mips_top_netlist: mips_top_netlist
|
||||
PORT MAP
|
||||
(
|
||||
debug => debug,
|
||||
|
||||
@@ -44,6 +44,8 @@ GENERIC
|
||||
(
|
||||
sys_freq_in : real := 100.0;
|
||||
cpu_freq : real := 100.0;
|
||||
WITH_TLB : boolean := true;
|
||||
TRANSLATE_KSEG0_1 : boolean := true;
|
||||
sdram_phaseshift : integer := 0;
|
||||
tsvga : vga_timespec_t := ts_vga_800_600_72
|
||||
|
||||
@@ -448,6 +450,63 @@ int_sample:
|
||||
end if;
|
||||
end 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 = 0xAC000000, Physical = 0x0C000000
|
||||
-- io_c : Virtual = 0x8C000000, Physical = 0x0C000000
|
||||
|
||||
gen_mem_mux_translate:
|
||||
if TRANSLATE_KSEG0_1 = 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_sdram;
|
||||
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
|
||||
if ADDR_O(9 downto 8) = "00" then
|
||||
mem_area <= mem_uart0;
|
||||
elsif ADDR_O(9 downto 8) = "01" then
|
||||
mem_area <= mem_uart1;
|
||||
elsif ADDR_O(9 downto 8) = "10" then
|
||||
mem_area <= mem_uart2;
|
||||
end if;
|
||||
elsif ADDR_O(18 downto 16) = "010" then
|
||||
mem_area <= mem_usb;
|
||||
elsif ADDR_O(18 downto 16) = "011" then
|
||||
mem_area <= mem_vga;
|
||||
elsif ADDR_O(18 downto 16) = "100" then
|
||||
mem_area <= mem_ac97;
|
||||
elsif ADDR_O(18 downto 16) = "101" then
|
||||
mem_area <= mem_emac;
|
||||
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 TRANSLATE_KSEG0_1 = false generate
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
@@ -490,6 +549,7 @@ mem_mux:
|
||||
mem_area <= mem_sdram;
|
||||
end if;
|
||||
end process;
|
||||
end generate;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
@@ -570,6 +630,13 @@ signal_mux:
|
||||
|
||||
------------------------------------------------------------------
|
||||
inst_mips_top: entity work.mips_top
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => 256, -- words
|
||||
dcache_size => 256, -- words
|
||||
WITH_TLB => WITH_TLB,
|
||||
TRANSLATE_KSEG0_1 => TRANSLATE_KSEG0_1
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
debug => debug,
|
||||
|
||||
Reference in New Issue
Block a user