forked from Github_Repos/cvw
Merge branch 'main' of https://github.com/davidharrishmc/riscv-wally into main
This commit is contained in:
commit
a968ae2f66
2
.gitignore
vendored
2
.gitignore
vendored
@ -126,3 +126,5 @@ tests/custom/*/*/*.map
|
||||
tests/custom/*/*/*.memfile
|
||||
tests/custom/crt0/*.a
|
||||
/pipelined/regression/sd_model.log
|
||||
fpga/src/sdc/*
|
||||
fpga/src/sdc.tar.gz
|
||||
|
@ -82,12 +82,12 @@ connect_debug_port u_ila_0/probe14 [get_nets [list {wallypipelinedsoc/core/lsu/b
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe15]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe15]
|
||||
connect_debug_port u_ila_0/probe15 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs/SEPC_REGW[63]} ]]
|
||||
connect_debug_port u_ila_0/probe15 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/SEPC_REGW[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe16]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe16]
|
||||
connect_debug_port u_ila_0/probe16 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SCAUSE_REGW[63]} ]]
|
||||
connect_debug_port u_ila_0/probe16 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SCAUSE_REGW[63]} ]]
|
||||
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
@ -109,7 +109,7 @@ connect_debug_port u_ila_0/probe19 [get_nets [list {wallypipelinedsoc/core/ieu/d
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 63 [get_debug_ports u_ila_0/probe20]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe20]
|
||||
connect_debug_port u_ila_0/probe20 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs/STVEC_REGW[63]} ]]
|
||||
connect_debug_port u_ila_0/probe20 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/STVEC_REGW[63]} ]]
|
||||
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
@ -674,7 +674,7 @@ connect_debug_port u_ila_0/probe129 [get_nets [list {wallypipelinedsoc/core/ieu/
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 64 [get_debug_ports u_ila_0/probe130]
|
||||
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe130]
|
||||
connect_debug_port u_ila_0/probe130 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs/csrs.SSCRATCH_REGW[63]} ]]
|
||||
connect_debug_port u_ila_0/probe130 [get_nets [list {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[0]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[1]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[2]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[3]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[4]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[5]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[6]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[7]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[8]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[9]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[10]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[11]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[12]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[13]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[14]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[15]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[16]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[17]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[18]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[19]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[20]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[21]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[22]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[23]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[24]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[25]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[26]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[27]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[28]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[29]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[30]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[31]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[32]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[33]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[34]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[35]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[36]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[37]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[38]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[39]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[40]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[41]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[42]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[43]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[44]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[45]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[46]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[47]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[48]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[49]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[50]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[51]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[52]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[53]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[54]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[55]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[56]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[57]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[58]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[59]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[60]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[61]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[62]} {wallypipelinedsoc/core/priv.priv/csr/csrs.csrs/csrs.SSCRATCH_REGW[63]} ]]
|
||||
|
||||
create_debug_port u_ila_0 probe
|
||||
set_property port_width 8 [get_debug_ports u_ila_0/probe131]
|
||||
|
@ -1,18 +1,19 @@
|
||||
dst := IP
|
||||
sdc_src := ~/repos/sdc.tar.gz
|
||||
# vcu118
|
||||
export XILINX_PART := xcvu9p-flga2104-2L-e
|
||||
export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
|
||||
export board := vcu118
|
||||
#export XILINX_PART := xcvu9p-flga2104-2L-e
|
||||
#export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
|
||||
#export board := vcu118
|
||||
|
||||
# vcu108
|
||||
#export XILINX_PART := xcvu095-ffva2104-2-e
|
||||
#export XILINX_BOARD := xilinx.com:vcu108:part0:1.2
|
||||
#export board := vcu108
|
||||
export XILINX_PART := xcvu095-ffva2104-2-e
|
||||
export XILINX_BOARD := xilinx.com:vcu108:part0:1.2
|
||||
export board := vcu108
|
||||
|
||||
|
||||
all: FPGA
|
||||
|
||||
FPGA: IP
|
||||
FPGA: IP SDC
|
||||
vivado -mode tcl -source wally.tcl 2>&1 | tee wally.log
|
||||
|
||||
IP: $(dst)/xlnx_proc_sys_reset.log \
|
||||
@ -20,6 +21,10 @@ IP: $(dst)/xlnx_proc_sys_reset.log \
|
||||
$(dst)/xlnx_axi_clock_converter.log \
|
||||
$(dst)/xlnx_ahblite_axi_bridge.log
|
||||
|
||||
SDC:
|
||||
cp $(sdc_src) ../src/
|
||||
tar xzf ../src/sdc.tar.gz -C ../src
|
||||
|
||||
$(dst)/%.log: %.tcl
|
||||
mkdir -p IP
|
||||
cd IP;\
|
||||
|
@ -17,6 +17,7 @@ read_ip IP/xlnx_ddr4.srcs/sources_1/ip/xlnx_ddr4/xlnx_ddr4.xci
|
||||
|
||||
read_verilog -sv [glob -type f ../../pipelined/src/*/*.sv ../../pipelined/src/*/*/*.sv]
|
||||
read_verilog {../src/fpgaTop.v}
|
||||
read_verilog -sv [glob -type f ../src/sdc/*.sv]
|
||||
|
||||
set_property include_dirs {../../pipelined/config/fpga ../../pipelined/config/shared} [current_fileset]
|
||||
|
||||
|
17
pipelined/src/cache/cache.sv
vendored
17
pipelined/src/cache/cache.sv
vendored
@ -1,10 +1,13 @@
|
||||
///////////////////////////////////////////
|
||||
// cache
|
||||
//
|
||||
// Written: ross1728@gmail.com July 07, 2021
|
||||
// Implements the L1 instruction/data cache
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Created: 7 July 2021
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Storage for data and meta data.
|
||||
// Purpose: Implements the I$ and D$. Interfaces with requests from IEU and HPTW and ahbcacheinterface
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.9, 7.10, and 7.19)
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
@ -53,7 +56,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
||||
input logic SelBusBeat, // Word in cache line comes from BeatCount
|
||||
input logic [LOGBWPL-1:0] BeatCount, // Beat in burst
|
||||
input logic [LINELEN-1:0] FetchBuffer, // Buffer long enough to hold entire cache line arriving from bus
|
||||
output logic [1:0] CacheBusRW, // [1] Read or [0] write bus
|
||||
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
|
||||
output logic [`PA_BITS-1:0] CacheBusAdr // Address for bus access
|
||||
);
|
||||
|
||||
@ -63,11 +66,11 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, LOGBWPL, WORDLEN, MUXINTE
|
||||
localparam SETLEN = $clog2(NUMLINES); // Number of set bits
|
||||
localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits
|
||||
localparam TAGLEN = `PA_BITS - SETTOP; // Number of tag bits
|
||||
localparam WORDSPERLINE = LINELEN/WORDLEN; // Number of words in cache line
|
||||
localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line
|
||||
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^
|
||||
localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete
|
||||
localparam LOGLLENBYTES = $clog2(WORDLEN/8); // Number of bits to address a word
|
||||
localparam CACHEWORDSPERLINE = `DCACHE_LINELENINBITS/WORDLEN; // *** see if this is the same as WORDSPERLINE
|
||||
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE); // ***
|
||||
|
||||
|
||||
logic SelAdr;
|
||||
logic [1:0] AdrSelMuxSel;
|
||||
|
34
pipelined/src/cache/cacheLRU.sv
vendored
34
pipelined/src/cache/cacheLRU.sv
vendored
@ -1,10 +1,13 @@
|
||||
///////////////////////////////////////////
|
||||
// dcache (data cache)
|
||||
//
|
||||
// Written: ross1728@gmail.com July 20, 2021
|
||||
// Implements Pseudo LRU
|
||||
// Tested for Powers of 2.
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Created: 20 July 2021
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Implements Pseudo LRU. Tested for Powers of 2.
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.8 and 7.15 to 7.18)
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
@ -28,18 +31,19 @@
|
||||
|
||||
module cacheLRU
|
||||
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128) (
|
||||
input logic clk, reset,
|
||||
input logic CacheEn,
|
||||
input logic FlushStage,
|
||||
input logic [NUMWAYS-1:0] HitWay,
|
||||
input logic [NUMWAYS-1:0] ValidWay,
|
||||
input logic [SETLEN-1:0] CAdr,
|
||||
input logic [SETLEN-1:0] PAdr,
|
||||
input logic LRUWriteEn,
|
||||
input logic SetValid,
|
||||
input logic InvalidateCache,
|
||||
input logic FlushCache,
|
||||
output logic [NUMWAYS-1:0] VictimWay
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
||||
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
||||
input logic [NUMWAYS-1:0] HitWay, // Which way is valid and matches PAdr's tag
|
||||
input logic [NUMWAYS-1:0] ValidWay, // Which ways for a particular set are valid, ignores tag
|
||||
input logic [SETLEN-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
|
||||
input logic [SETLEN-1:0] PAdr, // Physical address
|
||||
input logic LRUWriteEn, // Update the LRU state
|
||||
input logic SetValid, // Set the dirty bit in the selected way and set
|
||||
input logic InvalidateCache, // Clear all valid bits
|
||||
input logic FlushCache, // Flush all dirty lines back to memory
|
||||
output logic [NUMWAYS-1:0] VictimWay // LRU selects a victim to evict
|
||||
);
|
||||
|
||||
localparam LOGNUMWAYS = $clog2(NUMWAYS);
|
||||
|
91
pipelined/src/cache/cachefsm.sv
vendored
91
pipelined/src/cache/cachefsm.sv
vendored
@ -1,11 +1,14 @@
|
||||
///////////////////////////////////////////
|
||||
// dcache (data cache) fsm
|
||||
//
|
||||
// Written: ross1728@gmail.com August 25, 2021
|
||||
// Implements the L1 data cache fsm
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Created: 25 August 2021
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Controller for the dcache fsm
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.14 and Table 7.1)
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
@ -29,45 +32,41 @@
|
||||
module cachefsm (
|
||||
input logic clk,
|
||||
input logic reset,
|
||||
// hazard and privilege unit
|
||||
input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
|
||||
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
||||
output logic CacheCommitted, // Cache has started bus operation that shouldn't be interrupted
|
||||
output logic CacheStall, // Cache stalls pipeline during multicycle operation
|
||||
// inputs from IEU
|
||||
input logic FlushStage,
|
||||
input logic [1:0] CacheRW,
|
||||
input logic [1:0] CacheAtomic,
|
||||
input logic FlushCache,
|
||||
input logic InvalidateCache,
|
||||
// hazard inputs
|
||||
input logic Stall,
|
||||
// Bus inputs
|
||||
input logic CacheBusAck,
|
||||
// dcache internals
|
||||
input logic CacheHit,
|
||||
input logic LineDirty,
|
||||
input logic FlushAdrFlag,
|
||||
input logic FlushWayFlag,
|
||||
input logic [1:0] CacheRW, // [1] Read, [0] Write
|
||||
input logic [1:0] CacheAtomic, // Atomic operation
|
||||
input logic FlushCache, // Flush all dirty lines back to memory
|
||||
input logic InvalidateCache, // Clear all valid bits
|
||||
// Bus controls
|
||||
input logic CacheBusAck, // Bus operation completed
|
||||
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
|
||||
// performance counter outputs
|
||||
output logic CacheMiss, // Cache miss
|
||||
output logic CacheAccess, // Cache access
|
||||
|
||||
// hazard outputs
|
||||
output logic CacheStall,
|
||||
// counter outputs
|
||||
output logic CacheMiss,
|
||||
output logic CacheAccess,
|
||||
// Bus outputs
|
||||
output logic CacheCommitted,
|
||||
output logic [1:0] CacheBusRW,
|
||||
|
||||
// dcache internals
|
||||
output logic SelAdr,
|
||||
output logic ClearValid,
|
||||
output logic ClearDirty,
|
||||
output logic SetDirty,
|
||||
output logic SetValid,
|
||||
output logic SelWriteback,
|
||||
output logic LRUWriteEn,
|
||||
output logic SelFlush,
|
||||
output logic FlushAdrCntEn,
|
||||
output logic FlushWayCntEn,
|
||||
output logic FlushCntRst,
|
||||
output logic SelFetchBuffer,
|
||||
output logic CacheEn
|
||||
// cache internals
|
||||
input logic CacheHit, // Exactly 1 way hits
|
||||
input logic LineDirty, // The selected line and way is dirty
|
||||
input logic FlushAdrFlag, // On last set of a cache flush
|
||||
input logic FlushWayFlag, // On the last way for any set of a cache flush
|
||||
output logic SelAdr, // [0] SRAM reads from NextAdr, [1] SRAM reads from PAdr
|
||||
output logic ClearValid, // Clear the valid bit in the selected way and set
|
||||
output logic SetValid, // Set the dirty bit in the selected way and set
|
||||
output logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||
output logic SetDirty, // Set the dirty bit in the selected way and set
|
||||
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||
output logic LRUWriteEn, // Update the LRU state
|
||||
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
output logic FlushAdrCntEn, // Enable the counter for Flush Adr
|
||||
output logic FlushWayCntEn, // Enable the way counter during a flush
|
||||
output logic FlushCntRst, // Reset both flush counters
|
||||
output logic SelFetchBuffer, // Bypass the SRAM for a load hit by directly using the read data from the ahbcacheinterface's FetchBuffer
|
||||
output logic CacheEn // Enable the cache memory arrays. Disable hold read data constant
|
||||
);
|
||||
|
||||
logic resetDelay;
|
||||
@ -114,8 +113,6 @@ module cachefsm (
|
||||
case (CurrState)
|
||||
STATE_READY: if(InvalidateCache) NextState = STATE_READY;
|
||||
else if(FlushCache) NextState = STATE_FLUSH;
|
||||
// Delayed LRU update. Cannot check if victim line is dirty on this cycle.
|
||||
// To optimize do the fetch first, then eviction if necessary.
|
||||
else if(AnyMiss & ~LineDirty) NextState = STATE_FETCH;
|
||||
else if(AnyMiss & LineDirty) NextState = STATE_WRITEBACK;
|
||||
else NextState = STATE_READY;
|
||||
@ -128,11 +125,11 @@ module cachefsm (
|
||||
else NextState = STATE_WRITEBACK;
|
||||
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
|
||||
STATE_FLUSH: if(LineDirty) NextState = STATE_FLUSH_WRITEBACK;
|
||||
else if (FlushFlag) NextState = STATE_READ_HOLD;
|
||||
else NextState = STATE_FLUSH;
|
||||
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
|
||||
else if(CacheBusAck) NextState = STATE_READ_HOLD;
|
||||
else NextState = STATE_FLUSH_WRITEBACK;
|
||||
else if (FlushFlag) NextState = STATE_READ_HOLD;
|
||||
else NextState = STATE_FLUSH;
|
||||
STATE_FLUSH_WRITEBACK: if(CacheBusAck & ~FlushFlag) NextState = STATE_FLUSH;
|
||||
else if(CacheBusAck) NextState = STATE_READ_HOLD;
|
||||
else NextState = STATE_FLUSH_WRITEBACK;
|
||||
default: NextState = STATE_READY;
|
||||
endcase
|
||||
end
|
||||
@ -174,7 +171,7 @@ module cachefsm (
|
||||
assign CacheBusRW[0] = (CurrState == STATE_READY & AnyMiss & LineDirty) |
|
||||
(CurrState == STATE_WRITEBACK & ~CacheBusAck) |
|
||||
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck);
|
||||
// **** can this be simplified?
|
||||
|
||||
assign SelAdr = (CurrState == STATE_READY & (StoreAMO | AnyMiss)) | // changes if store delay hazard removed
|
||||
(CurrState == STATE_FETCH) |
|
||||
(CurrState == STATE_WRITEBACK) |
|
||||
|
47
pipelined/src/cache/cacheway.sv
vendored
47
pipelined/src/cache/cacheway.sv
vendored
@ -1,11 +1,14 @@
|
||||
///////////////////////////////////////////
|
||||
// cacheway
|
||||
//
|
||||
// Written: ross1728@gmail.com July 07, 2021
|
||||
// Implements the data, tag, valid, dirty, and replacement bits.
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Created: 7 July 2021
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement.
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.11)
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
@ -29,28 +32,28 @@
|
||||
module cacheway #(parameter NUMLINES=512, LINELEN = 256, TAGLEN = 26,
|
||||
OFFSETLEN = 5, INDEXLEN = 9, DIRTY_BITS = 1) (
|
||||
input logic clk,
|
||||
input logic CacheEn,
|
||||
input logic reset,
|
||||
input logic [$clog2(NUMLINES)-1:0] CAdr,
|
||||
input logic [`PA_BITS-1:0] PAdr,
|
||||
input logic [LINELEN-1:0] LineWriteData,
|
||||
input logic SetValid,
|
||||
input logic ClearValid,
|
||||
input logic SetDirty,
|
||||
input logic ClearDirty,
|
||||
input logic SelWriteback,
|
||||
input logic SelFlush,
|
||||
input logic VictimWay,
|
||||
input logic FlushWay,
|
||||
input logic InvalidateCache,
|
||||
input logic FlushStage,
|
||||
input logic [LINELEN/8-1:0] LineByteMask,
|
||||
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
|
||||
input logic CacheEn, // Enable the cache memory arrays. Disable hold read data constant
|
||||
input logic [$clog2(NUMLINES)-1:0] CAdr, // Cache address, the output of the address select mux, NextAdr, PAdr, or FlushAdr
|
||||
input logic [`PA_BITS-1:0] PAdr, // Physical address
|
||||
input logic [LINELEN-1:0] LineWriteData, // Final data written to cache (D$ only)
|
||||
input logic SetValid, // Set the dirty bit in the selected way and set
|
||||
input logic ClearValid, // Clear the valid bit in the selected way and set
|
||||
input logic SetDirty, // Set the dirty bit in the selected way and set
|
||||
input logic ClearDirty, // Clear the dirty bit in the selected way and set
|
||||
input logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
|
||||
input logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
|
||||
input logic VictimWay, // LRU selected this way as victim to evict
|
||||
input logic FlushWay, // This way is selected for flush and possible writeback if dirty
|
||||
input logic InvalidateCache,//Clear all valid bits
|
||||
input logic [LINELEN/8-1:0] LineByteMask, // Final byte enables to cache (D$ only)
|
||||
|
||||
output logic [LINELEN-1:0] ReadDataLineWay,
|
||||
output logic HitWay,
|
||||
output logic ValidWay,
|
||||
output logic DirtyWay,
|
||||
output logic [TAGLEN-1:0] TagWay);
|
||||
output logic [LINELEN-1:0] ReadDataLineWay,// This way's read data if valid
|
||||
output logic HitWay, // This way hits
|
||||
output logic ValidWay, // This way is valid
|
||||
output logic DirtyWay, // This way is dirty
|
||||
output logic [TAGLEN-1:0] TagWay); // THis way's tag if valid
|
||||
|
||||
localparam integer WORDSPERLINE = LINELEN/`XLEN;
|
||||
localparam integer BYTESPERLINE = LINELEN/8;
|
||||
|
19
pipelined/src/cache/subcachelineread.sv
vendored
19
pipelined/src/cache/subcachelineread.sv
vendored
@ -1,11 +1,14 @@
|
||||
///////////////////////////////////////////
|
||||
// subcachelineread
|
||||
//
|
||||
// Written: Ross Thompson ross1728@gmail.com February 04, 2022
|
||||
// Muxes the cache line downto the word size. Also include possilbe save/restore registers/muxes.
|
||||
// Written: Ross Thompson ross1728@gmail.com
|
||||
// Created: 4 February 2022
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Controller for the dcache fsm
|
||||
// Purpose: Muxes the cache line downto the word size. Also include possilbe save/restore registers/muxes.
|
||||
//
|
||||
// Documentation: RISC-V System on Chip Design Chapter 7
|
||||
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
@ -26,10 +29,12 @@
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module subcachelineread #(parameter LINELEN, WORDLEN, MUXINTERVAL)(
|
||||
input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr,
|
||||
input logic [LINELEN-1:0] ReadDataLine,
|
||||
output logic [WORDLEN-1:0] ReadDataWord
|
||||
module subcachelineread #(parameter LINELEN, WORDLEN,
|
||||
parameter MUXINTERVAL // The number of bits between mux. Set to 16 for I$ to support compressed. Set to `LLEN for D$
|
||||
)(
|
||||
input logic [$clog2(LINELEN/8) - $clog2(MUXINTERVAL/8) - 1 : 0] PAdr, // Physical address
|
||||
input logic [LINELEN-1:0] ReadDataLine,// Read data of the whole cacheline
|
||||
output logic [WORDLEN-1:0] ReadDataWord // read data of selected word.
|
||||
);
|
||||
|
||||
localparam WORDSPERLINE = LINELEN/MUXINTERVAL;
|
||||
|
@ -1,14 +1,17 @@
|
||||
///////////////////////////////////////////
|
||||
// 1 port sram.
|
||||
//
|
||||
// Written: ross1728@gmail.com May 3, 2021
|
||||
// Written: ross1728@gmail.com
|
||||
// Created: 3 May 2021
|
||||
// Modified: 20 January 2023
|
||||
//
|
||||
// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement.
|
||||
// Basic sram with 1 read write port.
|
||||
// When clk rises Addr and LineWriteData are sampled.
|
||||
// Following the clk edge read data is output from the sampled Addr.
|
||||
// Write
|
||||
//
|
||||
// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement.
|
||||
//
|
||||
// Documentation:
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
|
||||
|
@ -38,13 +38,13 @@ module bpred (
|
||||
input logic [`XLEN-1:0] PCNextF, // Next Fetch Address
|
||||
input logic [`XLEN-1:0] PCPlus2or4F, // PCF+2/4
|
||||
output logic [`XLEN-1:0] PCNext1F, // Branch Predictor predicted or corrected fetch address on miss prediction
|
||||
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage.
|
||||
output logic [`XLEN-1:0] NextValidPCE, // Address of next valid instruction after the instruction in the Memory stage
|
||||
|
||||
// Update Predictor
|
||||
input logic [`XLEN-1:0] PCF, // Fetch stage instruction address.
|
||||
input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took.
|
||||
input logic [`XLEN-1:0] PCE, // Execution stage instruction address.
|
||||
input logic [`XLEN-1:0] PCM, // Memory stage instruction address.
|
||||
input logic [`XLEN-1:0] PCF, // Fetch stage instruction address
|
||||
input logic [`XLEN-1:0] PCD, // Decode stage instruction address. Also the address the branch predictor took
|
||||
input logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
||||
input logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
||||
|
||||
// Branch and jump outcome
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
@ -53,11 +53,11 @@ module bpred (
|
||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
||||
|
||||
// Report branch prediction status
|
||||
output logic BPPredWrongE, // Prediction is wrong.
|
||||
output logic DirPredictionWrongM, // Prediction direction is wrong.
|
||||
output logic BTBPredPCWrongM, // Prediction target wrong.
|
||||
output logic RASPredPCWrongM, // RAS prediction is wrong.
|
||||
output logic PredictionInstrClassWrongM // Class prediction is wrong.
|
||||
output logic BPPredWrongE, // Prediction is wrong
|
||||
output logic DirPredictionWrongM, // Prediction direction is wrong
|
||||
output logic BTBPredPCWrongM, // Prediction target wrong
|
||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||
output logic PredictionInstrClassWrongM // Class prediction is wrong
|
||||
);
|
||||
|
||||
logic BTBValidF;
|
||||
|
@ -28,92 +28,104 @@
|
||||
`include "wally-config.vh"
|
||||
|
||||
module ifu (
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
input logic clk, reset,
|
||||
input logic StallF, StallD, StallE, StallM, StallW,
|
||||
input logic FlushD, FlushE, FlushM, FlushW,
|
||||
(* mark_debug = "true" *) output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
|
||||
// Command from CPU
|
||||
input logic InvalidateICacheM, // Clears all instruction cache valid bits
|
||||
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
|
||||
// Bus interface
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA,
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUHADDR,
|
||||
(* mark_debug = "true" *) output logic IFUStallF,
|
||||
(* mark_debug = "true" *) output logic [2:0] IFUHBURST,
|
||||
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS,
|
||||
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE,
|
||||
(* mark_debug = "true" *) output logic IFUHWRITE,
|
||||
(* mark_debug = "true" *) input logic IFUHREADY,
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
|
||||
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
|
||||
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
|
||||
(* mark_debug = "true" *) input logic IFUHREADY, // Bus ready from IFU to EBU
|
||||
(* mark_debug = "true" *) output logic IFUHWRITE, // Bus write operation from IFU to EBU
|
||||
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
|
||||
(* mark_debug = "true" *) output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
|
||||
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
|
||||
|
||||
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF, // Fetch stage instruction address
|
||||
// Execute
|
||||
output logic [`XLEN-1:0] PCLinkE,
|
||||
input logic PCSrcE,
|
||||
input logic [`XLEN-1:0] IEUAdrE,
|
||||
output logic [`XLEN-1:0] PCE,
|
||||
output logic BPPredWrongE,
|
||||
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
|
||||
input logic PCSrcE, // Executation stage branch is taken
|
||||
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
|
||||
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
|
||||
output logic BPPredWrongE, // Prediction is wrong
|
||||
// Mem
|
||||
output logic CommittedF,
|
||||
input logic [`XLEN-1:0] UnalignedPCNextF,
|
||||
output logic [`XLEN-1:0] PCNext2F,
|
||||
input logic CSRWriteFenceM,
|
||||
input logic InvalidateICacheM,
|
||||
output logic [31:0] InstrD, InstrM,
|
||||
output logic [`XLEN-1:0] PCM,
|
||||
// branch predictor
|
||||
output logic [3:0] InstrClassM,
|
||||
output logic DirPredictionWrongM,
|
||||
output logic BTBPredPCWrongM,
|
||||
output logic RASPredPCWrongM,
|
||||
output logic PredictionInstrClassWrongM,
|
||||
// Faults
|
||||
input logic IllegalBaseInstrFaultD,
|
||||
output logic InstrPageFaultF,
|
||||
output logic IllegalIEUInstrFaultD,
|
||||
output logic InstrMisalignedFaultM,
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] PTE,
|
||||
input logic [1:0] PageType,
|
||||
input logic [`XLEN-1:0] SATP_REGW,
|
||||
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
|
||||
input logic [1:0] STATUS_MPP,
|
||||
input logic ITLBWriteF, sfencevmaM,
|
||||
output logic ITLBMissF, InstrDAPageFaultF,
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
|
||||
output logic InstrAccessFaultF,
|
||||
output logic ICacheAccess,
|
||||
output logic ICacheMiss
|
||||
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
|
||||
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
|
||||
output logic [`XLEN-1:0] PCNext2F, // Selected PC between branch prediction and next valid PC if CSRWriteFence
|
||||
output logic [31:0] InstrD, // The decoded instruction in Decode stage
|
||||
output logic [31:0] InstrM, // The decoded instruction in Memory stage
|
||||
output logic [`XLEN-1:0] PCM, // Memory stage instruction address
|
||||
// branch predictor
|
||||
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
|
||||
output logic DirPredictionWrongM, // Prediction direction is wrong
|
||||
output logic BTBPredPCWrongM, // Prediction target wrong
|
||||
output logic RASPredPCWrongM, // RAS prediction is wrong
|
||||
output logic PredictionInstrClassWrongM, // Class prediction is wrong
|
||||
// Faults
|
||||
input logic IllegalBaseInstrFaultD, // Illegal non-compressed instruction
|
||||
output logic InstrPageFaultF, // Instruction page fault
|
||||
output logic IllegalIEUInstrFaultD, // Illegal instruction including compressed
|
||||
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
// mmu management
|
||||
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
|
||||
input logic [`XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
|
||||
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
|
||||
input logic ITLBWriteF, // Writes PTE and PageType to ITLB
|
||||
input logic [`XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
|
||||
input logic STATUS_MXR, // Status CSR: make executable page readable
|
||||
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
|
||||
input logic STATUS_MPRV, // Status CSR: modify machine privilege
|
||||
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
|
||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
|
||||
output logic InstrDAPageFaultF, // ITLB hit needs to update dirty or access bits
|
||||
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP configuration from privileged unit
|
||||
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], // PMP address from privileged unit
|
||||
output logic InstrAccessFaultF, // Instruction access fault
|
||||
output logic ICacheAccess, // Report I$ read to performance counters
|
||||
output logic ICacheMiss // Report I$ miss to performance counters
|
||||
);
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCNextF;
|
||||
logic BranchMisalignedFaultE;
|
||||
logic [`XLEN-1:0] PCPlus2or4F, PCLinkD;
|
||||
logic [`XLEN-1:2] PCPlus4F;
|
||||
logic CompressedF;
|
||||
logic [31:0] InstrRawD, InstrRawF, IROMInstrF, ICacheInstrF;
|
||||
logic [31:0] FinalInstrRawF;
|
||||
logic [1:0] IFURWF;
|
||||
|
||||
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
|
||||
(* mark_debug = "true" *) logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
|
||||
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
|
||||
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
|
||||
logic [`XLEN-1:0] PCNextFSpill; // Next PCF after possible + 2 to handle spill
|
||||
logic [`XLEN-1:0] PCFSpill; // PCF with possible + 2 to handle spill
|
||||
logic [`XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
|
||||
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
|
||||
logic [`XLEN-1:0] PCD; // Decode stage instruction address
|
||||
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
|
||||
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
|
||||
logic [`XLEN+1:0] PCFExt; //
|
||||
|
||||
logic [31:0] IROMInstrF; // Instruction from the IROM
|
||||
logic [31:0] ICacheInstrF; // Instruction from the I$
|
||||
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
|
||||
logic CompressedF; // The fetched instruction is compressed
|
||||
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
|
||||
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
|
||||
|
||||
logic [31:0] InstrE;
|
||||
logic [`XLEN-1:0] PCD;
|
||||
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10
|
||||
logic [31:0] InstrE; // Instruction in the Execution stage
|
||||
logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush
|
||||
|
||||
localparam [31:0] nop = 32'h00000013; // instruction for NOP
|
||||
logic [31:0] NextInstrD, NextInstrE;
|
||||
|
||||
logic [`XLEN-1:0] NextValidPCE;
|
||||
|
||||
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PCPF; // used to either truncate or expand PCPF and PCNextF into `PA_BITS width.
|
||||
logic [`XLEN+1:0] PCFExt;
|
||||
|
||||
logic CacheableF;
|
||||
logic [`XLEN-1:0] PCNextFSpill;
|
||||
logic [`XLEN-1:0] PCFSpill;
|
||||
logic SelNextSpillF;
|
||||
logic ICacheFetchLine;
|
||||
logic BusStall;
|
||||
logic ICacheStallF, IFUCacheBusStallD;
|
||||
logic GatedStallD;
|
||||
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF;
|
||||
logic CacheableF; // PMA indicates isntruction address is cacheable
|
||||
logic SelNextSpillF; // In a spill, stall pipeline and gate local stallF
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic ICacheStallF; // I$ busy with multicycle operation
|
||||
logic IFUCacheBusStallD; // EIther I$ or bus busy with multicycle operation
|
||||
logic GatedStallD; // StallD gated by selected next spill
|
||||
// branch predictor signal
|
||||
logic [`XLEN-1:0] PCNext1F, PCNext0F;
|
||||
logic BusCommittedF, CacheCommittedF;
|
||||
logic SelIROM;
|
||||
logic [`XLEN-1:0] PCNext1F; // Branch predictor next PCF
|
||||
logic BusCommittedF; // Bus memory operation in flight, delay interrupts
|
||||
logic CacheCommittedF; // I$ memory operation started, delay interrupts
|
||||
logic SelIROM; // PMA indicates instruction address is in the IROM
|
||||
|
||||
assign PCFExt = {2'b00, PCFSpill};
|
||||
|
||||
@ -202,13 +214,12 @@ module ifu (
|
||||
localparam integer LOGBWPL = `ICACHE ? $clog2(WORDSPERLINE) : 1;
|
||||
if(`ICACHE) begin : icache
|
||||
localparam integer LINELEN = `ICACHE ? `ICACHE_LINELENINBITS : `XLEN;
|
||||
localparam integer LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
|
||||
localparam integer LLENPOVERAHBW = `LLEN / `AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
|
||||
logic [LINELEN-1:0] FetchBuffer;
|
||||
logic [`PA_BITS-1:0] ICacheBusAdr;
|
||||
logic ICacheBusAck;
|
||||
logic [1:0] CacheBusRW, BusRW, CacheRWF;
|
||||
|
||||
//assign BusRW = IFURWF & ~{IgnoreRequest, IgnoreRequest} & ~{CacheableF, CacheableF} & ~{SelIROM, SelIROM};
|
||||
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
|
||||
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
|
||||
cache #(.LINELEN(`ICACHE_LINELENINBITS),
|
||||
@ -257,8 +268,7 @@ module ifu (
|
||||
if(`IROM_SUPPORTED) mux2 #(32) UnCachedDataMux2(FetchBuffer, IROMInstrF, SelIROM, InstrRawF);
|
||||
else assign InstrRawF = FetchBuffer;
|
||||
assign IFUHBURST = 3'b0;
|
||||
assign {ICacheFetchLine, ICacheStallF, FinalInstrRawF} = '0;
|
||||
assign {ICacheMiss, ICacheAccess} = '0;
|
||||
assign {ICacheMiss, ICacheAccess, ICacheStallF} = '0;
|
||||
end
|
||||
end else begin : nobus // block: bus
|
||||
assign {BusStall, CacheCommittedF} = '0;
|
||||
@ -324,7 +334,6 @@ module ifu (
|
||||
mux2 #(`XLEN) pcmux1(.d0(PCPlus2or4F), .d1(IEUAdrE), .s(PCSrcE), .y(PCNext1F));
|
||||
assign BPPredWrongE = PCSrcE;
|
||||
assign {InstrClassM, DirPredictionWrongM, BTBPredPCWrongM, RASPredPCWrongM, PredictionInstrClassWrongM} = '0;
|
||||
assign PCNext0F = PCPlus2or4F;
|
||||
assign NextValidPCE = PCE;
|
||||
end
|
||||
|
||||
@ -359,6 +368,7 @@ module ifu (
|
||||
flopenr #(1) InstrMisalginedReg(clk, reset, ~StallM, BranchMisalignedFaultE, InstrMisalignedFaultM);
|
||||
|
||||
// Instruction and PC/PCLink pipeline registers
|
||||
// Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0.
|
||||
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
|
||||
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
|
||||
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
|
||||
|
@ -34,7 +34,7 @@
|
||||
module lsu (
|
||||
input logic clk, reset,
|
||||
input logic StallM, FlushM, StallW, FlushW,
|
||||
output logic LSUStallM, // LSU stalls pipeline during a multicycle operation.
|
||||
output logic LSUStallM, // LSU stalls pipeline during a multicycle operation
|
||||
// connected to cpu (controls)
|
||||
input logic [1:0] MemRWM, // Read/Write control
|
||||
input logic [2:0] Funct3M, // Size of memory operation
|
||||
@ -53,7 +53,7 @@ module lsu (
|
||||
// cpu privilege
|
||||
input logic [1:0] PrivilegeModeW, // Current privilege mode
|
||||
input logic BigEndianM, // Swap byte order to big endian
|
||||
input logic sfencevmaM, // Virtual memory address fence
|
||||
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
|
||||
// fpu
|
||||
input logic [`FLEN-1:0] FWriteDataM, // Write data from FPU
|
||||
input logic FpLoadStoreM, // Selects FPU as store for write data
|
||||
@ -103,7 +103,7 @@ module lsu (
|
||||
|
||||
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
|
||||
|
||||
logic DCacheStallW; // D$ busy with multicycle operation
|
||||
logic DCacheStallM; // D$ busy with multicycle operation
|
||||
logic BusStall; // Bus interface busy with multicycle operation
|
||||
logic HPTWStall; // HPTW busy with multicycle operation
|
||||
|
||||
@ -126,7 +126,7 @@ module lsu (
|
||||
logic [(`LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write
|
||||
|
||||
logic DTLBMissM; // DTLB miss causes HPTW walk
|
||||
logic DTLBWriteM; // Writes PTE to DTLB
|
||||
logic DTLBWriteM; // Writes PTE and PageType to DTLB
|
||||
logic DataDAPageFaultM; // DTLB hit needs to update dirty or access bits
|
||||
logic LSULoadAccessFaultM; // Load acces fault
|
||||
logic LSUStoreAmoAccessFaultM; // Store access fault
|
||||
@ -152,7 +152,7 @@ module lsu (
|
||||
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
|
||||
hptw hptw(.clk, .reset, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
|
||||
.DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
|
||||
.FlushW, .DCacheStallW, .SATP_REGW, .PCF,
|
||||
.FlushW, .DCacheStallM, .SATP_REGW, .PCF,
|
||||
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
|
||||
.ReadDataM(ReadDataM[`XLEN-1:0]), // ReadDataM is LLEN, but HPTW only needs XLEN
|
||||
.WriteDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M,
|
||||
@ -179,7 +179,7 @@ module lsu (
|
||||
// the trap module.
|
||||
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
|
||||
assign GatedStallW = StallW & ~SelHPTW;
|
||||
assign LSUStallM = DCacheStallW | HPTWStall | BusStall;
|
||||
assign LSUStallM = DCacheStallM | HPTWStall | BusStall;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// MMU and misalignment fault logic required if privileged unit exists
|
||||
@ -267,7 +267,7 @@ module lsu (
|
||||
.FlushCache(FlushDCacheM), .NextAdr(IEUAdrE[11:0]), .PAdr(PAdrM),
|
||||
.ByteMask(ByteMaskM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
|
||||
.CacheWriteData(LSUWriteDataM), .SelHPTW,
|
||||
.CacheStall(DCacheStallW), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
|
||||
.CacheCommitted(DCacheCommittedM),
|
||||
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
|
||||
.FetchBuffer, .CacheBusRW,
|
||||
@ -307,14 +307,14 @@ module lsu (
|
||||
if(`DTIM_SUPPORTED) mux2 #(`XLEN) ReadDataMux2(FetchBuffer, DTIMReadDataWordM, SelDTIM, ReadDataWordMuxM);
|
||||
else assign ReadDataWordMuxM = FetchBuffer[`XLEN-1:0];
|
||||
assign LSUHBURST = 3'b0;
|
||||
assign {DCacheStallW, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||
assign {DCacheStallM, DCacheCommittedM, DCacheMiss, DCacheAccess} = '0;
|
||||
end
|
||||
end else begin: nobus // block: bus, only DTIM
|
||||
assign LSUHWDATA = '0;
|
||||
assign ReadDataWordMuxM = DTIMReadDataWordM;
|
||||
assign {BusStall, BusCommittedM} = '0;
|
||||
assign {DCacheMiss, DCacheAccess} = '0;
|
||||
assign {DCacheStallW, DCacheCommittedM} = '0;
|
||||
assign {DCacheStallM, DCacheCommittedM} = '0;
|
||||
end
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -43,7 +43,7 @@ module hptw (
|
||||
input logic [1:0] PrivilegeModeW,
|
||||
input logic [`XLEN-1:0] ReadDataM, // page table entry from LSU
|
||||
input logic [`XLEN-1:0] WriteDataM,
|
||||
input logic DCacheStallW, // stall from LSU
|
||||
input logic DCacheStallM, // stall from LSU
|
||||
input logic [2:0] Funct3M,
|
||||
input logic [6:0] Funct7M,
|
||||
input logic ITLBMissF,
|
||||
@ -114,7 +114,7 @@ module hptw (
|
||||
|
||||
// State flops
|
||||
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissOrDAFaultM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheStallW | UpdatePTE;
|
||||
assign PRegEn = HPTWRW[1] & ~DCacheStallM | UpdatePTE;
|
||||
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, NextPTE, PTE); // Capture page table entry from data cache
|
||||
|
||||
// Assign PTE descriptors common across all XLEN values
|
||||
@ -248,24 +248,24 @@ module hptw (
|
||||
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
|
||||
else NextWalkerState = IDLE;
|
||||
L3_ADR: NextWalkerState = L3_RD; // first access in SV48
|
||||
L3_RD: if (DCacheStallW) NextWalkerState = L3_RD;
|
||||
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
|
||||
else NextWalkerState = L2_ADR;
|
||||
L2_ADR: if (InitialWalkerState == L2_ADR | ValidNonLeafPTE) NextWalkerState = L2_RD; // first access in SV39
|
||||
else NextWalkerState = LEAF;
|
||||
L2_RD: if (DCacheStallW) NextWalkerState = L2_RD;
|
||||
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
|
||||
else NextWalkerState = L1_ADR;
|
||||
L1_ADR: if (InitialWalkerState == L1_ADR | ValidNonLeafPTE) NextWalkerState = L1_RD; // first access in SV32
|
||||
else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
L1_RD: if (DCacheStallW) NextWalkerState = L1_RD;
|
||||
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
|
||||
else NextWalkerState = L0_ADR;
|
||||
L0_ADR: if (ValidNonLeafPTE) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
L0_RD: if (DCacheStallW) NextWalkerState = L0_RD;
|
||||
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
|
||||
else NextWalkerState = LEAF;
|
||||
LEAF: if (`HPTW_WRITES_SUPPORTED & DAPageFault) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = IDLE;
|
||||
UPDATE_PTE: if(DCacheStallW) NextWalkerState = UPDATE_PTE;
|
||||
UPDATE_PTE: if(DCacheStallM) NextWalkerState = UPDATE_PTE;
|
||||
else NextWalkerState = LEAF;
|
||||
default: NextWalkerState = IDLE; // should never be reached
|
||||
endcase // case (WalkerState)
|
||||
|
@ -1,362 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// SDC.sv
|
||||
//
|
||||
// Written: Ross Thompson September 22, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: SDC interface to AHBLite BUS.
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
`define SDCCLKDIV -8'd3
|
||||
|
||||
module SDC (
|
||||
input logic HCLK,
|
||||
input logic HRESETn,
|
||||
input logic HSELSDC,
|
||||
input logic [4:0] HADDR,
|
||||
input logic HWRITE,
|
||||
input logic HREADY,
|
||||
input logic [1:0] HTRANS,
|
||||
input logic [`XLEN-1:0] HWDATA,
|
||||
output logic [`XLEN-1:0] HREADSDC,
|
||||
output logic HRESPSDC,
|
||||
output logic HREADYSDC,
|
||||
|
||||
//sd card interface
|
||||
// place the tristate drivers at the top. this level
|
||||
// will use dedicated 1 direction ports.
|
||||
output logic SDCCmdOut,
|
||||
input logic SDCCmdIn,
|
||||
output logic SDCCmdOE,
|
||||
input logic [3:0] SDCDatIn,
|
||||
output logic SDCCLK,
|
||||
// interrupt to PLIC
|
||||
output logic SDCIntM
|
||||
);
|
||||
|
||||
logic InitTrans;
|
||||
logic RegRead;
|
||||
logic RegWrite;
|
||||
logic [4:0] HADDRDelay;
|
||||
|
||||
|
||||
// Register outputs
|
||||
logic signed [7:0] CLKDiv;
|
||||
logic [2:0] Command;
|
||||
logic [63:9] Address;
|
||||
|
||||
|
||||
logic SDCDone;
|
||||
|
||||
logic [2:0] ErrorCode;
|
||||
logic InvalidCommand;
|
||||
logic SDCBusy;
|
||||
|
||||
logic StartCLKDivUpdate;
|
||||
logic CLKDivUpdateEn;
|
||||
logic SDCCLKEN;
|
||||
logic CLKGate;
|
||||
logic SDCCLKIn;
|
||||
|
||||
|
||||
logic SDCDataValid;
|
||||
logic [`XLEN-1:0] SDCReadData;
|
||||
logic [`XLEN-1:0] SDCReadDataPreNibbleSwap;
|
||||
logic [`XLEN-1:0] SDCWriteData;
|
||||
logic FatalError;
|
||||
|
||||
logic [4095:0] ReadData512Byte;
|
||||
logic [`XLEN-1:0] ReadData512ByteWords [4096/`XLEN-1:0] ;
|
||||
logic SDCInitialized;
|
||||
logic SDCRestarting;
|
||||
logic SDCLast;
|
||||
|
||||
logic [$clog2(4096/`XLEN)-1:0] WordCount;
|
||||
logic WordCountRst;
|
||||
logic [5:0] Status;
|
||||
logic CommandCompleted;
|
||||
logic ReadDone;
|
||||
|
||||
|
||||
|
||||
genvar index;
|
||||
|
||||
assign HRESPSDC = 1'b0;
|
||||
|
||||
// registers
|
||||
//| Offset | Name | Size | Purpose |
|
||||
//|--------+---------+--------+------------------------------------------------|
|
||||
//| 0x0 | CLKDiv | 4 | Divide HCLK to produce SDCLK |
|
||||
//| 0x4 | Status | 4 | Provide status to software |
|
||||
//| 0x8 | Control | 4 | Send commands to SDC |
|
||||
//| 0xC | Size | 4 | Size of data command (only 512 byte supported) |
|
||||
//| 0x10 | address | 8 | address of operation |
|
||||
//| 0x18 | data | XLEN/8 | Data Bus interface |
|
||||
|
||||
// Status contains
|
||||
// Status[0] initialized
|
||||
// Status[1] Busy on read
|
||||
// Status[2] invalid command
|
||||
// Status[5:3] error code
|
||||
|
||||
// control contains 3 bit command
|
||||
// control[2:0]
|
||||
// 000 nop op
|
||||
// xx1 initialize
|
||||
// 010 Write no implemented
|
||||
// 100 Read
|
||||
// 110 Atomic read/write not implemented
|
||||
|
||||
// size is fixed to 512. Read only
|
||||
|
||||
|
||||
// Currently using a mailbox style interface. Data is passed through the Data register (0x10)
|
||||
// The card will support 3 operations
|
||||
// 1. initialize
|
||||
// 2. read
|
||||
// 3. write
|
||||
// all read and write operations will occur on 512 bytes (4096 bits) of data
|
||||
// starting at the 512 byte aligned address in the address register This register
|
||||
// is the byte address.
|
||||
|
||||
// currently does not support writes
|
||||
|
||||
assign InitTrans = HREADY & HSELSDC & HTRANS[1];
|
||||
//assign RegRead = InitTrans & ~HWRITE;
|
||||
// register resolve combo loop
|
||||
flopr #(1) RegReadReg(HCLK, ~HRESETn, InitTrans & ~HWRITE, RegRead);
|
||||
// AHBLite Spec has write data 1 cycle after write command
|
||||
flopr #(1) RegWriteReg(HCLK, ~HRESETn, InitTrans & HWRITE, RegWrite);
|
||||
|
||||
flopenr #(5) HADDRReg(HCLK, ~HRESETn, InitTrans, HADDR, HADDRDelay);
|
||||
|
||||
assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite;
|
||||
|
||||
flopenl #(8) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[7:0], `SDCCLKDIV, CLKDiv);
|
||||
|
||||
// Control reg
|
||||
flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (CommandCompleted),
|
||||
CommandCompleted ? '0 : HWDATA[2:0], '0, Command);
|
||||
|
||||
if (`XLEN == 64) begin
|
||||
flopenr #(64-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
|
||||
HWDATA[`XLEN-1:9], Address);
|
||||
end else begin
|
||||
flopenr #(32-9) AddressLowReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite),
|
||||
HWDATA[`XLEN-1:9], Address[31:9]);
|
||||
flopenr #(32) AddressHighReg(HCLK, ~HRESETn, (HADDRDelay == 'h14 & RegWrite),
|
||||
HWDATA, Address[63:32]);
|
||||
end
|
||||
|
||||
flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite),
|
||||
HWDATA, SDCWriteData);
|
||||
|
||||
assign InvalidCommand = (Command[2] | Command[1]) & Command[0];
|
||||
|
||||
assign Status = {ErrorCode, InvalidCommand, SDCBusy, SDCInitialized};
|
||||
|
||||
if(`XLEN == 64) begin
|
||||
always_comb
|
||||
case(HADDRDelay[4:0])
|
||||
'h0: HREADSDC = {24'b0, CLKDiv, 26'b0, Status};
|
||||
'h4: HREADSDC = {26'b0, Status, 29'b0, Command};
|
||||
'h8: HREADSDC = {29'b0, Command, 32'h200};
|
||||
'hC: HREADSDC = {32'h200, Address[31:9], 9'b0};
|
||||
'h10: HREADSDC = {Address, 9'b0};
|
||||
'h18: HREADSDC = SDCReadData;
|
||||
default: HREADSDC = {24'b0, CLKDiv, 26'b0, Status};
|
||||
endcase // case (HADDRDelay[4:0])
|
||||
end else begin
|
||||
always_comb
|
||||
case(HADDRDelay[4:0])
|
||||
'h0: HREADSDC = {24'b0, CLKDiv};
|
||||
'h4: HREADSDC = {26'b0, Status};
|
||||
'h8: HREADSDC = {29'b0, Command};
|
||||
'hC: HREADSDC = 'h200;
|
||||
'h10: HREADSDC = {Address[31:9], 9'b0};
|
||||
'h14: HREADSDC = Address[63:32];
|
||||
'h18: HREADSDC = SDCReadData[31:0];
|
||||
default: HREADSDC = {24'b0, CLKDiv};
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
for(index = 0; index < 4096/`XLEN; index++) begin
|
||||
assign ReadData512ByteWords[index] = ReadData512Byte[(index+1)*`XLEN-1:index*`XLEN];
|
||||
end
|
||||
|
||||
assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount];
|
||||
if(`XLEN == 64) begin
|
||||
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
|
||||
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
|
||||
SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44],
|
||||
SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36],
|
||||
SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
|
||||
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
|
||||
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
|
||||
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
|
||||
end else begin
|
||||
assign SDCReadData = {SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
|
||||
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
|
||||
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
|
||||
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
|
||||
end
|
||||
|
||||
flopenr #($clog2(4096/`XLEN)) WordCountReg
|
||||
(.clk(HCLK),
|
||||
.reset(~HRESETn | WordCountRst),
|
||||
.en(HADDRDelay[4:0] == 'h18 & ReadDone),
|
||||
.d(WordCount + 1'b1),
|
||||
.q(WordCount));
|
||||
|
||||
|
||||
|
||||
typedef enum {STATE_READY,
|
||||
|
||||
// clock update states
|
||||
STATE_CLK_DIV1,
|
||||
STATE_CLK_DIV2,
|
||||
STATE_CLK_DIV3,
|
||||
STATE_CLK_DIV4,
|
||||
|
||||
// restart SDC
|
||||
STATE_RESTART,
|
||||
|
||||
// SDC operation
|
||||
STATE_PROCESS_CMD,
|
||||
|
||||
STATE_READ
|
||||
} statetype;
|
||||
|
||||
|
||||
statetype CurrState, NextState;
|
||||
|
||||
always_ff @(posedge HCLK, negedge HRESETn)
|
||||
if (~HRESETn) CurrState <= STATE_READY;
|
||||
else CurrState <= NextState;
|
||||
|
||||
always_comb begin
|
||||
CLKDivUpdateEn = 1'b0;
|
||||
HREADYSDC = 1'b0;
|
||||
SDCCLKEN = 1'b1;
|
||||
WordCountRst = 1'b0;
|
||||
SDCBusy = 1'b0;
|
||||
CommandCompleted = 1'b0;
|
||||
ReadDone = 1'b0;
|
||||
|
||||
case (CurrState)
|
||||
STATE_READY : begin
|
||||
if (StartCLKDivUpdate)begin
|
||||
NextState = STATE_CLK_DIV1;
|
||||
HREADYSDC = 1'b0;
|
||||
end else if (Command[2] | Command[1]) begin
|
||||
NextState = STATE_PROCESS_CMD;
|
||||
HREADYSDC = 1'b0;
|
||||
end else if(HADDRDelay[4:0] == 'h18 & RegRead) begin
|
||||
NextState = STATE_READ;
|
||||
HREADYSDC = 1'b0;
|
||||
end else begin
|
||||
NextState = STATE_READY;
|
||||
HREADYSDC = 1'b1;
|
||||
end
|
||||
end
|
||||
STATE_CLK_DIV1: begin
|
||||
NextState = STATE_CLK_DIV2;
|
||||
SDCCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV2: begin
|
||||
NextState = STATE_CLK_DIV3;
|
||||
CLKDivUpdateEn = 1'b1;
|
||||
SDCCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV3: begin
|
||||
NextState = STATE_CLK_DIV4;
|
||||
SDCCLKEN = 1'b0;
|
||||
end
|
||||
STATE_CLK_DIV4: begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
STATE_PROCESS_CMD: begin
|
||||
HREADYSDC = 1'b1;
|
||||
WordCountRst = 1'b1;
|
||||
SDCBusy = 1'b1;
|
||||
if(SDCDataValid) begin
|
||||
NextState = STATE_READY;
|
||||
CommandCompleted = 1'b1;
|
||||
end else begin
|
||||
NextState = STATE_PROCESS_CMD;
|
||||
CommandCompleted = 1'b0;
|
||||
end
|
||||
end
|
||||
STATE_READ: begin
|
||||
NextState = STATE_READY;
|
||||
HREADYSDC = 1'b1;
|
||||
ReadDone = 1'b1;
|
||||
end
|
||||
default: begin
|
||||
NextState = STATE_READY;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// clock generation divider
|
||||
|
||||
clockgater clockgater(.E(SDCCLKEN),
|
||||
.SE(1'b0),
|
||||
.CLK(HCLK),
|
||||
.ECLK(CLKGate));
|
||||
|
||||
|
||||
clkdivider #(8) clkdivider(.i_COUNT_IN_MAX(CLKDiv),
|
||||
.i_EN(CLKDiv <= 0), // enable if < 0 (msb is 1)
|
||||
.i_CLK(CLKGate),
|
||||
.i_RST(~HRESETn | CLKDivUpdateEn),
|
||||
.o_CLK(SDCCLKIn));
|
||||
|
||||
// assign SDCCLKIn = CLKGate;
|
||||
|
||||
|
||||
// should always be 0 for real implementation, but for simulation set to 1.
|
||||
logic LimitTimers;
|
||||
assign LimitTimers = '0;
|
||||
|
||||
sd_top sd_top(.CLK(SDCCLKIn),
|
||||
.a_RST(~HRESETn),
|
||||
.i_SD_CMD(SDCCmdIn),
|
||||
.o_SD_CMD(SDCCmdOut),
|
||||
.o_SD_CMD_OE(SDCCmdOE),
|
||||
.i_SD_DAT(SDCDatIn),
|
||||
.o_SD_CLK(SDCCLK),
|
||||
.i_BLOCK_ADDR(Address[32:9]),
|
||||
.o_READY_FOR_READ(SDCInitialized),
|
||||
.o_SD_RESTARTING(SDCRestarting),
|
||||
.i_READ_REQUEST(Command[2]),
|
||||
.o_DATA_TO_CORE(),
|
||||
.ReadData(ReadData512Byte),
|
||||
.o_DATA_VALID(SDCDataValid),
|
||||
.o_LAST_NIBBLE(SDCLast),
|
||||
.o_ERROR_CODE_Q(ErrorCode),
|
||||
.o_FATAL_ERROR(FatalError),
|
||||
.i_COUNT_IN_MAX(-8'd62),
|
||||
.LIMIT_SD_TIMERS(LimitTimers)); // *** must change this to 0 for real hardware.
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -1,43 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// counter.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson
|
||||
// Converted to SystemVerilog.
|
||||
//
|
||||
// Purpose: basic up counter
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module SDCcounter #(parameter integer WIDTH=32) (
|
||||
input logic [WIDTH-1:0] CountIn,
|
||||
output logic [WIDTH-1:0] CountOut,
|
||||
input logic Load,
|
||||
input logic Enable,
|
||||
input logic clk,
|
||||
input logic reset
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] NextCount;
|
||||
|
||||
assign NextCount = Load ? CountIn : (CountOut + 1'b1);
|
||||
flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut);
|
||||
endmodule
|
||||
|
||||
|
@ -1,105 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// clock divider.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 18, 2021
|
||||
// Converted to system verilog.
|
||||
//
|
||||
// Purpose: clock divider for sd flash
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module clkdivider #(parameter integer g_COUNT_WIDTH) (
|
||||
input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX, //((Divide by value)/2) - 1
|
||||
input logic i_EN, //Enable frequency division of i_clk
|
||||
input logic i_CLK, // 1.2 GHz Base clock
|
||||
input logic i_RST, // at start: clears flip flop and loads counter,
|
||||
// i_RST must NOT be a_RST, it needs to be synchronized with the 50 MHz Clock to load the
|
||||
// counter's initial value
|
||||
output logic o_CLK // frequency divided clock
|
||||
);
|
||||
|
||||
|
||||
logic [g_COUNT_WIDTH-1:0] r_count_out; // wider for sign
|
||||
logic w_counter_overflowed;
|
||||
|
||||
logic r_fd_Q;
|
||||
logic w_fd_D;
|
||||
|
||||
logic w_load;
|
||||
|
||||
logic resetD, resetDD, resetPulse;
|
||||
logic rstdd2, rstddn;
|
||||
|
||||
assign w_load = resetPulse | w_counter_overflowed; // reload when zero occurs or when set by outside
|
||||
|
||||
SDCcounter #(.WIDTH(g_COUNT_WIDTH)) // wider for sign, this way the (MSB /= '1') only for zero
|
||||
my_counter (.clk(i_CLK),
|
||||
.Load(w_load), // reload when zero occurs or when set by outside
|
||||
.CountIn(i_COUNT_IN_MAX), // negative signed integer
|
||||
.CountOut(r_count_out),
|
||||
.Enable(1'b1), // ALWAYS COUNT
|
||||
.reset(1'b0)); // no reset, only load
|
||||
|
||||
|
||||
assign w_counter_overflowed = r_count_out[g_COUNT_WIDTH-1] == '0;
|
||||
|
||||
// to ensure the clock keeps running we need to make the reset last 1 cycle
|
||||
// rather than until the reset is released. Alternatively we could do
|
||||
// two resets. The first which resets this and the clk_fsm and the second
|
||||
// which resets the rest of the design.
|
||||
// Or we can make this clock divider not depend on reset.
|
||||
|
||||
flop #(1) pulseReset
|
||||
(.d(i_RST),
|
||||
.q(resetD),
|
||||
.clk(i_CLK));
|
||||
|
||||
flop #(1) pulseReset2
|
||||
(.d(resetD),
|
||||
.q(resetDD),
|
||||
.clk(i_CLK));
|
||||
|
||||
//assign resetPulse = i_RST & ~resetDD;
|
||||
assign resetPulse = ~i_RST & resetDD;
|
||||
|
||||
assign rstdd2 = i_RST | resetDD;
|
||||
|
||||
flop #(1) fallingEdge
|
||||
(.d(rstdd2),
|
||||
.q(rstddn),
|
||||
.clk(~i_CLK));
|
||||
|
||||
flopenr #(1) toggle_flip_flop
|
||||
(.d(w_fd_D),
|
||||
.q(r_fd_Q),
|
||||
.clk(i_CLK),
|
||||
.reset(resetPulse),
|
||||
.en(w_counter_overflowed)); // only update when counter overflows
|
||||
|
||||
assign w_fd_D = ~ r_fd_Q;
|
||||
|
||||
/* -----\/----- EXCLUDED -----\/-----
|
||||
if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN), .O(o_CLK));
|
||||
else assign o_CLK = i_EN ? r_fd_Q : i_CLK;
|
||||
-----/\----- EXCLUDED -----/\----- */
|
||||
|
||||
if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN & ~rstddn), .O(o_CLK));
|
||||
else assign o_CLK = i_EN & ~rstddn ? r_fd_Q : i_CLK;
|
||||
endmodule
|
@ -1,63 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// crc16 sipo np ce
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 18, 2021
|
||||
// Converted to system verilog.
|
||||
//
|
||||
// Purpose: CRC16 generator SIPO using register_ce
|
||||
// w/o appending any zero-bits to the message
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module crc16_sipo_np_ce(
|
||||
input logic CLK, // sequential device
|
||||
input logic RST, // initial calue of CRC register must be "0000_0000_0000_0000"
|
||||
input logic i_enable, // input is valid
|
||||
input logic i_message_bit,
|
||||
output logic [15:0] o_crc16
|
||||
);
|
||||
|
||||
logic [15:0] w_crc16_d;
|
||||
|
||||
flopenr #(16) crc16reg(.clk(CLK),
|
||||
.reset(RST),
|
||||
.en(i_enable),
|
||||
.d(w_crc16_d),
|
||||
.q(o_crc16));
|
||||
|
||||
assign w_crc16_d[15] = o_crc16[14];
|
||||
assign w_crc16_d[14] = o_crc16[13];
|
||||
assign w_crc16_d[13] = o_crc16[12];
|
||||
assign w_crc16_d[12] = o_crc16[11] ^ (i_message_bit ^ o_crc16[15]);
|
||||
assign w_crc16_d[11] = o_crc16[10];
|
||||
assign w_crc16_d[10] = o_crc16[9];
|
||||
assign w_crc16_d[9] = o_crc16[8];
|
||||
assign w_crc16_d[8] = o_crc16[7];
|
||||
assign w_crc16_d[7] = o_crc16[6];
|
||||
assign w_crc16_d[6] = o_crc16[5];
|
||||
assign w_crc16_d[5] = o_crc16[4] ^ (i_message_bit ^ o_crc16[15]);
|
||||
assign w_crc16_d[4] = o_crc16[3];
|
||||
assign w_crc16_d[3] = o_crc16[2];
|
||||
assign w_crc16_d[2] = o_crc16[1];
|
||||
assign w_crc16_d[1] = o_crc16[0];
|
||||
assign w_crc16_d[0] = i_message_bit ^ o_crc16[15];
|
||||
|
||||
|
||||
endmodule
|
@ -1,67 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// crc7 sipo np ce
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 18, 2021
|
||||
// Converted to system verilog.
|
||||
//
|
||||
// Purpose: takes 40 bits of input, generates 7 bit CRC after a single
|
||||
// clock cycle!
|
||||
// w/o appending any zero-bits to the message
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module crc7_pipo (
|
||||
input logic [39:0] i_DATA,
|
||||
input logic i_CRC_ENABLE,
|
||||
input logic RST,
|
||||
input logic CLK,
|
||||
output logic [6:0] o_CRC
|
||||
);
|
||||
|
||||
logic [6:0] r_lfsr_q;
|
||||
logic [6:0] w_lfsr_d;
|
||||
|
||||
assign o_CRC = r_lfsr_q;
|
||||
|
||||
assign w_lfsr_d[0] = r_lfsr_q[1] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[4] ^ i_DATA[7] ^ i_DATA[8] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[23] ^ i_DATA[24] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[34] ^ i_DATA[35] ^ i_DATA[37] ^ i_DATA[39];
|
||||
|
||||
assign w_lfsr_d[1] = r_lfsr_q[2] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[1] ^ i_DATA[5] ^ i_DATA[8] ^ i_DATA[9] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[24] ^ i_DATA[25] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[35] ^ i_DATA[36] ^ i_DATA[38];
|
||||
|
||||
assign w_lfsr_d[2] = r_lfsr_q[0] ^ r_lfsr_q[3] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[2] ^ i_DATA[6] ^ i_DATA[9] ^ i_DATA[10] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[25] ^ i_DATA[26] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[36] ^ i_DATA[37] ^ i_DATA[39];
|
||||
|
||||
assign w_lfsr_d[3] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[5] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[3] ^ i_DATA[4] ^ i_DATA[8] ^ i_DATA[10] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[26] ^ i_DATA[27] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[38] ^ i_DATA[39];
|
||||
|
||||
assign w_lfsr_d[4] = r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[6] ^ i_DATA[1] ^ i_DATA[4] ^ i_DATA[5] ^ i_DATA[9] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[27] ^ i_DATA[28] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[39];
|
||||
|
||||
assign w_lfsr_d[5] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ i_DATA[2] ^ i_DATA[5] ^ i_DATA[6] ^ i_DATA[10] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[28] ^ i_DATA[29] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[37];
|
||||
|
||||
assign w_lfsr_d[6] = r_lfsr_q[0] ^ r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[3] ^ i_DATA[6] ^ i_DATA[7] ^ i_DATA[11] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[29] ^ i_DATA[30] ^ i_DATA[33] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[38];
|
||||
|
||||
|
||||
|
||||
flopenr #(7)
|
||||
lfsrReg(.clk(CLK),
|
||||
.reset(RST),
|
||||
.en(i_CRC_ENABLE),
|
||||
.d(w_lfsr_d),
|
||||
.q(r_lfsr_q));
|
||||
|
||||
|
||||
endmodule
|
@ -1,60 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// crc16 sipo np ce
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 18, 2021
|
||||
//
|
||||
// Purpose: CRC7 generator SIPO using register_ce
|
||||
// w/o appending any zero-bits othe message
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module crc7_sipo_np_ce(
|
||||
input logic clk,
|
||||
input logic rst,// initial CRC value must be b"000_0000"
|
||||
input logic i_enable,
|
||||
input logic i_message_bit,
|
||||
output logic [6:0] o_crc7
|
||||
);
|
||||
|
||||
|
||||
logic [6:0] w_crc7_d;
|
||||
logic [6:0] r_crc7_q;
|
||||
|
||||
flopenr #(7)
|
||||
crc7Reg(.clk(clk),
|
||||
.reset(rst),
|
||||
.en(i_enable),
|
||||
.d(w_crc7_d),
|
||||
.q(r_crc7_q));
|
||||
|
||||
assign w_crc7_d[6] = r_crc7_q[5];
|
||||
assign w_crc7_d[5] = r_crc7_q[4];
|
||||
assign w_crc7_d[4] = r_crc7_q[3];
|
||||
assign w_crc7_d[3] = r_crc7_q[2] ^ (i_message_bit ^ r_crc7_q[6]);
|
||||
assign w_crc7_d[2] = r_crc7_q[1];
|
||||
assign w_crc7_d[1] = r_crc7_q[0];
|
||||
assign w_crc7_d[0] = i_message_bit ^ r_crc7_q[6];
|
||||
|
||||
assign o_crc7 = r_crc7_q;
|
||||
|
||||
|
||||
endmodule
|
||||
|
||||
|
@ -1,49 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// piso generic ce
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 18, 2021
|
||||
//
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module piso_generic_ce #(parameter integer g_BUS_WIDTH) (
|
||||
input logic clk,
|
||||
input logic i_load,
|
||||
input logic [g_BUS_WIDTH-1:0] i_data,
|
||||
input logic i_en,
|
||||
output o_data);
|
||||
|
||||
|
||||
logic [g_BUS_WIDTH-1:0] w_reg_d;
|
||||
logic [g_BUS_WIDTH-1:0] r_reg_q;
|
||||
|
||||
flopenr #(g_BUS_WIDTH)
|
||||
shiftReg(.clk(clk),
|
||||
.reset(1'b0),
|
||||
.en(1'b1),
|
||||
.d(w_reg_d),
|
||||
.q(r_reg_q));
|
||||
|
||||
assign o_data = i_en ? r_reg_q[g_BUS_WIDTH - 1] : 1'b1;
|
||||
assign w_reg_d = i_load ? i_data :
|
||||
i_en ? {r_reg_q[g_BUS_WIDTH - 2 : 0], 1'b1} :
|
||||
r_reg_q[g_BUS_WIDTH - 1 : 0];
|
||||
|
||||
endmodule
|
@ -1,49 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// regfile_p2r1w1_nibo
|
||||
//
|
||||
// Written: Ross Thompson September 18, 2021
|
||||
// Modified: 2 port register file with 1 read and 1 write
|
||||
//
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module regfile_p2r1w1_nibo #(parameter integer DEPTH = 10, parameter integer WIDTH = 4) (
|
||||
input logic clk,
|
||||
input logic we1,
|
||||
input logic [DEPTH-1:0] ra1,
|
||||
output logic [WIDTH-1:0] rd1,
|
||||
output logic [(2**DEPTH)*WIDTH-1:0] Rd1All,
|
||||
input logic [DEPTH-1:0] wa1,
|
||||
input logic [WIDTH-1:0] wd1
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] regs [2**DEPTH-1:0];
|
||||
genvar index;
|
||||
|
||||
always_ff @(posedge clk) begin
|
||||
if(we1) begin
|
||||
regs[wa1] <= wd1;
|
||||
end
|
||||
end
|
||||
|
||||
assign rd1 = regs[ra1];
|
||||
for(index = 0; index < 2**DEPTH; index++)
|
||||
assign Rd1All[index*WIDTH+WIDTH-1:index*WIDTH] = regs[index];
|
||||
|
||||
endmodule
|
@ -1,44 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// regfile_p2r1w1bwen
|
||||
//
|
||||
// Written: Ross Thompson September 18, 2021
|
||||
// Modified: 2 port register file with 1 read and 1 write
|
||||
//
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module regfile_p2r1w1bwen #(parameter integer DEPTH = 10, parameter integer WIDTH = 4)(
|
||||
input logic clk,
|
||||
input logic we1,
|
||||
input logic [WIDTH-1:0] we1bit,
|
||||
input logic [DEPTH-1:0] ra1,
|
||||
output logic [WIDTH-1:0] rd1,
|
||||
input logic [DEPTH-1:0] wa1,
|
||||
input logic [WIDTH-1:0] wd1
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] regs [2**DEPTH-1:0];
|
||||
integer i;
|
||||
|
||||
always_ff @(posedge clk)
|
||||
if (we1) // global write enable
|
||||
regs[wa1] = wd1 & we1bit | regs[wa1] & ~we1bit; // bit write enable
|
||||
|
||||
assign rd1 = regs[ra1];
|
||||
endmodule
|
@ -1,93 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// sd_clk_fsm.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 19, 2021
|
||||
//
|
||||
// Purpose: Controls clock dividers.
|
||||
// Replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk
|
||||
// in sd_cmd_fsm.vhd. Attempts to correct issues with oversampling and
|
||||
// under-sampling of control signals (for counter_cmd), that were present in my
|
||||
// previous design.
|
||||
// This runs on 50 MHz.
|
||||
// sd_cmd_fsm will run on SD_CLK_Gated (50 MHz or 400 KHz, selected by this)
|
||||
// asynchronous reset is used for both sd_cmd_fsm and for this.
|
||||
// It must be synchronized with 50 MHz and held for a minimum period of a full
|
||||
// 400 KHz pulse width.
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module sd_clk_fsm (
|
||||
input logic CLK,
|
||||
input logic i_RST,
|
||||
(* mark_debug = "true" *)output logic o_DONE,
|
||||
(* mark_debug = "true" *)input logic i_START,
|
||||
(* mark_debug = "true" *)input logic i_FATAL_ERROR,
|
||||
(* mark_debug = "true" *)output logic o_HS_TO_INIT_CLK_DIVIDER_RST, // resets clock divider that is going from 50 MHz to 400 KHz
|
||||
(* mark_debug = "true" *)output logic o_SD_CLK_SELECTED, // which clock is selected ('0'=HS or '1'=init)
|
||||
(* mark_debug = "true" *)output logic o_G_CLK_SD_EN // Turns gated clock (G_CLK_SD) off and on
|
||||
);
|
||||
|
||||
|
||||
logic [3:0] w_next_state;
|
||||
(* mark_debug = "true" *) logic [3:0] r_curr_state;
|
||||
|
||||
|
||||
// clock selection
|
||||
parameter c_sd_clk_init = 1'b1;
|
||||
parameter c_sd_clk_hs = 1'b0;
|
||||
|
||||
// States
|
||||
localparam s_reset = 4'b0000;
|
||||
localparam s_enable_init_clk = 4'b0001; // enable 400 KHz
|
||||
localparam s_disable_sd_clocks = 4'b0010;
|
||||
localparam s_select_hs_clk = 4'b0011;
|
||||
localparam s_enable_hs_clk = 4'b0100;
|
||||
localparam s_done = 4'b0101;
|
||||
localparam s_disable_sd_clocks_2 = 4'b0110; // if error occurs
|
||||
localparam s_select_init_clk = 4'b0111; // if error occurs
|
||||
localparam s_safe_state = 4'b1111; //always provide a safe state return if all states are not used
|
||||
|
||||
flopenr #(4) stateReg(.clk(CLK),
|
||||
.reset(i_RST),
|
||||
.en(1'b1),
|
||||
.d(w_next_state),
|
||||
.q(r_curr_state));
|
||||
|
||||
assign w_next_state = i_RST ? s_reset :
|
||||
r_curr_state == s_reset | (r_curr_state == s_enable_init_clk & ~i_START) | (r_curr_state == s_select_init_clk) ? s_enable_init_clk :
|
||||
r_curr_state == s_enable_init_clk & i_START ? s_disable_sd_clocks :
|
||||
r_curr_state == s_disable_sd_clocks ? s_select_hs_clk :
|
||||
r_curr_state == s_select_hs_clk ? s_enable_hs_clk :
|
||||
r_curr_state == s_enable_hs_clk | (r_curr_state == s_done & ~i_FATAL_ERROR) ? s_done :
|
||||
r_curr_state == s_done & i_FATAL_ERROR ? s_disable_sd_clocks_2 :
|
||||
r_curr_state == s_disable_sd_clocks_2 ? s_select_init_clk :
|
||||
s_safe_state;
|
||||
|
||||
|
||||
assign o_HS_TO_INIT_CLK_DIVIDER_RST = r_curr_state == s_reset;
|
||||
|
||||
assign o_SD_CLK_SELECTED = (r_curr_state == s_select_hs_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done) ? c_sd_clk_hs : c_sd_clk_init;
|
||||
|
||||
assign o_G_CLK_SD_EN = (r_curr_state == s_enable_init_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done);
|
||||
|
||||
assign o_DONE = r_curr_state == s_done;
|
||||
|
||||
endmodule
|
||||
|
@ -1,586 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// sd_clk_fsm.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 19, 2021
|
||||
//
|
||||
// Purpose: Finite state machine for the SD CMD bus
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module sd_cmd_fsm (
|
||||
input logic CLK, // HS
|
||||
//i_SLOWER_CLK : in std_logic;
|
||||
input logic i_RST, // reset FSM,
|
||||
// MUST COME OUT OF RESET
|
||||
// SYNCHRONIZED TO THE 1.2 GHZ CLOCK!
|
||||
output logic o_TIMER_LOAD, o_TIMER_EN, // Timer
|
||||
output logic [18:0] o_TIMER_IN,
|
||||
input logic [18:0] i_TIMER_OUT,
|
||||
output logic o_COUNTER_LOAD, o_COUNTER_EN, // Counter
|
||||
output logic [7:0] o_COUNTER_IN,
|
||||
input logic [7:0] i_COUNTER_OUT,
|
||||
output logic o_SD_CLK_EN, // Clock Gaters
|
||||
input logic i_CLOCK_CHANGE_DONE, // Communication with CLK_FSM
|
||||
output logic o_START_CLOCK_CHANGE, // Communication with CLK_FSM
|
||||
output logic o_IC_RST, o_IC_EN, o_IC_UP_DOWN, // Instruction counter
|
||||
input logic [3:0] i_IC_OUT, // stop when you get to 10 because that is CMD17
|
||||
input logic [1:0] i_USES_DAT,
|
||||
input logic [6:0] i_OPCODE,
|
||||
input logic [2:0] i_R_TYPE,
|
||||
// bit masks
|
||||
input logic [31:0] i_NO_REDO_MASK,
|
||||
input logic [31:0] i_NO_REDO_ANS,
|
||||
input logic [31:0] i_NO_ERROR_MASK,
|
||||
input logic [31:0] i_NO_ERROR_ANS,
|
||||
(* mark_debug = "true" *) output logic o_SD_CMD_OE, // Enable ouptut on tri-state SD_CMD line
|
||||
// TX Components
|
||||
output logic o_TX_PISO40_LOAD, o_TX_PISO40_EN, // Shift register for TX command head
|
||||
output logic o_TX_PISO8_LOAD, o_TX_PISO8_EN, // Shift register for TX command tail
|
||||
output logic o_TX_CRC7_PIPO_RST, o_TX_CRC7_PIPO_EN, // Parallel-to-Parallel CRC7 Generator
|
||||
output logic [1:0] o_TX_SOURCE_SELECT, // What gets sent to CMD_TX
|
||||
// TX Memory
|
||||
output logic o_CMD_TX_IS_CMD55_RST,
|
||||
output logic o_CMD_TX_IS_CMD55_EN, // '1' means that the command that was just sent has index
|
||||
// 55, so the subsequent command is to be
|
||||
// viewed as ACMD by the SD card.
|
||||
// RX Components
|
||||
input logic i_SD_CMD_RX, // serial response input on SD_CMD
|
||||
output logic o_RX_SIPO48_RST, o_RX_SIPO48_EN, // Shift Register for all 48 bits of Response
|
||||
input logic [39:8] i_RESPONSE_CONTENT, // last 32 bits of RX_SIPO_40_OUT
|
||||
input logic [45:40] i_RESPONSE_INDEX, // 6 bits from RX_SIPO_40_OUT
|
||||
output logic o_RX_CRC7_SIPO_RST, o_RX_CRC7_SIPO_EN, // Serial-to-parallel CRC7 Generator
|
||||
input logic [6:0] i_RX_CRC7,
|
||||
// RX Memory
|
||||
output logic o_RCA_REGISTER_RST, o_RCA_REGISTER_EN, // Relative Card Address
|
||||
// Communication to sd_dat_fsm
|
||||
output logic o_CMD_TX_DONE, // begin waiting for DAT_RX to complete
|
||||
input logic i_DAT_RX_DONE, // now go to next state since data block rx was completed
|
||||
(* mark_debug = "true" *) input logic i_ERROR_CRC16, // repeat last command
|
||||
(* mark_debug = "true" *) input logic i_ERROR_DAT_TIMES_OUT,
|
||||
// Commnuication to core
|
||||
output logic o_READY_FOR_READ, // tell core that I have completed initialization
|
||||
output logic o_SD_RESTARTING, // inform core the need to restart
|
||||
input logic i_READ_REQUEST, // core tells me to execute CMD17
|
||||
// Communication to Host
|
||||
output logic o_DAT_ERROR_FD_RST,
|
||||
output logic [2:0] o_ERROR_CODE_Q, // Indicates what caused the fatal error
|
||||
output logic o_FATAL_ERROR, // SD Card is damaged beyond recovery, restart entire initialization procedure of card
|
||||
input logic LIMIT_SD_TIMERS
|
||||
);
|
||||
|
||||
logic [4:0] w_next_state;
|
||||
(* mark_debug = "true" *) logic [4:0] r_curr_state;
|
||||
logic w_resend_last_command, w_rx_crc7_check, w_rx_index_check, w_rx_bad_crc7, w_rx_bad_index, w_rx_bad_reply, w_bad_card;
|
||||
|
||||
logic [31:0] w_redo_result, w_error_result;
|
||||
logic w_ACMD41_init_done;
|
||||
logic w_fail_cnt_en, w_fail_count_rst;
|
||||
logic [10:0] r_fail_count_out;
|
||||
|
||||
logic w_ACMD41_busy_timer_START, w_ACMD41_times_out_FLAG, w_ACMD41_busy_timer_RST; //give up after 1000 ms of ACMD41
|
||||
logic [2:0] w_ERROR_CODE_D, r_ERROR_CODE_Q ; // Error Codes for fatal error on SD CMD FSM
|
||||
logic w_ERROR_CODE_RST, w_ERROR_CODE_EN;
|
||||
logic [18:0] Timer_In;
|
||||
|
||||
|
||||
localparam s_reset_clear_error_reg = 5'b00000;
|
||||
localparam s_idle_supply_no_clk = 5'b00001;
|
||||
localparam s_idle_supply_sd_clk = 5'b00010;
|
||||
localparam s_ld_head = 5'b00011;
|
||||
localparam s_tx_head = 5'b00100;
|
||||
localparam s_ld_tail = 5'b00101;
|
||||
localparam s_tx_tail = 5'b00110;
|
||||
localparam s_setup_rx = 5'b00111;
|
||||
localparam s_idle_ncc = 5'b01000;
|
||||
localparam s_fetch_next_cmd = 5'b01001;
|
||||
localparam s_rx_48 = 5'b01010;
|
||||
localparam s_rx_136 = 5'b01011;
|
||||
localparam s_error_no_response = 5'b01100;
|
||||
localparam s_idle_for_dat = 5'b01101;
|
||||
localparam s_error_bad_card = 5'b01110;
|
||||
localparam s_idle_nrc = 5'b01111;
|
||||
localparam s_count_attempt = 5'b10000;
|
||||
localparam s_reset_from_error = 5'b10001;
|
||||
//localparam s_enable_hs_clk = 5'b10010;
|
||||
localparam s_idle_for_start_bit = 5'b10011;
|
||||
localparam s_fetch_prev_cmd = 5'b10100; // use to resend previous cmd55 if acmd is resent
|
||||
// localparam s_setup_rx_b = 5'b10110;
|
||||
// localparam s_idle_for_start_bit_b= 5'b10111;
|
||||
// localparam s_rx_48_b = 5'b11000;
|
||||
// localparam s_rx_136_b = 5'b11001;
|
||||
localparam s_error_dat_time_out = 5'b11010; // don't advance states if the dat fsm times out
|
||||
localparam s_idle_for_clock_change = 5'b11011; // replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk
|
||||
localparam s_study_response = 5'b11100; // Do error checking here
|
||||
localparam s_idle_for_read_request = 5'b11101; // After power up and initialization sequence is completed
|
||||
localparam s_Error_TX_Failed = 5'b11110; // when fail_cnt_out exceeds c_max_attempts
|
||||
|
||||
localparam c_MAX_ATTEMPTS = 1500; // Give up sending a command after 3 failed attempts
|
||||
// (except ACMD41) so the processor is not locked up forever
|
||||
|
||||
localparam c_response_type_R0_NONE = 0;
|
||||
localparam c_response_type_R1_NORMAL = 1;
|
||||
localparam c_response_type_R2_CID_CSD = 2;
|
||||
localparam c_response_type_R3_OCR = 3;
|
||||
localparam c_response_type_R6_RCA = 6;
|
||||
localparam c_response_type_R7_CIC = 7;
|
||||
|
||||
localparam c_start_bit = 1'b0;
|
||||
|
||||
localparam c_DAT_none = 2'b00;
|
||||
localparam c_DAT_busy = 2'b01;
|
||||
localparam c_DAT_wide = 2'b10;
|
||||
localparam c_DAT_block = 2'b11;
|
||||
|
||||
// Instructions mnemonics based on index (opcode(5 downto 0))
|
||||
localparam logic [45:40] c_Go_Idle_State = 6'd0; //CMD0
|
||||
localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2
|
||||
localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3
|
||||
localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6
|
||||
localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6
|
||||
localparam logic [45:40] c_Select_Card = 6'd07; // CMD7
|
||||
localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8
|
||||
localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17
|
||||
localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41
|
||||
localparam logic [45:40] c_App_Command = 6'd55; // CMD55
|
||||
|
||||
// clock selection
|
||||
localparam c_sd_clk_init = 1'b1;
|
||||
localparam c_sd_clk_hs = 1'b0;
|
||||
|
||||
//tx source selection
|
||||
localparam logic [1:0] c_tx_low = 2'b00;
|
||||
localparam logic [1:0] c_tx_high = 2'b01;
|
||||
localparam logic [1:0] c_tx_head = 2'b10;
|
||||
localparam logic [1:0] c_tx_tail = 2'b11;
|
||||
|
||||
// Error Codes for Error Register
|
||||
localparam logic [2:0] c_NO_ERRORS = 3'b000; // no fatal errors occurred
|
||||
// (default value when register is cleared during reset)
|
||||
localparam [2:0] C_ERROR_NO_CMD_RESPONSE = 3'b100; // card timed out while waiting for a response on CMD, no start bit
|
||||
// of response packet was ever received
|
||||
// (possible causes: illegal command, card is disconnected,
|
||||
// not meeting timing (you can fix timing by inverting the clock
|
||||
// sent to card))
|
||||
localparam logic [2:0] c_ERROR_NO_DAT_RESPONSE = 3'b101; // card timed out while waiting for a data block on DAT, no start bit
|
||||
// of DAT packet was ever received
|
||||
// (possible cause: card is disconnected)
|
||||
localparam logic [2:0] C_ERROR_BAD_CARD_STATUS = 3'b110; // status bits of a response indicate a card is not supported
|
||||
// or that the card is damaged internally
|
||||
localparam logic [2:0] C_ERROR_EXCEED_MAX_ATTEMPTS = 3'b111; // if a command fails it may be resent,
|
||||
// but after so many attempts you should just give up
|
||||
|
||||
//Alias for value of SD_CMD_Output_Enable
|
||||
localparam c_TX_COMMAND = 1'b1; // Enable output on SD_CMD
|
||||
localparam c_RX_RESPONSE = 1'b0; // Disable Output on SD_CMD
|
||||
|
||||
// load values in for timers and counters
|
||||
localparam logic [7:0] c_NID_max = 8'd63; // counter_in: should be "4"
|
||||
// downto 0 = 5 bits count
|
||||
// but is not enough time for
|
||||
// sdModel.v
|
||||
localparam logic [7:0] c_NCR_max = 8'd63; // counter_in
|
||||
localparam logic [7:0] c_NCC_min = 8'd7; // counter_in
|
||||
localparam logic [7:0] c_NRC_min = 8'd8; // counter_in
|
||||
|
||||
//localparam logic [18:0] c_1000ms = 19'd400000; // ACMD41 timeout
|
||||
//*** BUG this value is too bit to fit into 19 bits.
|
||||
localparam logic [18:0] c_1000ms = 19'd40000; // ACMD41 timeout
|
||||
|
||||
// command instruction type (opcode(6))
|
||||
localparam c_CMD = 1'b0;
|
||||
localparam c_ACMD = 1'b1;
|
||||
|
||||
// counter direction for up_down
|
||||
localparam c_increment = 1'b1; // count <= count + 1
|
||||
localparam c_decrement = 1'b0; // count <= count - 1
|
||||
|
||||
|
||||
logic COUNTER_OUT_GT_ZERO;
|
||||
logic COUNTER_OUT_GE_ZERO;
|
||||
logic COUNTER_OUT_GT_8;
|
||||
logic COUNTER_OUT_EQ_8;
|
||||
logic COUNTER_OUT_EQ_ZERO;
|
||||
logic TIMER_OUT_GT_ZERO;
|
||||
logic TIMER_OUT_EQ_ZERO;
|
||||
logic fail_count_out_le_max_attempts;
|
||||
logic fail_count_out_lt_max_attempts;
|
||||
logic fail_count_out_gt_max_attempts;
|
||||
logic IC_OUT_EQ_2;
|
||||
logic IC_OUT_EQ_3;
|
||||
logic IC_OUT_LT_9;
|
||||
logic IC_OUT_GE_9;
|
||||
|
||||
|
||||
assign Timer_In = LIMIT_SD_TIMERS ? 19'b0000000000000000011 : 19'b0011000011010100000; // 250 ms
|
||||
|
||||
//Fail Counter, tracks how many failed attempts at command transmission
|
||||
SDCcounter #(11) fail_counter
|
||||
(.CountIn(11'b0),
|
||||
.CountOut(r_fail_count_out),
|
||||
.Load(1'b0),
|
||||
.Enable(w_fail_cnt_en),
|
||||
.clk(CLK),
|
||||
.reset(w_fail_count_rst));
|
||||
|
||||
// Simple timer for ACMD41 busy
|
||||
simple_timer #(19) ACMD41_busy_timer
|
||||
(.VALUE(c_1000ms),
|
||||
.START(w_ACMD41_busy_timer_START),
|
||||
.FLAG(w_ACMD41_times_out_FLAG),
|
||||
.RST(w_ACMD41_busy_timer_RST),
|
||||
.CLK(CLK));
|
||||
|
||||
// State Register, instantiate register_ce. 32 state state machine
|
||||
flopenr #(5) state_reg
|
||||
(.d(w_next_state),
|
||||
.q(r_curr_state),
|
||||
.en(1'b1),
|
||||
.reset(i_RST),
|
||||
.clk(CLK));
|
||||
|
||||
// Error register : indicates what type of fatal error occured for interrupt
|
||||
flopenr #(3) error_reg
|
||||
(.d(w_ERROR_CODE_D),
|
||||
.q(r_ERROR_CODE_Q),
|
||||
.en(w_ERROR_CODE_EN),
|
||||
.reset(w_ERROR_CODE_RST),
|
||||
.clk(CLK));
|
||||
|
||||
assign o_ERROR_CODE_Q = r_ERROR_CODE_Q;
|
||||
assign COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0;
|
||||
assign COUNTER_OUT_GE_ZERO = $signed(i_COUNTER_OUT) >= $signed(8'b0);
|
||||
assign COUNTER_OUT_GT_8 = i_COUNTER_OUT > 8;
|
||||
assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8;
|
||||
assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0;
|
||||
assign TIMER_OUT_GT_ZERO = i_TIMER_OUT > 0;
|
||||
assign TIMER_OUT_EQ_ZERO = i_TIMER_OUT == 0;
|
||||
assign fail_count_out_le_max_attempts = r_fail_count_out <= (c_MAX_ATTEMPTS-1);
|
||||
assign fail_count_out_lt_max_attempts = r_fail_count_out < (c_MAX_ATTEMPTS-1);
|
||||
assign fail_count_out_gt_max_attempts = r_fail_count_out > (c_MAX_ATTEMPTS-1);
|
||||
assign IC_OUT_EQ_2 = i_IC_OUT == 2;
|
||||
assign IC_OUT_EQ_3 = i_IC_OUT == 3;
|
||||
assign IC_OUT_LT_9 = i_IC_OUT < 9;
|
||||
assign IC_OUT_GE_9 = i_IC_OUT >= 9;
|
||||
|
||||
assign w_next_state = i_RST ? s_reset_clear_error_reg :
|
||||
|
||||
((r_curr_state == s_reset_clear_error_reg) |
|
||||
(r_curr_state == s_Error_TX_Failed) |
|
||||
(r_curr_state == s_error_no_response) |
|
||||
(r_curr_state == s_error_bad_card) |
|
||||
(r_curr_state == s_error_dat_time_out)) ? s_reset_from_error :
|
||||
|
||||
|
||||
((r_curr_state == s_reset_from_error) |
|
||||
((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_GT_ZERO))) ? s_idle_supply_no_clk :
|
||||
|
||||
(((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_EQ_ZERO)) |
|
||||
((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_GT_ZERO))) ? s_idle_supply_sd_clk :
|
||||
|
||||
(r_curr_state == s_ld_head) ? s_count_attempt :
|
||||
|
||||
(((r_curr_state == s_count_attempt) & (fail_count_out_le_max_attempts)) |
|
||||
((r_curr_state == s_count_attempt) &
|
||||
(((IC_OUT_EQ_2) & (i_OPCODE[5:0] == c_App_Command)) |
|
||||
((IC_OUT_EQ_3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR})))) // to work CMD55, ACMD41 MUST be lines 2, 3 of instruction fetch mux of sd_top.vhd
|
||||
& (w_ACMD41_times_out_FLAG)
|
||||
& (fail_count_out_gt_max_attempts))) ? s_tx_head :
|
||||
|
||||
((r_curr_state == s_count_attempt) & (fail_count_out_gt_max_attempts)) ? s_Error_TX_Failed :
|
||||
|
||||
((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (COUNTER_OUT_GT_8))) ? s_ld_tail :
|
||||
|
||||
(((r_curr_state == s_ld_tail) & (COUNTER_OUT_EQ_8)) |
|
||||
((r_curr_state == s_tx_tail) & (COUNTER_OUT_GT_ZERO))) ? s_tx_tail :
|
||||
|
||||
(r_curr_state == s_tx_tail) & (COUNTER_OUT_EQ_ZERO) ? s_setup_rx :
|
||||
|
||||
(((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) |
|
||||
((r_curr_state == s_idle_ncc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_ncc :
|
||||
|
||||
(((r_curr_state == s_setup_rx) & (i_R_TYPE != c_response_type_R0_NONE)) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) &
|
||||
(COUNTER_OUT_GT_ZERO))) ? s_idle_for_start_bit :
|
||||
|
||||
((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) &
|
||||
(COUNTER_OUT_EQ_ZERO)) ? s_error_no_response :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
|
||||
/* verilator lint_off UNSIGNED */
|
||||
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE == c_response_type_R2_CID_CSD)) |
|
||||
/* verilator lint_on UNSIGNED */
|
||||
((r_curr_state == s_rx_136) & (COUNTER_OUT_GT_ZERO))) ? s_rx_136 :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
|
||||
/* verilator lint_off UNSIGNED */
|
||||
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE != c_response_type_R2_CID_CSD)) |
|
||||
/* verilator lint_on UNSIGNED */
|
||||
((r_curr_state == s_rx_48) & (COUNTER_OUT_GT_ZERO))) ? s_rx_48 :
|
||||
|
||||
(((r_curr_state == s_rx_136) & (COUNTER_OUT_EQ_ZERO)) |
|
||||
((r_curr_state == s_rx_48) & COUNTER_OUT_EQ_ZERO)) ? s_study_response :
|
||||
|
||||
(r_curr_state == s_study_response) & w_bad_card ? s_error_bad_card :
|
||||
|
||||
(((r_curr_state == s_study_response) & (~w_bad_card) & (i_USES_DAT != c_DAT_none)) |
|
||||
((r_curr_state == s_idle_for_dat) & (~i_DAT_RX_DONE))) ? s_idle_for_dat :
|
||||
|
||||
((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) & (i_ERROR_DAT_TIMES_OUT)) ? s_error_dat_time_out :
|
||||
|
||||
(((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) &
|
||||
(~i_ERROR_DAT_TIMES_OUT)) |
|
||||
((r_curr_state == s_study_response) & (~w_bad_card) &
|
||||
(i_USES_DAT == c_DAT_none)) |
|
||||
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_GT_ZERO))) ? s_idle_nrc :
|
||||
|
||||
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
|
||||
(w_resend_last_command) & ((i_OPCODE[6] == c_ACMD) &
|
||||
((i_OPCODE[5:0]) != c_App_Command))) ? s_fetch_prev_cmd :
|
||||
|
||||
((r_curr_state == s_fetch_prev_cmd) |
|
||||
((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_EQ_ZERO)) |
|
||||
((r_curr_state == s_fetch_next_cmd) & // before CMD17
|
||||
(IC_OUT_LT_9)) | // blindly load head of next command
|
||||
((r_curr_state == s_idle_for_read_request) & (i_READ_REQUEST)) | // got the request, load head
|
||||
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
|
||||
(w_resend_last_command) & ((i_OPCODE[6] == c_CMD) |
|
||||
((i_OPCODE[5:0]) == c_App_Command)))) ? s_ld_head :
|
||||
|
||||
(((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
|
||||
(~w_resend_last_command) & ((i_OPCODE) == ({c_CMD, c_Switch_Function}))) |
|
||||
((r_curr_state == s_idle_for_clock_change) & (~i_CLOCK_CHANGE_DONE))) ? s_idle_for_clock_change :
|
||||
|
||||
(((r_curr_state == s_idle_ncc) & (COUNTER_OUT_EQ_ZERO)) |
|
||||
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
|
||||
(~w_resend_last_command) & ((i_OPCODE) != ({c_CMD, c_Switch_Function}))) |
|
||||
((r_curr_state == s_idle_for_clock_change) & (i_CLOCK_CHANGE_DONE))) ? s_fetch_next_cmd :
|
||||
|
||||
(((r_curr_state == s_fetch_next_cmd) &
|
||||
(IC_OUT_GE_9)) | // During and after CMD17, wait for request to send CMD17 from core
|
||||
// waiting for request
|
||||
(r_curr_state == s_idle_for_read_request)) ? s_idle_for_read_request :
|
||||
|
||||
s_reset_clear_error_reg;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// state outputs
|
||||
assign w_ACMD41_busy_timer_START = ((r_curr_state == s_count_attempt) & (i_OPCODE == {c_ACMD, c_SD_Send_OCR}) & (r_fail_count_out == 1));
|
||||
|
||||
assign w_ACMD41_busy_timer_RST = ((r_curr_state == s_reset_from_error) | (w_ACMD41_init_done));
|
||||
|
||||
// Error Register
|
||||
assign w_ERROR_CODE_RST = (r_curr_state == s_reset_clear_error_reg);
|
||||
|
||||
assign w_ERROR_CODE_EN = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) | (r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out);
|
||||
|
||||
assign w_ERROR_CODE_D = (r_curr_state == s_Error_TX_Failed) ? C_ERROR_EXCEED_MAX_ATTEMPTS : // give up
|
||||
(r_curr_state == s_error_bad_card) ? C_ERROR_BAD_CARD_STATUS : // card is damaged or unsupported
|
||||
(r_curr_state == s_error_no_response) ? C_ERROR_NO_CMD_RESPONSE : // no response was received on CMD line
|
||||
(r_curr_state == s_error_dat_time_out) ? c_ERROR_NO_DAT_RESPONSE : // no data packet was received on DAT bus
|
||||
c_NO_ERRORS; // all is well
|
||||
|
||||
// Failure counter
|
||||
assign w_fail_count_rst = ((r_curr_state == s_reset_from_error) | (r_curr_state == s_fetch_next_cmd & i_OPCODE[5:0] != c_App_Command));
|
||||
|
||||
|
||||
assign w_fail_cnt_en = ((r_curr_state == s_count_attempt) & (i_OPCODE[6] != c_ACMD | i_OPCODE[5:0] == c_App_Command));
|
||||
// & (i_OPCODE != ({c_ACMD, c_SD_Send_OCR})) else // NOT ACMD41, it can take up to 1 second
|
||||
|
||||
// Timer module
|
||||
assign o_TIMER_EN = (r_curr_state == s_idle_supply_no_clk);
|
||||
|
||||
assign o_TIMER_LOAD = (r_curr_state == s_reset_from_error);
|
||||
|
||||
assign o_TIMER_IN = (r_curr_state == s_reset_from_error) ? Timer_In : '0;
|
||||
|
||||
// Clock selection/gater module(s) ...
|
||||
assign o_SD_CLK_EN = ~((r_curr_state == s_reset_from_error) | (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_for_clock_change));
|
||||
|
||||
assign o_START_CLOCK_CHANGE = (r_curr_state == s_idle_for_clock_change);
|
||||
|
||||
// RCA register module
|
||||
assign o_RCA_REGISTER_RST = (r_curr_state == s_reset_from_error);
|
||||
|
||||
assign o_RCA_REGISTER_EN = ((r_curr_state == s_idle_nrc) & (i_R_TYPE == c_response_type_R6_RCA));
|
||||
|
||||
// Instruction counter module
|
||||
assign o_IC_RST = (r_curr_state == s_reset_from_error);
|
||||
|
||||
//assign o_IC_EN = (r_curr_state == s_fetch_next_cmd) | (r_curr_state == s_fetch_prev_cmd);
|
||||
|
||||
assign o_IC_EN = (((r_curr_state == s_fetch_next_cmd) & (i_IC_OUT < 10)) | (r_curr_state == s_fetch_prev_cmd));
|
||||
|
||||
assign o_IC_UP_DOWN = (r_curr_state == s_fetch_prev_cmd) ? c_decrement : c_increment;
|
||||
|
||||
// "Previous Command sent was CMD55, so the command I'm now sending is ACMD" module
|
||||
assign o_CMD_TX_IS_CMD55_RST = (r_curr_state == s_reset_from_error);
|
||||
|
||||
assign o_CMD_TX_IS_CMD55_EN = (r_curr_state == s_ld_head);
|
||||
|
||||
// Output signals to DAT FSM
|
||||
//o_CMD_TX_DONE = '0' when (r_curr_state == s_reset) else // reset
|
||||
// '0' when (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_supply_sd_clk) else // power up
|
||||
// '0' when ((r_curr_state == s_ld_head)
|
||||
// | (r_curr_state == s_tx_head)
|
||||
// | (r_curr_state == s_ld_tail)
|
||||
// | (r_curr_state == s_tx_tail)) else // tx
|
||||
// '1';
|
||||
assign o_CMD_TX_DONE = (r_curr_state == s_setup_rx);
|
||||
|
||||
// Counter Module
|
||||
assign o_COUNTER_LOAD = (r_curr_state == s_idle_supply_no_clk) |
|
||||
(r_curr_state == s_ld_head) |
|
||||
(r_curr_state == s_setup_rx) |
|
||||
(r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) |
|
||||
(r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) |
|
||||
(r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0);
|
||||
|
||||
assign o_COUNTER_IN = (r_curr_state == s_idle_supply_no_clk) ? 8'd73 :
|
||||
// | is it 73 downto 0 == 74 bits
|
||||
(r_curr_state == s_ld_head) ? 8'd47 : // or is it 48
|
||||
((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) ? c_NCC_min :
|
||||
((r_curr_state == s_setup_rx)
|
||||
& (i_R_TYPE != c_response_type_R0_NONE)
|
||||
& (((i_OPCODE) == ({c_CMD, c_All_Send_CID})) |
|
||||
((i_OPCODE) == ({c_ACMD, c_SD_Send_OCR})))) ? c_NID_max :
|
||||
(r_curr_state == s_setup_rx) ? c_NCR_max :
|
||||
((r_curr_state == s_idle_for_start_bit) & (i_R_TYPE == c_response_type_R2_CID_CSD)) ? 8'd135 : // | is it 136
|
||||
(r_curr_state == s_idle_for_start_bit) ? 8'd46 : // | is it not48
|
||||
(r_curr_state == s_rx_48) | (r_curr_state == s_rx_136) ? c_NRC_min : // | is it 8
|
||||
8'd0;
|
||||
|
||||
assign o_COUNTER_EN = (r_curr_state == s_idle_supply_sd_clk) ? 1'b1 :
|
||||
((r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail) | (r_curr_state == s_tx_tail)) ? 1'b1 :
|
||||
(r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) ? 1'b0 :
|
||||
(r_curr_state == s_idle_for_start_bit) ? 1'b1 :
|
||||
(r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) ? 1'b0 :
|
||||
(r_curr_state == s_rx_48) ? 1'b1 :
|
||||
(r_curr_state == s_idle_nrc) ? 1'b1 :
|
||||
(r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0) ? 1'b0 :
|
||||
(r_curr_state == s_rx_136) ? 1'b1 :
|
||||
(r_curr_state == s_idle_ncc) ? 1'b1 :
|
||||
1'b0;
|
||||
|
||||
// SD_CMD Tri-state Buffer Module
|
||||
assign o_SD_CMD_OE = (r_curr_state == s_idle_supply_sd_clk) ? c_TX_COMMAND :
|
||||
((r_curr_state == s_tx_head)
|
||||
| (r_curr_state == s_ld_tail)
|
||||
| (r_curr_state == s_tx_tail)) ? c_TX_COMMAND :
|
||||
c_RX_RESPONSE;
|
||||
|
||||
// Shift Registers
|
||||
// TX_PISO40 Transmit Command Head
|
||||
assign o_TX_PISO40_LOAD = (r_curr_state == s_ld_head);
|
||||
|
||||
assign o_TX_PISO40_EN = (r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail);
|
||||
|
||||
// TX_CRC7_PIPO Generate Tail
|
||||
assign o_TX_CRC7_PIPO_RST = (r_curr_state == s_ld_head);
|
||||
|
||||
assign o_TX_CRC7_PIPO_EN = (r_curr_state == s_tx_head);
|
||||
|
||||
// TX_PISO8 Transmit Command Tail
|
||||
assign o_TX_PISO8_LOAD = (r_curr_state == s_ld_tail);
|
||||
|
||||
assign o_TX_PISO8_EN = (r_curr_state == s_tx_tail);
|
||||
|
||||
// RX_CRC7_SIPO Calculate the CRC7 of the first 47-bits of reply (should be zero)
|
||||
assign o_RX_CRC7_SIPO_RST = (r_curr_state == s_setup_rx);
|
||||
|
||||
assign o_RX_CRC7_SIPO_EN = (r_curr_state == s_rx_48) & (i_COUNTER_OUT > 0); // or (r_curr_state == s_rx_48_b)
|
||||
|
||||
// RX_SIPO40 Content bits of response
|
||||
assign o_RX_SIPO48_RST = (r_curr_state == s_setup_rx);
|
||||
|
||||
assign o_RX_SIPO48_EN = (r_curr_state == s_rx_48 | r_curr_state == s_rx_48);
|
||||
|
||||
// Fatal Error Signal Wire
|
||||
assign o_FATAL_ERROR = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) |
|
||||
(r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out);
|
||||
|
||||
assign o_DAT_ERROR_FD_RST = (r_curr_state == s_ld_head);
|
||||
|
||||
// I'm debating the merit of creating yet another state for sd_cmd_fsm.vhd to go into when and if sd_dat_fsm.vhd
|
||||
// times out while waiting for start bit on the DAT bus resulting in Error_Time_Out going high in
|
||||
// sd_Dat_fsm.vhd while sd_cmd_fsm.vhd is still in s_idle_for_dat
|
||||
|
||||
// TX source selection bits for mux
|
||||
assign o_TX_SOURCE_SELECT = (r_curr_state == s_idle_supply_sd_clk) ? c_tx_high :
|
||||
((r_curr_state == s_ld_head)
|
||||
| (r_curr_state == s_tx_head)
|
||||
| (r_curr_state == s_ld_tail)) ? c_tx_head :
|
||||
(r_curr_state == s_tx_tail) ? c_tx_tail :
|
||||
c_tx_high; // This occurs when not transmitting anything
|
||||
|
||||
// Study Response
|
||||
assign w_rx_crc7_check = (r_curr_state == s_idle_nrc) &
|
||||
((i_R_TYPE != c_response_type_R0_NONE) &
|
||||
(i_R_TYPE != c_response_type_R3_OCR) &
|
||||
(i_R_TYPE != c_response_type_R2_CID_CSD));
|
||||
|
||||
assign w_rx_index_check = (r_curr_state == s_idle_nrc) &
|
||||
((i_R_TYPE != c_response_type_R0_NONE) &
|
||||
(i_R_TYPE != c_response_type_R3_OCR) &
|
||||
(i_R_TYPE != c_response_type_R2_CID_CSD));
|
||||
|
||||
assign w_redo_result = i_RESPONSE_CONTENT & i_NO_REDO_MASK;
|
||||
|
||||
assign w_rx_bad_reply = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & (w_redo_result != i_NO_REDO_ANS));
|
||||
|
||||
assign w_rx_bad_crc7 = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & ((w_rx_crc7_check) & (i_RX_CRC7 != 7'b0)));
|
||||
|
||||
assign w_rx_bad_index = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response)
|
||||
& ((w_rx_index_check) & (i_RESPONSE_INDEX != i_OPCODE[5:0])));
|
||||
|
||||
assign w_resend_last_command = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) &
|
||||
((w_rx_bad_reply) | (w_rx_bad_index) | (w_rx_bad_crc7))) |
|
||||
((r_curr_state == s_idle_nrc) &
|
||||
((i_ERROR_CRC16) &
|
||||
((i_USES_DAT == c_DAT_block) | (i_USES_DAT == c_DAT_wide))));
|
||||
|
||||
assign w_error_result = i_RESPONSE_CONTENT & i_NO_ERROR_MASK;
|
||||
|
||||
// Make assignment based on what was read from the OCR Register.
|
||||
// Bit 31, Card power up status bit: '1' == SD Flash Card power up procedure is finished.
|
||||
// '0' == SD Flash Card power up procedure is not finished.
|
||||
// Bit 30, Card capacity status bit: '1' == Extended capacity card is in use (64 GB in size or greater).
|
||||
// '0' == Extended capacity card is not in use.
|
||||
assign w_ACMD41_init_done = ((i_IC_OUT == 3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR}))) &
|
||||
(~w_rx_bad_reply) & (r_curr_state == s_study_response);
|
||||
|
||||
assign w_bad_card = ((r_curr_state == s_study_response) & (w_error_result != i_NO_ERROR_ANS) &
|
||||
((~w_ACMD41_times_out_FLAG) | (w_ACMD41_init_done)));
|
||||
|
||||
// Communication with core
|
||||
assign o_READY_FOR_READ = (r_curr_state == s_idle_for_read_request);
|
||||
|
||||
assign o_SD_RESTARTING = (r_curr_state == s_Error_TX_Failed) |
|
||||
(r_curr_state == s_error_dat_time_out) |
|
||||
(r_curr_state == s_error_bad_card) |
|
||||
(r_curr_state == s_error_no_response);
|
||||
|
||||
|
||||
|
||||
|
||||
endmodule
|
@ -1,253 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// sd_dat_fsm.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 19, 2021
|
||||
//
|
||||
// Purpose: Runs in parallel with sd_cmd_fsm to control activity on the DAT
|
||||
// bus of the SD card.
|
||||
// 14 State Mealy FSM + Safe state = 15 State Mealy FSM
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module sd_dat_fsm (
|
||||
input logic CLK, // HS Clock (48 MHz)
|
||||
input logic i_RST,
|
||||
// Timer module control
|
||||
input logic i_SD_CLK_SELECTED, // Which frequency I'm in determines what count in to load for a 100ms timer
|
||||
output logic o_TIMER_LOAD, o_TIMER_EN, // Timer Control signals
|
||||
output logic [22:0] o_TIMER_IN, // Need Enough bits for 100 milliseconds at 48MHz
|
||||
input logic [22:0] i_TIMER_OUT, // (ceiling(log((clk freq)(delay desired)-1)/log(2))-1) downto 0
|
||||
// Nibble counter module control
|
||||
output logic o_COUNTER_RST, o_COUNTER_EN, // nibble counter
|
||||
input logic [10:0] i_COUNTER_OUT, // max nibbles is 1024 + crc16 bits = 1040 bits
|
||||
// CRC16 Generation control
|
||||
(* mark_debug = "true" *)output logic o_CRC16_EN, o_CRC16_RST, // shared signals for all 4 CRC16_SIPO (one for each of 4 DAT lines)
|
||||
(* mark_debug = "true" *)input logic i_DATA_CRC16_GOOD, // indicates that no errors in transmission when CRC16 are all zero
|
||||
// For R1b
|
||||
output logic o_BUSY_RST, o_BUSY_EN, // busy signal for R1b
|
||||
(* mark_debug = "true" *)input logic i_DAT0_Q,
|
||||
// Storage Buffers for DAT bits read
|
||||
output logic o_NIBO_EN, // 512 bytes block data (Nibble In Block Out)
|
||||
// From LUT
|
||||
(* mark_debug = "true" *)input logic [1:0] i_USES_DAT, // current command needs use of DAT bus
|
||||
// For communicating with core
|
||||
output logic o_DATA_VALID, // indicates that DATA being send over o_DATA to core is valid
|
||||
output logic o_LAST_NIBBLE, // indicates that the last nibble has been sent
|
||||
// For communication with sd_cmd_fsm
|
||||
(* mark_debug = "true" *)input logic i_CMD_TX_DONE, // command transmission completed, begin waiting for DATA
|
||||
(* mark_debug = "true" *)output logic o_DAT_RX_DONE, // tell SD_CMD_FSM that DAT communication is completed, send next instruction to sd card
|
||||
(* mark_debug = "true" *)output logic o_ERROR_DAT_TIMES_OUT, // error flag for when DAT times out (so don't fetch more instructions)
|
||||
(* mark_debug = "true" *)output logic o_DAT_ERROR_FD_RST,
|
||||
(* mark_debug = "true" *)output logic o_DAT_ERROR_FD_EN, // tell SD_CMD_FSM to resend command due to error in transmission
|
||||
input logic LIMIT_SD_TIMERS
|
||||
);
|
||||
|
||||
(* mark_debug = "true" *) logic [3:0] r_curr_state;
|
||||
logic [3:0] w_next_state;
|
||||
|
||||
logic r_error_crc16_fd_Q;
|
||||
|
||||
logic [22:0] Identify_Timer_In;
|
||||
logic [22:0] Data_TX_Timer_In;
|
||||
|
||||
localparam logic [3:0] s_reset = 4'b0000;
|
||||
localparam logic [3:0] s_idle = 4'b0001;
|
||||
localparam logic [3:0] s_idle_for_start_bit = 4'b0010;
|
||||
localparam logic [3:0] s_read_r1b = 4'b0011;
|
||||
localparam logic [3:0] s_notify_r1b_completed = 4'b0100;
|
||||
localparam logic [3:0] s_error_time_out = 4'b0101;
|
||||
localparam logic [3:0] s_rx_wide_data = 4'b0110;
|
||||
localparam logic [3:0] s_rx_block_data = 4'b0111;
|
||||
localparam logic [3:0] s_rx_crc16 = 4'b1000;
|
||||
localparam logic [3:0] s_error_crc16_fail = 4'b1001;
|
||||
localparam logic [3:0] s_publish_block_data = 4'b1010;
|
||||
localparam logic [3:0] s_publish_wide_data = 4'b1011;
|
||||
localparam logic [3:0] s_reset_wide_data = 4'b1100;
|
||||
localparam logic [3:0] s_reset_block_data = 4'b1101;
|
||||
localparam logic [3:0] s_reset_nibble_counter = 4'b1110; // Before publishing CMD17 Block Data
|
||||
|
||||
localparam logic [1:0] c_DAT_none = 2'b00;
|
||||
localparam logic [1:0] c_DAT_busy = 2'b01;
|
||||
localparam logic [1:0] c_DAT_wide = 2'b10;
|
||||
localparam logic [1:0] c_DAT_block = 2'b11;
|
||||
|
||||
localparam logic c_start_bit = 0;
|
||||
localparam logic c_busy_bit = 0;
|
||||
|
||||
// load values in for timers and counters
|
||||
localparam logic c_slow_clock = 1'b1; // use during initialization (card identification mode)
|
||||
localparam logic c_HS_clock = 1'b0; // use after CMD6 switches clock frequency (CMD17)
|
||||
|
||||
|
||||
logic TIMER_OUT_GT_0;
|
||||
logic TIMER_OUT_EQ_0;
|
||||
logic COUNTER_OUT_EQ_1023;
|
||||
logic COUNTER_OUT_LT_1023;
|
||||
logic COUNTER_OUT_LT_128;
|
||||
logic COUNTER_OUT_EQ_128;
|
||||
logic COUNTER_OUT_LT_144;
|
||||
logic COUNTER_OUT_EQ_144;
|
||||
logic COUNTER_OUT_LT_1040;
|
||||
logic COUNTER_OUT_EQ_1040;
|
||||
|
||||
|
||||
assign Identify_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b00000001001110001000000; // 40,000 unsigned.
|
||||
assign Data_TX_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b11110100001001000000000; // 8,000,000 unsigned.
|
||||
|
||||
flopenr #(4) stateReg(.clk(CLK),
|
||||
.reset(i_RST),
|
||||
.en(1'b1),
|
||||
.d(w_next_state),
|
||||
.q(r_curr_state));
|
||||
|
||||
assign TIMER_OUT_GT_0 = i_TIMER_OUT > 0;
|
||||
assign TIMER_OUT_EQ_0 = i_TIMER_OUT == 0;
|
||||
assign COUNTER_OUT_EQ_1023 = i_COUNTER_OUT == 1023;
|
||||
assign COUNTER_OUT_LT_1023 = i_COUNTER_OUT < 1023;
|
||||
assign COUNTER_OUT_LT_128 = i_COUNTER_OUT < 128;
|
||||
assign COUNTER_OUT_EQ_128 = i_COUNTER_OUT == 128;
|
||||
assign COUNTER_OUT_LT_144 = i_COUNTER_OUT < 144;
|
||||
assign COUNTER_OUT_EQ_144 = i_COUNTER_OUT == 144;
|
||||
assign COUNTER_OUT_LT_1040 = i_COUNTER_OUT < 1040;
|
||||
assign COUNTER_OUT_EQ_1040 = i_COUNTER_OUT == 1040;
|
||||
|
||||
assign w_next_state = ((i_RST) |
|
||||
(r_curr_state == s_error_time_out) | // noticed this change is needed during emulation
|
||||
(r_curr_state == s_notify_r1b_completed) |
|
||||
(r_curr_state == s_error_crc16_fail) |
|
||||
(r_curr_state == s_publish_wide_data) |
|
||||
((r_curr_state == s_publish_block_data) & (COUNTER_OUT_EQ_1023))) ? s_reset :
|
||||
|
||||
((r_curr_state == s_reset) |
|
||||
((r_curr_state == s_idle) & ((i_USES_DAT == c_DAT_none) | ((i_USES_DAT != c_DAT_none) & (~i_CMD_TX_DONE))))) ? s_idle :
|
||||
|
||||
((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_wide) & (i_CMD_TX_DONE)) ? s_reset_wide_data :
|
||||
|
||||
((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_block) & (i_CMD_TX_DONE)) ? s_reset_block_data :
|
||||
|
||||
((r_curr_state == s_reset_wide_data) |
|
||||
((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_busy) & (i_CMD_TX_DONE)) |
|
||||
(r_curr_state == s_reset_block_data) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q != c_start_bit))) ? s_idle_for_start_bit :
|
||||
|
||||
((r_curr_state == s_idle_for_start_bit) & // Apparently R1b's busy signal is optional,
|
||||
(TIMER_OUT_EQ_0) & // Even if it never shows up,
|
||||
(i_USES_DAT == c_DAT_busy)) ? s_notify_r1b_completed : // pretend it did, & move on
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) &
|
||||
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_busy)) |
|
||||
((r_curr_state == s_read_r1b) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b :
|
||||
|
||||
(((r_curr_state == s_read_r1b) & (TIMER_OUT_EQ_0)) |
|
||||
((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_EQ_0) &
|
||||
(i_USES_DAT != c_DAT_busy))) ? s_error_time_out :
|
||||
|
||||
((r_curr_state == s_read_r1b) & (i_DAT0_Q != c_busy_bit)) ? s_notify_r1b_completed :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_start_bit) &
|
||||
(i_USES_DAT == c_DAT_wide)) |
|
||||
((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_LT_128))) ? s_rx_wide_data :
|
||||
|
||||
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) &
|
||||
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_block)) |
|
||||
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_LT_1023))) ? s_rx_block_data :
|
||||
|
||||
(((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_EQ_128)) |
|
||||
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_EQ_1023)) |
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_LT_144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_LT_1040))))) ? s_rx_crc16 :
|
||||
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144)) |
|
||||
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040))) &
|
||||
(~i_DATA_CRC16_GOOD)) ? s_error_crc16_fail :
|
||||
|
||||
((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144) &
|
||||
(i_DATA_CRC16_GOOD)) ? s_publish_wide_data :
|
||||
|
||||
((r_curr_state == s_rx_crc16) &
|
||||
(i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040) & (i_DATA_CRC16_GOOD)) ? s_reset_nibble_counter :
|
||||
|
||||
((r_curr_state == s_reset_nibble_counter)) ? s_publish_block_data :
|
||||
|
||||
s_reset;
|
||||
|
||||
assign o_TIMER_IN = (r_curr_state == s_reset) & (i_SD_CLK_SELECTED == c_slow_clock) ? Identify_Timer_In : Data_TX_Timer_In;
|
||||
|
||||
assign o_TIMER_LOAD = ((r_curr_state == s_reset) |
|
||||
(r_curr_state == s_reset_block_data));
|
||||
|
||||
assign o_TIMER_EN = ((r_curr_state == s_idle_for_start_bit) |
|
||||
(r_curr_state == s_read_r1b));
|
||||
|
||||
// Nibble Counter module
|
||||
assign o_COUNTER_RST = (r_curr_state == s_reset) | (r_curr_state == s_reset_nibble_counter);
|
||||
|
||||
assign o_COUNTER_EN = ((r_curr_state == s_rx_block_data) |
|
||||
(r_curr_state == s_rx_wide_data) |
|
||||
(r_curr_state == s_rx_crc16)) | (r_curr_state == s_publish_block_data);
|
||||
|
||||
// CRC16 Generation module
|
||||
assign o_CRC16_RST = (r_curr_state == s_reset);
|
||||
|
||||
assign o_CRC16_EN = ((r_curr_state == s_rx_block_data) |
|
||||
(r_curr_state == s_rx_wide_data) |
|
||||
(r_curr_state == s_rx_crc16));
|
||||
|
||||
// Flip Flop Module (for R1b)
|
||||
assign o_BUSY_RST = (r_curr_state == s_reset);
|
||||
|
||||
//o_BUSY_EN = '1' when ((r_curr_state == s_idle_for_start_bit) |
|
||||
// (r_curr_state == s_read_r1b)) else
|
||||
// '0';
|
||||
assign o_BUSY_EN = 1'b1; // Always sample data
|
||||
|
||||
// DAT Storage Modules
|
||||
assign o_NIBO_EN = (r_curr_state == s_rx_block_data);
|
||||
|
||||
// To sd_cmd_fsm
|
||||
assign o_DAT_RX_DONE = ((r_curr_state == s_error_time_out) |
|
||||
(r_curr_state == s_notify_r1b_completed) |
|
||||
(r_curr_state == s_error_crc16_fail) |
|
||||
(r_curr_state == s_publish_wide_data) |
|
||||
(r_curr_state == s_publish_block_data));
|
||||
|
||||
assign o_ERROR_DAT_TIMES_OUT = (r_curr_state == s_error_time_out);
|
||||
|
||||
|
||||
// o_RESEND_READ_WIDE (Error! This is not defined. Indicates switch command must be re-rent),
|
||||
// should be a function of block busy logic
|
||||
|
||||
// For Communication with core
|
||||
assign o_DATA_VALID = (r_curr_state == s_publish_block_data);
|
||||
|
||||
assign o_LAST_NIBBLE = ((r_curr_state == s_publish_block_data)
|
||||
& (COUNTER_OUT_EQ_1023)) | (r_curr_state == s_error_time_out); // notify done if errors occur
|
||||
|
||||
// o_ERROR_CRC16 (note: saved to flip flop because otherwise is only 1 clock cycle, not what I want)
|
||||
assign o_DAT_ERROR_FD_RST = (r_curr_state == s_reset_block_data) | (r_curr_state == s_reset_wide_data);
|
||||
assign o_DAT_ERROR_FD_EN = (r_curr_state == s_rx_crc16);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
endmodule
|
@ -1,652 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// sd_top.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 19, 2021
|
||||
//
|
||||
// Purpose: SD card controller
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module sd_top #(parameter g_COUNT_WIDTH = 8) (
|
||||
input logic CLK, // 1.2 GHz (1.0 GHz typical)
|
||||
input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles)
|
||||
// a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK!
|
||||
// io_SD_CMD_z : inout std_logic; // SD CMD Bus
|
||||
(* mark_debug = "true" *)input logic i_SD_CMD, // CMD Response from card
|
||||
(* mark_debug = "true" *)output logic o_SD_CMD, // CMD Command from host
|
||||
(* mark_debug = "true" *)output logic o_SD_CMD_OE, // Direction of SD_CMD
|
||||
(* mark_debug = "true" *)input logic [3:0] i_SD_DAT, // SD DAT Bus
|
||||
(* mark_debug = "true" *)output logic o_SD_CLK, // SD CLK Bus
|
||||
// For communication with core cpu
|
||||
input logic [32:9] i_BLOCK_ADDR, // see "Addressing" in parts.fods (only 8GB total capacity is used)
|
||||
output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and
|
||||
// sd card is ready to read a 512 byte block to the core.
|
||||
// Held high during idle until i_READ_REQUEST is received
|
||||
output logic o_SD_RESTARTING, // inform core the need to restart
|
||||
|
||||
input logic i_READ_REQUEST, // After Ready for read is sent to the core, the core will
|
||||
// pulse this bit high to indicate it wants the block at this address
|
||||
output logic [3:0] o_DATA_TO_CORE, // nibble being sent to core when DATA block is
|
||||
output logic [4095:0] ReadData, // full 512 bytes to Bus
|
||||
// being published
|
||||
output logic o_DATA_VALID, // held high while data being read to core to indicate that it is valid
|
||||
output logic o_LAST_NIBBLE, // pulse when last nibble is sent
|
||||
output logic [2:0] o_ERROR_CODE_Q, // indicates which error occured
|
||||
output logic o_FATAL_ERROR, // indicates that the FATAL ERROR register has updated
|
||||
// For tuning
|
||||
input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX,
|
||||
input logic LIMIT_SD_TIMERS
|
||||
);
|
||||
|
||||
localparam logic c_CMD = 1'b0;
|
||||
localparam logic c_ACMD = 1'b1;
|
||||
|
||||
// packet bit names
|
||||
localparam logic c_start_bit = 1'b0; // bit 47
|
||||
localparam logic c_stop_bit = 1'b1; // bit 0, AKA "end bit"
|
||||
// transmitter bit, bit 46
|
||||
localparam logic c_tx_host_command = 1'b1;
|
||||
localparam logic c_tx_card_response = 1'b0;
|
||||
|
||||
// response types
|
||||
localparam logic [2:0] c_response_type_R0_NONE = 3'd0;
|
||||
localparam logic [2:0] c_response_type_R1_NORMAL = 3'd1;
|
||||
localparam logic [2:0] c_response_type_R2_CID_CSD = 3'd2;
|
||||
localparam logic [2:0] c_response_type_R3_OCR = 3'd3;
|
||||
localparam logic [2:0] c_response_type_R6_RCA = 3'd6;
|
||||
localparam logic [2:0] c_response_type_R7_CIC = 3'd7;
|
||||
|
||||
// uses dat
|
||||
localparam logic [1:0] c_DAT_none = 2'b00;
|
||||
localparam logic [1:0] c_DAT_busy = 2'b01;
|
||||
localparam logic [1:0] c_DAT_wide = 2'b10;
|
||||
localparam logic [1:0] c_DAT_block = 2'b11;
|
||||
|
||||
// tx source selection
|
||||
localparam logic [1:0] c_tx_low = 2'b00;
|
||||
localparam logic [1:0] c_tx_high = 2'b01;
|
||||
localparam logic [1:0] c_tx_head = 2'b10;
|
||||
localparam logic [1:0] c_tx_tail = 2'b11;
|
||||
|
||||
// command indexes
|
||||
localparam logic [45:40] c_Go_Idle_State = 6'd00; // CMD0
|
||||
localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2
|
||||
localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3
|
||||
localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6
|
||||
localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6
|
||||
localparam logic [45:40] c_Select_Card = 6'd07; // CMD7
|
||||
localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8
|
||||
localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17
|
||||
localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41
|
||||
localparam logic [45:40] c_App_Command = 6'd55; // CMD55
|
||||
|
||||
// bitmasks
|
||||
localparam logic [127:96] c_CMD0_mask_check_redo_bits = 32'h00000000; // Go_Idle_State
|
||||
localparam logic [127:96] c_CMD0_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD0_mask_check_error_bits = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD0_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_CMD2_mask_check_redo_bits = 32'h00000000; // All_Send_CID
|
||||
localparam logic [127:96] c_CMD2_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD2_mask_check_error_bits = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD2_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_CMD3_mask_check_redo_bits = 32'h00000000; // SD_Send_RCA
|
||||
localparam logic [127:96] c_CMD3_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD3_mask_check_error_bits = 32'h00002000;
|
||||
localparam logic [127:96] c_CMD3_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_CMD6_mask_check_redo_bits = 32'h00000000; // Switch_Function
|
||||
localparam logic [127:96] c_CMD6_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD6_mask_check_error_bits = 32'h82380000;
|
||||
localparam logic [127:96] c_CMD6_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_ACMD6_mask_check_redo_bits = 32'h00000000; // Set_Bus_Width
|
||||
localparam logic [127:96] c_ACMD6_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_ACMD6_mask_check_error_bits = 32'h8F398020;
|
||||
localparam logic [127:96] c_ACMD6_ans_error_free = 32'h00000020;
|
||||
|
||||
localparam logic [127:96] c_CMD7_mask_check_redo_bits = 32'h00000000; // Select_Card
|
||||
localparam logic [127:96] c_CMD7_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD7_mask_check_error_bits = 32'h0F398000;
|
||||
localparam logic [127:96] c_CMD7_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_CMD8_mask_check_redo_bits = 32'h00000000; // Send_IF_State
|
||||
localparam logic [127:96] c_CMD8_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD8_mask_check_error_bits = 32'h00000FFF;
|
||||
localparam logic [127:96] c_CMD8_ans_error_free = 32'h000001FF;
|
||||
|
||||
localparam logic [127:96] c_CMD17_mask_check_redo_bits = 32'h00000000; // Read_Single_Block
|
||||
localparam logic [127:96] c_CMD17_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD17_mask_check_error_bits = 32'hCF398000;
|
||||
localparam logic [127:96] c_CMD17_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_ACMD41_mask_check_redo_bits = 32'h80000000; //32'h80000000; // SD_Send_OCR
|
||||
localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000; //32'h80000000;
|
||||
localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h41FF8000; // 32'h41FF8000;
|
||||
localparam logic [127:96] c_ACMD41_ans_error_free = 32'h40FF8000; // 32'h40FF8000
|
||||
|
||||
localparam logic [127:96] c_CMD55_mask_check_redo_bits = 32'h00000000; // App_Command
|
||||
localparam logic [127:96] c_CMD55_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_CMD55_mask_check_error_bits = 32'h0F398000;
|
||||
localparam logic [127:96] c_CMD55_ans_error_free = 32'h00000000;
|
||||
|
||||
localparam logic [127:96] c_ACMD55_mask_check_redo_bits = 32'h00000000; // App_Command
|
||||
localparam logic [127:96] c_ACMD55_ans_dont_redo = 32'h00000000;
|
||||
localparam logic [127:96] c_ACMD55_mask_check_error_bits = 32'h0F398000;
|
||||
localparam logic [127:96] c_ACMD55_ans_error_free = 32'h00000000;
|
||||
|
||||
// SD_CMD_FSM Connections
|
||||
logic w_TIMER_LOAD, w_TIMER_EN;
|
||||
logic [18:0] w_TIMER_IN;
|
||||
logic [18:0] r_TIMER_OUT;
|
||||
logic w_COUNTER_LOAD, w_COUNTER_EN;
|
||||
logic [7:0] w_COUNTER_IN;
|
||||
logic [7:0] r_COUNTER_OUT;
|
||||
logic w_SD_CLK_EN;
|
||||
logic w_CLOCK_CHANGE_DONE, w_START_CLOCK_CHANGE; // to clk fsm
|
||||
logic w_HS_TO_INIT_CLK_DIVIDER_RST;
|
||||
(* mark_debug = "true" *)logic w_IC_RST, w_IC_EN, w_IC_UP_DOWN;
|
||||
(* mark_debug = "true" *)logic w_SD_CMD_OE;
|
||||
logic w_TX_PISO40_LOAD, w_TX_PISO40_EN;
|
||||
logic w_TX_PISO8_LOAD, w_TX_PISO8_EN;
|
||||
logic w_TX_CRC7_PIPO_RST, w_TX_CRC7_PIPO_EN;
|
||||
logic [1:0] w_TX_SOURCE_SELECT;
|
||||
logic w_CMD_TX_IS_CMD55_RST;
|
||||
logic w_CMD_TX_IS_CMD55_EN;
|
||||
logic w_RX_SIPO48_RST, w_RX_SIPO48_EN;
|
||||
(* mark_debug = "true" *)logic [39:8] r_RESPONSE_CONTENT;
|
||||
(* mark_debug = "true" *)logic [45:40] r_RESPONSE_INDEX;
|
||||
logic w_RX_CRC7_SIPO_RST, w_RX_CRC7_SIPO_EN;
|
||||
logic [6:0] r_RX_CRC7_Q;
|
||||
logic w_RCA_REGISTER_RST, w_RCA_REGISTER_EN;
|
||||
logic w_CMD_TX_DONE;
|
||||
logic w_DAT_RX_DONE;
|
||||
logic w_DAT_ERROR_FD_RST_DAT, w_DAT_ERROR_FD_RST_CMD, w_DAT_ERROR_FD_RST, w_DAT_ERROR_FD_EN;
|
||||
(* mark_debug = "true" *)logic r_DAT_ERROR_Q; // CRC16 error or time out
|
||||
(* mark_debug = "true" *)logic w_NOT_DAT_ERROR_Q; // '0'=no error, '1'=tx error on DAT bus
|
||||
(* mark_debug = "true" *)logic w_ERROR_DAT_TIMES_OUT;
|
||||
(* mark_debug = "true" *)logic w_FATAL_ERROR;
|
||||
(* mark_debug = "true" *)logic [2:0] r_ERROR_CODE_Q; // indicates which fatal error occured
|
||||
|
||||
// Communication with core
|
||||
(* mark_debug = "true" *)logic w_READY_FOR_READ;
|
||||
(* mark_debug = "true" *)logic w_READ_REQUEST;
|
||||
(* mark_debug = "true" *)logic [3:0] r_DATA_TO_CORE;
|
||||
(* mark_debug = "true" *)logic w_DATA_VALID;
|
||||
(* mark_debug = "true" *)logic w_LAST_NIBBLE;
|
||||
|
||||
//SD_DAT_FSM Connections
|
||||
logic w_DAT_TIMER_LOAD, w_DAT_TIMER_EN;
|
||||
logic w_DAT_COUNTER_RST, w_DAT_COUNTER_EN;
|
||||
logic w_CRC16_EN, w_CRC16_RST;
|
||||
logic w_BUSY_RST, w_BUSY_EN;
|
||||
logic w_NIBO_EN;
|
||||
logic w_DATA_CRC16_GOOD;
|
||||
logic [22:0] w_DAT_TIMER_IN;
|
||||
logic [22:0] r_DAT_TIMER_OUT;
|
||||
logic [10:0] r_DAT_COUNTER_OUT;
|
||||
(* mark_debug = "true" *)logic [3:0] r_DAT_Q;
|
||||
|
||||
// RCA Register
|
||||
logic [15:0] w_RCA_D_Q;
|
||||
logic [15:0] r_RCA_Q2;
|
||||
|
||||
// Multiplexer Logics
|
||||
logic [132:0] w_instruction_control_bits;
|
||||
logic [132:130] w_R_TYPE ;
|
||||
logic [129:128] w_USES_DAT ;
|
||||
logic [127:96] w_NO_REDO_MASK ;
|
||||
logic [95:64] w_NO_REDO_ANS ;
|
||||
logic [63:32] w_NO_ERROR_MASK ;
|
||||
logic [31:0] w_NO_ERROR_ANS ;
|
||||
logic [45:40] w_command_index ;
|
||||
logic [39:8] w_command_arguments ;
|
||||
logic [47:8] w_command_head ;
|
||||
(* mark_debug = "true" *)logic [6:0] w_OPCODE_Q ;
|
||||
|
||||
// TOP_LEVEL Connections
|
||||
logic [40:9] w_BLOCK_ADDR ;
|
||||
(* mark_debug = "true" *)logic [3:0] r_IC_OUT ;
|
||||
logic [2:0] r_command_index_is_55_history ; // [0] is live index, [1] is currently saved index, [2] is index of previous command
|
||||
logic r_previous_command_index_was_55_q; // is index of previous command 55, wired to r_command_index_is_55_history[2]
|
||||
logic r_ACMD_Q; // if the previous command sent to the SD card successfully had index 55, then the SD card thinks the current command is ACMD
|
||||
|
||||
// TX
|
||||
logic [45:8] w_command_content; // first 40 bits of command packet
|
||||
logic w_tx_head_Q; // transmission of first part of command packet
|
||||
logic w_tx_tail_Q; // transmission of last part of command packet
|
||||
logic [7:0] r_command_tail; // last 8 bits of command packet
|
||||
logic [6:0] r_TX_CRC7;
|
||||
|
||||
// RX
|
||||
logic [47:0] r_RX_RESPONSE;
|
||||
|
||||
// Tri state IO Driver BC18MIMS
|
||||
logic w_SD_CMD_TX_Q; // Write Data
|
||||
logic w_SD_CMD_RX; // Read Data
|
||||
|
||||
|
||||
// CLOCKS
|
||||
//logic r_CLK_HS := '0'; // 50 MHz Divided Clock [static]
|
||||
//logic r_SD_CLK_ungated := '0'; // Selected clock before it is clock gated
|
||||
|
||||
//logic r_SD_CLK := '0'; // GATED CLOCKS
|
||||
logic r_TO_SD_CLK; // What is actually sent to the SD card
|
||||
|
||||
logic w_G_CLK_SD_EN;
|
||||
logic r_CLK_SD, r_G_CLK_SD; // clocks
|
||||
logic [15:0] r_CLK_FSM_RST ; // a_rst logic delayed by one 1.2 GHz period
|
||||
logic w_SD_CLK_SELECTED;
|
||||
|
||||
//DAT FSM Connections
|
||||
logic [15:0] r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16;
|
||||
logic [15:0] r_DAT0_CRC16;
|
||||
|
||||
assign w_BLOCK_ADDR = {8'h00, i_BLOCK_ADDR}; // (40 downto 36 are zero since card is 64 GB)
|
||||
// (35 downto 32 are zero since memeory is only 8GB total)
|
||||
|
||||
assign o_READY_FOR_READ = w_READY_FOR_READ;
|
||||
assign w_READ_REQUEST = i_READ_REQUEST;
|
||||
assign o_DATA_TO_CORE = r_DATA_TO_CORE;
|
||||
assign o_DATA_VALID = w_DATA_VALID;
|
||||
assign o_LAST_NIBBLE = (w_LAST_NIBBLE | w_FATAL_ERROR); // indicate done if (last nibble OR Fatal Error go high)
|
||||
assign o_FATAL_ERROR = w_FATAL_ERROR;
|
||||
|
||||
sd_cmd_fsm my_sd_cmd_fsm
|
||||
(
|
||||
.CLK(r_G_CLK_SD),
|
||||
.i_RST(a_RST),
|
||||
.o_TIMER_LOAD(w_TIMER_LOAD),
|
||||
.o_TIMER_EN(w_TIMER_EN),
|
||||
.o_TIMER_IN(w_TIMER_IN),
|
||||
.i_TIMER_OUT(r_TIMER_OUT),
|
||||
.o_COUNTER_LOAD(w_COUNTER_LOAD),
|
||||
.o_COUNTER_EN(w_COUNTER_EN),
|
||||
.o_COUNTER_IN(w_COUNTER_IN),
|
||||
.i_COUNTER_OUT(r_COUNTER_OUT),
|
||||
.o_SD_CLK_EN(w_SD_CLK_EN),
|
||||
.i_CLOCK_CHANGE_DONE(w_CLOCK_CHANGE_DONE),
|
||||
.o_START_CLOCK_CHANGE(w_START_CLOCK_CHANGE),
|
||||
.o_IC_RST(w_IC_RST),
|
||||
.o_IC_EN(w_IC_EN),
|
||||
.o_IC_UP_DOWN(w_IC_UP_DOWN),
|
||||
.i_IC_OUT(r_IC_OUT),
|
||||
.i_USES_DAT(w_USES_DAT),
|
||||
.i_OPCODE(w_OPCODE_Q),
|
||||
.i_R_TYPE(w_R_TYPE),
|
||||
.i_NO_REDO_MASK(w_NO_REDO_MASK),
|
||||
.i_NO_REDO_ANS(w_NO_REDO_ANS),
|
||||
.i_NO_ERROR_MASK(w_NO_ERROR_MASK),
|
||||
.i_NO_ERROR_ANS(w_NO_ERROR_ANS),
|
||||
.o_SD_CMD_OE(w_SD_CMD_OE),
|
||||
.o_TX_PISO40_LOAD(w_TX_PISO40_LOAD),
|
||||
.o_TX_PISO40_EN(w_TX_PISO40_EN),
|
||||
.o_TX_PISO8_LOAD(w_TX_PISO8_LOAD),
|
||||
.o_TX_PISO8_EN(w_TX_PISO8_EN),
|
||||
.o_TX_CRC7_PIPO_RST(w_TX_CRC7_PIPO_RST),
|
||||
.o_TX_CRC7_PIPO_EN(w_TX_CRC7_PIPO_EN),
|
||||
.o_TX_SOURCE_SELECT(w_TX_SOURCE_SELECT),
|
||||
.o_CMD_TX_IS_CMD55_RST(w_CMD_TX_IS_CMD55_RST),
|
||||
.o_CMD_TX_IS_CMD55_EN(w_CMD_TX_IS_CMD55_EN),
|
||||
.i_SD_CMD_RX(w_SD_CMD_RX),
|
||||
.o_RX_SIPO48_RST(w_RX_SIPO48_RST),
|
||||
.o_RX_SIPO48_EN(w_RX_SIPO48_EN),
|
||||
.i_RESPONSE_CONTENT(r_RESPONSE_CONTENT),
|
||||
.i_RESPONSE_INDEX(r_RESPONSE_INDEX),
|
||||
.o_RX_CRC7_SIPO_RST(w_RX_CRC7_SIPO_RST),
|
||||
.o_RX_CRC7_SIPO_EN(w_RX_CRC7_SIPO_EN),
|
||||
.i_RX_CRC7(r_RX_CRC7_Q),
|
||||
.o_RCA_REGISTER_RST(w_RCA_REGISTER_RST),
|
||||
.o_RCA_REGISTER_EN(w_RCA_REGISTER_EN),
|
||||
.o_CMD_TX_DONE(w_CMD_TX_DONE),
|
||||
.i_DAT_RX_DONE(w_DAT_RX_DONE),
|
||||
.i_ERROR_CRC16(w_NOT_DAT_ERROR_Q),
|
||||
.i_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT),
|
||||
.i_READ_REQUEST(w_READ_REQUEST),
|
||||
.o_READY_FOR_READ(w_READY_FOR_READ),
|
||||
.o_SD_RESTARTING(o_SD_RESTARTING),
|
||||
.o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_CMD),
|
||||
.o_ERROR_CODE_Q(r_ERROR_CODE_Q),
|
||||
.o_FATAL_ERROR(w_FATAL_ERROR),
|
||||
.LIMIT_SD_TIMERS(LIMIT_SD_TIMERS));
|
||||
|
||||
assign o_ERROR_CODE_Q = r_ERROR_CODE_Q;
|
||||
|
||||
sd_dat_fsm my_sd_dat_fsm
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.i_RST(a_RST),
|
||||
.o_TIMER_LOAD(w_DAT_TIMER_LOAD),
|
||||
.o_TIMER_EN(w_DAT_TIMER_EN),
|
||||
.o_TIMER_IN(w_DAT_TIMER_IN),
|
||||
.i_TIMER_OUT(r_DAT_TIMER_OUT),
|
||||
.i_SD_CLK_SELECTED(w_SD_CLK_SELECTED),
|
||||
.o_COUNTER_RST(w_DAT_COUNTER_RST),
|
||||
.o_COUNTER_EN(w_DAT_COUNTER_EN),
|
||||
.i_COUNTER_OUT(r_DAT_COUNTER_OUT),
|
||||
.o_CRC16_EN(w_CRC16_EN),
|
||||
.o_CRC16_RST(w_CRC16_RST),
|
||||
.i_DATA_CRC16_GOOD(w_DATA_CRC16_GOOD),
|
||||
.o_BUSY_RST(w_BUSY_RST),
|
||||
.o_BUSY_EN(w_BUSY_EN),
|
||||
.i_DAT0_Q(r_DAT_Q[0]),
|
||||
.o_NIBO_EN(w_NIBO_EN),
|
||||
.i_USES_DAT(w_USES_DAT),
|
||||
.i_CMD_TX_DONE(w_CMD_TX_DONE),
|
||||
.o_DAT_RX_DONE(w_DAT_RX_DONE),
|
||||
.o_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT),
|
||||
.o_DATA_VALID(w_DATA_VALID),
|
||||
.o_LAST_NIBBLE(w_LAST_NIBBLE),
|
||||
.o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_DAT),
|
||||
.o_DAT_ERROR_FD_EN(w_DAT_ERROR_FD_EN),
|
||||
.LIMIT_SD_TIMERS(LIMIT_SD_TIMERS));
|
||||
|
||||
assign w_DAT_ERROR_FD_RST = w_DAT_ERROR_FD_RST_CMD | w_DAT_ERROR_FD_RST_DAT;
|
||||
|
||||
flopenr #(1) dat_error_fd
|
||||
(.clk(r_G_CLK_SD),
|
||||
.d(w_DATA_CRC16_GOOD),
|
||||
.q(r_DAT_ERROR_Q),
|
||||
.en(w_DAT_ERROR_FD_EN),
|
||||
.reset((w_DAT_ERROR_FD_RST)));
|
||||
|
||||
assign w_NOT_DAT_ERROR_Q = ~r_DAT_ERROR_Q;
|
||||
|
||||
up_down_counter #(23) dat_fsm_timer
|
||||
(
|
||||
.CountIn(w_DAT_TIMER_IN),
|
||||
.CountOut(r_DAT_TIMER_OUT),
|
||||
.Load(w_DAT_TIMER_LOAD),
|
||||
.Enable(w_DAT_TIMER_EN),
|
||||
.UpDown(1'b0), // Count DOWN only
|
||||
.clk(r_G_CLK_SD),
|
||||
.reset(1'b0)); // No Reset, Just Load
|
||||
|
||||
SDCcounter #(11) dat_nibble_counter
|
||||
(
|
||||
.CountIn('0),
|
||||
.CountOut(r_DAT_COUNTER_OUT),
|
||||
.Load(1'b0),
|
||||
.Enable(w_DAT_COUNTER_EN),
|
||||
.clk(r_G_CLK_SD),
|
||||
.reset(w_DAT_COUNTER_RST));
|
||||
|
||||
regfile_p2r1w1_nibo #(.DEPTH(10), .WIDTH(4) ) regfile_cmd17_data_block // Nibble In - Nibble Out (NINO)
|
||||
(.clk(r_G_CLK_SD),
|
||||
.we1(w_NIBO_EN),
|
||||
.ra1(r_DAT_COUNTER_OUT[9:0]), // Nibble Read (to core) Address
|
||||
.rd1(r_DATA_TO_CORE), // output nibble to core
|
||||
.Rd1All(ReadData),
|
||||
.wa1(r_DAT_COUNTER_OUT[9:0]), // Nibble Write (to host) Address
|
||||
.wd1(r_DAT_Q)); // input nibble from card
|
||||
|
||||
crc16_sipo_np_ce crc16_sipo_np_ce_DAT3
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.RST(w_CRC16_RST),
|
||||
.i_enable(w_CRC16_EN),
|
||||
.i_message_bit(r_DAT_Q[3]),
|
||||
.o_crc16(r_DAT3_CRC16));
|
||||
|
||||
crc16_sipo_np_ce crc16_sipo_np_ce_DAT2
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.RST(w_CRC16_RST),
|
||||
.i_enable(w_CRC16_EN),
|
||||
.i_message_bit(r_DAT_Q[2]),
|
||||
.o_crc16(r_DAT2_CRC16));
|
||||
|
||||
crc16_sipo_np_ce crc16_sipo_np_ce_DAT1
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.RST(w_CRC16_RST),
|
||||
.i_enable(w_CRC16_EN),
|
||||
.i_message_bit(r_DAT_Q[1]),
|
||||
.o_crc16(r_DAT1_CRC16));
|
||||
|
||||
crc16_sipo_np_ce crc16_sipo_np_ce_DAT0
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.RST(w_CRC16_RST),
|
||||
.i_enable(w_CRC16_EN),
|
||||
.i_message_bit(r_DAT_Q[0]),
|
||||
.o_crc16(r_DAT0_CRC16));
|
||||
|
||||
|
||||
assign w_DATA_CRC16_GOOD = ({r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16, r_DAT0_CRC16}) == 64'h0000000000000000;
|
||||
|
||||
flopenr #(4) busy_bit_fd
|
||||
(.en(w_BUSY_EN),
|
||||
.clk(r_G_CLK_SD),
|
||||
.d(i_SD_DAT),
|
||||
.q(r_DAT_Q),
|
||||
.reset(w_BUSY_RST));
|
||||
|
||||
sd_clk_fsm my_clk_fsm
|
||||
(.CLK(CLK),
|
||||
.i_RST(a_RST),
|
||||
.o_DONE(w_CLOCK_CHANGE_DONE),
|
||||
.i_START(w_START_CLOCK_CHANGE),
|
||||
.o_HS_TO_INIT_CLK_DIVIDER_RST(w_HS_TO_INIT_CLK_DIVIDER_RST),
|
||||
.o_SD_CLK_SELECTED(w_SD_CLK_SELECTED),
|
||||
.i_FATAL_ERROR(w_FATAL_ERROR),
|
||||
.o_G_CLK_SD_EN(w_G_CLK_SD_EN));
|
||||
|
||||
up_down_counter #(19) cmd_fsm_timer
|
||||
(.CountIn(w_TIMER_IN),
|
||||
.CountOut(r_TIMER_OUT),
|
||||
.Load(w_TIMER_LOAD),
|
||||
.Enable(w_TIMER_EN),
|
||||
.UpDown(1'b0), // Count DOWN only
|
||||
.clk(r_G_CLK_SD),
|
||||
.reset(1'b0)); // No Reset, Just Load
|
||||
|
||||
up_down_counter #(8) cmd_fsm_counter
|
||||
(.CountIn(w_COUNTER_IN),
|
||||
.CountOut(r_COUNTER_OUT),
|
||||
.Load(w_COUNTER_LOAD),
|
||||
.Enable(w_COUNTER_EN),
|
||||
.UpDown(1'b0), // Count DOWN only
|
||||
.clk(r_G_CLK_SD),
|
||||
.reset(1'b0)); // No RESET, only LOAD
|
||||
|
||||
up_down_counter #(4) instruction_counter
|
||||
(.CountIn('0), // No CountIn, only RESET
|
||||
.CountOut(r_IC_OUT),
|
||||
.Load(1'b0), // No LOAD, only RESET
|
||||
.Enable(w_IC_EN),
|
||||
.UpDown(w_IC_UP_DOWN),
|
||||
.clk(r_G_CLK_SD),
|
||||
.reset(w_IC_RST | a_RST));
|
||||
|
||||
// Clock selection
|
||||
clkdivider #(g_COUNT_WIDTH) slow_clk_divider // Divide 50 MHz to <400 KHz (Initial clock)
|
||||
(.i_COUNT_IN_MAX(i_COUNT_IN_MAX),
|
||||
.i_EN(w_SD_CLK_SELECTED),
|
||||
//.i_EN(1'b1),
|
||||
//.i_RST(w_HS_TO_INIT_CLK_DIVIDER_RST),
|
||||
.i_RST(a_RST),
|
||||
.i_CLK(CLK),
|
||||
.o_CLK(r_CLK_SD));
|
||||
|
||||
clockgater sd_clk_gater // Select which clock goes to components
|
||||
(.CLK(r_CLK_SD),
|
||||
.E(w_G_CLK_SD_EN | a_RST),
|
||||
.SE(1'b0),
|
||||
.ECLK(r_G_CLK_SD));
|
||||
|
||||
clockgater to_sd_clk_gater // Enable activity on the SD_CLK line
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.E(w_SD_CLK_EN),
|
||||
.SE(1'b0),
|
||||
.ECLK(r_TO_SD_CLK));
|
||||
|
||||
flopenr #(16) RCA_register_CE
|
||||
(.clk(r_G_CLK_SD),
|
||||
.en(w_RCA_REGISTER_EN),
|
||||
.d(w_RCA_D_Q),
|
||||
.q(r_RCA_Q2),
|
||||
.reset(w_RCA_REGISTER_RST));
|
||||
|
||||
// ACMD_Detector
|
||||
flopenr #(1) index_history_fd_2to1
|
||||
(.clk(r_G_CLK_SD),
|
||||
.reset(w_CMD_TX_IS_CMD55_RST),
|
||||
.en(w_CMD_TX_IS_CMD55_EN),
|
||||
.d(r_command_index_is_55_history[2]),
|
||||
.q(r_command_index_is_55_history[1]));
|
||||
|
||||
flopenr #(1) index_history_fd_1to0
|
||||
(.clk(r_G_CLK_SD),
|
||||
.reset(w_CMD_TX_IS_CMD55_RST),
|
||||
.en(w_CMD_TX_IS_CMD55_EN),
|
||||
.d(r_command_index_is_55_history[1]),
|
||||
.q(r_command_index_is_55_history[0]));
|
||||
|
||||
|
||||
|
||||
assign r_command_index_is_55_history[2] = (w_command_index == 55);
|
||||
|
||||
|
||||
assign r_previous_command_index_was_55_q = r_command_index_is_55_history[0];
|
||||
assign r_ACMD_Q = r_previous_command_index_was_55_q; // if the previous command WAS 55, the current command is ACMD
|
||||
|
||||
assign o_SD_CLK = r_TO_SD_CLK;
|
||||
|
||||
|
||||
|
||||
// Multiplexers
|
||||
//Fetch index and argument of command
|
||||
assign w_command_content = (r_IC_OUT == 0) ? ({c_Go_Idle_State, 32'h00000000}) : // CMD0
|
||||
(r_IC_OUT == 1) ? ({c_Send_IF_State, 32'h000001FF}) : // CMD8
|
||||
(r_IC_OUT == 2) ? ({c_App_Command, 32'h00000000}) : // CMD55
|
||||
(r_IC_OUT == 3) ? ({c_SD_Send_OCR, 32'h40FF8000}) : // ACMD41
|
||||
(r_IC_OUT == 4) ? ({c_All_Send_CID, 32'h00000000}) : // CMD2
|
||||
(r_IC_OUT == 5) ? ({c_SD_Send_RCA, 32'h00000000}) : // CMD3
|
||||
(r_IC_OUT == 6) ? ({c_Select_Card, r_RCA_Q2[15:0], 16'h0000}) : // CMD7
|
||||
(r_IC_OUT == 7) ? ({c_App_Command, r_RCA_Q2[15:0], 16'h0000}) : // CMD55
|
||||
(r_IC_OUT == 8) ? ({c_Set_Bus_Width, 32'h00000002}) : // ACMD6
|
||||
(r_IC_OUT == 9) ? ({c_Switch_Function, 32'h80FFFFF1}) : // CMD6
|
||||
(r_IC_OUT == 10) ? ({c_Read_Single_Block, w_BLOCK_ADDR}) : // CMD17
|
||||
({c_Read_Single_Block, w_BLOCK_ADDR}); // when in doubt just send CMD17
|
||||
|
||||
assign w_command_index = w_command_content[45:40];
|
||||
assign w_command_arguments = w_command_content[39:8];
|
||||
assign w_command_head = {c_start_bit, c_tx_host_command, w_command_content};
|
||||
|
||||
assign w_OPCODE_Q = {r_ACMD_Q, w_command_index};
|
||||
|
||||
// TX
|
||||
|
||||
crc7_pipo tx_crc7_pipo
|
||||
(.CLK(r_G_CLK_SD),
|
||||
.i_DATA(w_command_head),
|
||||
.i_CRC_ENABLE(w_TX_CRC7_PIPO_EN),
|
||||
.RST(w_TX_CRC7_PIPO_RST),
|
||||
.o_CRC(r_TX_CRC7));
|
||||
|
||||
assign r_command_tail = {r_TX_CRC7, c_stop_bit};
|
||||
|
||||
piso_generic_ce #(40) tx_piso40_command_head
|
||||
(.clk(r_G_CLK_SD),
|
||||
.i_load(w_TX_PISO40_LOAD),
|
||||
.i_data(w_command_head),
|
||||
.i_en(w_TX_PISO40_EN),
|
||||
.o_data(w_tx_head_Q));
|
||||
|
||||
piso_generic_ce #(8) tx_piso8_command_tail
|
||||
(.clk(r_G_CLK_SD),
|
||||
.i_load(w_TX_PISO8_LOAD),
|
||||
.i_data(r_command_tail),
|
||||
.i_en(w_TX_PISO8_EN),
|
||||
.o_data(w_tx_tail_Q));
|
||||
|
||||
assign w_SD_CMD_TX_Q = (w_TX_SOURCE_SELECT == c_tx_low) ? 1'b0 :
|
||||
(w_TX_SOURCE_SELECT == c_tx_high) ? 1'b1 :
|
||||
(w_TX_SOURCE_SELECT == c_tx_head) ? w_tx_head_Q :
|
||||
(w_TX_SOURCE_SELECT == c_tx_tail) ? w_tx_tail_Q :
|
||||
1'b0;
|
||||
|
||||
assign w_SD_CMD_RX = i_SD_CMD;
|
||||
|
||||
flopenr #(1) sd_cmd_out_reg
|
||||
(.d(w_SD_CMD_TX_Q),
|
||||
.q(o_SD_CMD),
|
||||
.en(1'b1),
|
||||
.clk(~r_G_CLK_SD),
|
||||
.reset(a_RST));
|
||||
|
||||
flopenr #(1) sd_cmd_out_oe_reg
|
||||
(.d(w_SD_CMD_OE),
|
||||
.q(o_SD_CMD_OE),
|
||||
.en(1'b1),
|
||||
.clk(~r_G_CLK_SD),
|
||||
.reset(a_RST));
|
||||
|
||||
// RX
|
||||
sipo_generic_ce #(48) rx_sipo48_response_content
|
||||
(.clk(r_G_CLK_SD),
|
||||
.rst(w_RX_SIPO48_RST),
|
||||
.i_enable(w_RX_SIPO48_EN),
|
||||
.i_message_bit(w_SD_CMD_RX),
|
||||
.o_data(r_RX_RESPONSE));
|
||||
|
||||
assign r_RESPONSE_CONTENT = r_RX_RESPONSE[39:8];
|
||||
assign r_RESPONSE_INDEX = r_RX_RESPONSE[45:40];
|
||||
assign w_RCA_D_Q = r_RESPONSE_CONTENT[39:24];
|
||||
|
||||
crc7_sipo_np_ce rx_crc7_sipo
|
||||
(.clk(r_G_CLK_SD),
|
||||
.rst(w_RX_CRC7_SIPO_RST),
|
||||
.i_enable(w_RX_CRC7_SIPO_EN),
|
||||
.i_message_bit(w_SD_CMD_RX),
|
||||
.o_crc7(r_RX_CRC7_Q));
|
||||
|
||||
// Fetch control bits using r_opcode
|
||||
assign w_instruction_control_bits = (w_OPCODE_Q == ({c_CMD, c_Go_Idle_State})) ? ({c_response_type_R0_NONE, c_DAT_none, c_CMD0_mask_check_redo_bits, c_CMD0_ans_dont_redo, c_CMD0_mask_check_error_bits, c_CMD0_ans_error_free}) : // CMD0
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_All_Send_CID})) ? ({c_response_type_R2_CID_CSD, c_DAT_none, c_CMD2_mask_check_redo_bits, c_CMD2_ans_dont_redo, c_CMD2_mask_check_error_bits, c_CMD2_ans_error_free}): // CMD2
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_SD_Send_RCA})) ? ({c_response_type_R6_RCA, c_DAT_none, c_CMD3_mask_check_redo_bits, c_CMD3_ans_dont_redo, c_CMD3_mask_check_error_bits, c_CMD3_ans_error_free}) : // CMD3
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_Switch_Function})) ? ({c_response_type_R1_NORMAL, c_DAT_wide, c_CMD6_mask_check_redo_bits, c_CMD6_ans_dont_redo, c_CMD6_mask_check_error_bits, c_CMD6_ans_error_free}): // CMD6
|
||||
|
||||
(w_OPCODE_Q == ({c_ACMD, c_Set_Bus_Width})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD6_mask_check_redo_bits, c_ACMD6_ans_dont_redo, c_ACMD6_mask_check_error_bits, c_ACMD6_ans_error_free}): //ACMD6
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_Select_Card})) ? ({c_response_type_R1_NORMAL, c_DAT_busy, c_CMD7_mask_check_redo_bits, c_CMD7_ans_dont_redo, c_CMD7_mask_check_error_bits, c_CMD7_ans_error_free}): // CMD7
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_Send_IF_State})) ? ({c_response_type_R7_CIC, c_DAT_none, c_CMD8_mask_check_redo_bits, c_CMD8_ans_dont_redo, c_CMD8_mask_check_error_bits, c_CMD8_ans_error_free}): // CMD8
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_Read_Single_Block})) ? ({c_response_type_R1_NORMAL, c_DAT_block, c_CMD17_mask_check_redo_bits, c_CMD17_ans_dont_redo, c_CMD17_mask_check_error_bits, c_CMD17_ans_error_free}): // CMD17
|
||||
|
||||
(w_OPCODE_Q == ({c_ACMD, c_SD_Send_OCR})) ? ({c_response_type_R3_OCR, c_DAT_none, c_ACMD41_mask_check_redo_bits, c_ACMD41_ans_dont_redo, c_ACMD41_mask_check_error_bits, c_ACMD41_ans_error_free}) : //ACMD41
|
||||
|
||||
(w_OPCODE_Q == ({c_CMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_CMD55_mask_check_redo_bits, c_CMD55_ans_dont_redo, c_CMD55_mask_check_error_bits, c_CMD55_ans_error_free}) : // CMD55
|
||||
|
||||
(w_OPCODE_Q == ({c_ACMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}) : //ACMD55
|
||||
|
||||
({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}); // when in doubt just send ACMD55
|
||||
|
||||
assign w_R_TYPE = w_instruction_control_bits[132:130];
|
||||
assign w_USES_DAT = w_instruction_control_bits[129:128];
|
||||
assign w_NO_REDO_MASK = w_instruction_control_bits[127:96];
|
||||
assign w_NO_REDO_ANS = w_instruction_control_bits[95:64];
|
||||
assign w_NO_ERROR_MASK = w_instruction_control_bits[63:32];
|
||||
assign w_NO_ERROR_ANS = w_instruction_control_bits[31:0];
|
||||
|
||||
|
||||
endmodule
|
||||
|
@ -1,98 +0,0 @@
|
||||
|
||||
///////////////////////////////////////////
|
||||
// sd_top_wrapper.sv
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 19, 2021
|
||||
//
|
||||
// Purpose: SD card controller wrapper
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
module sd_top_wrapper #(parameter g_COUNT_WIDTH = 8) (
|
||||
input logic clk_in1_p,
|
||||
input logic clk_in1_n,
|
||||
input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles)
|
||||
// a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK!
|
||||
// io_SD_CMD_z : inout std_logic; // SD CMD Bus
|
||||
inout SD_CMD, // CMD Response from card
|
||||
input logic [3:0] i_SD_DAT, // SD DAT Bus
|
||||
output logic o_SD_CLK, // SD CLK Bus
|
||||
// For communication with core cpu
|
||||
output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and
|
||||
// sd card is ready to read a 512 byte block to the core.
|
||||
// Held high during idle until i_READ_REQUEST is received
|
||||
output logic o_SD_RESTARTING, // inform core the need to restart
|
||||
|
||||
input logic i_READ_REQUEST, // After Ready for read is sent to the core, the core will
|
||||
// pulse this bit high to indicate it wants the block at this address
|
||||
output logic [3:0] o_DATA_TO_CORE, // nibble being sent to core when DATA block is being published
|
||||
output logic o_DATA_VALID // held high while data being read to core to indicate that it is valid
|
||||
);
|
||||
|
||||
wire CLK;
|
||||
wire LIMIT_SD_TIMERS;
|
||||
wire [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX;
|
||||
wire [4095:0] ReadData; // full 512 bytes to Bus
|
||||
wire [32:9] i_BLOCK_ADDR; // see "Addressing" in parts.fods (only 8GB total capacity is used)
|
||||
wire o_SD_CMD; // CMD Command from host
|
||||
wire i_SD_CMD; // CMD Command from host
|
||||
wire o_SD_CMD_OE; // Direction of SD_CMD
|
||||
wire [2:0] o_ERROR_CODE_Q; // indicates which error occured
|
||||
wire o_FATAL_ERROR; // indicates that the FATAL ERROR register has updated
|
||||
wire o_LAST_NIBBLE; // pulse when last nibble is sent
|
||||
|
||||
assign LIMIT_SD_TIMERS = 1'b0;
|
||||
assign i_COUNT_IN_MAX = -8'd62;
|
||||
assign i_BLOCK_ADDR = 23'h0;
|
||||
|
||||
clk_wiz_0 clk_wiz_0(.clk_in1_p(clk_in1_p),
|
||||
.clk_in1_n(clk_in1_n),
|
||||
.reset(1'b0),
|
||||
.clk_out1(CLK),
|
||||
.locked(locked));
|
||||
|
||||
IOBUF SDCMDIODriver(.T(~o_SD_CMD_OE),
|
||||
.I(o_SD_CMD),
|
||||
.O(i_SD_CMD),
|
||||
.IO(SD_CMD));
|
||||
|
||||
|
||||
sd_top #(g_COUNT_WIDTH)
|
||||
sd_top(.CLK(CLK),
|
||||
.a_RST(a_RST),
|
||||
.i_SD_CMD(i_SD_CMD), // CMD Response from card
|
||||
.o_SD_CMD(o_SD_CMD), // CMD Command from host
|
||||
.o_SD_CMD_OE(o_SD_CMD_OE), // Direction of SD_CMD
|
||||
.i_SD_DAT(i_SD_DAT), // SD DAT Bus
|
||||
.o_SD_CLK(o_SD_CLK), // SD CLK Bus
|
||||
.i_BLOCK_ADDR(i_BLOCK_ADDR), // see "Addressing" in parts.fods (only 8GB total capacity is used)
|
||||
.o_READY_FOR_READ(o_READY_FOR_READ), // tells core that initialization sequence is completed and
|
||||
.o_SD_RESTARTING(o_SD_RESTARTING), // inform core the need to restart
|
||||
.i_READ_REQUEST(i_READ_REQUEST), // After Ready for read is sent to the core, the core will
|
||||
.o_DATA_TO_CORE(o_DATA_TO_CORE), // nibble being sent to core when DATA block is
|
||||
.ReadData(ReadData), // full 512 bytes to Bus
|
||||
.o_DATA_VALID(o_DATA_VALID), // held high while data being read to core to indicate that it is valid
|
||||
.o_LAST_NIBBLE(o_LAST_NIBBLE), // pulse when last nibble is sent
|
||||
.o_ERROR_CODE_Q(o_ERROR_CODE_Q), // indicates which error occured
|
||||
.o_FATAL_ERROR(o_FATAL_ERROR), // indicates that the FATAL ERROR register has updated
|
||||
.i_COUNT_IN_MAX(i_COUNT_IN_MAX),
|
||||
.LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)
|
||||
);
|
||||
|
||||
endmodule
|
@ -1,54 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// simple_timer.sv
|
||||
//
|
||||
// Written: Ross Thompson September 20, 2021
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: SD card controller
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module simple_timer #(parameter BUS_WIDTH = 4) (
|
||||
input logic [BUS_WIDTH-1:0] VALUE,
|
||||
input logic START,
|
||||
output logic FLAG,
|
||||
input logic RST,
|
||||
input logic CLK
|
||||
);
|
||||
|
||||
|
||||
logic [BUS_WIDTH-1:0] count;
|
||||
logic timer_en;
|
||||
|
||||
assign timer_en = count != 0;
|
||||
|
||||
always_ff @(posedge CLK, posedge RST) begin
|
||||
if (RST) begin
|
||||
count <= '0;
|
||||
end else if (START) begin
|
||||
count <= VALUE - 1'b1;
|
||||
end else if(timer_en) begin
|
||||
count <= count - 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
assign FLAG = count != 0;
|
||||
|
||||
endmodule
|
||||
|
@ -1,51 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// sipo_generic_ce
|
||||
//
|
||||
// Written: Richard Davis
|
||||
// Modified: Ross Thompson September 20, 2021
|
||||
//
|
||||
// Purpose: serial to n-bit parallel shift register using register_ce.
|
||||
// When given a n-bit word as input transmit the message serially MSB (leftmost)
|
||||
// bit first.
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module sipo_generic_ce #(g_BUS_WIDTH) (
|
||||
input logic clk,
|
||||
input logic rst,
|
||||
input logic i_enable, // data valid, write to register
|
||||
input logic i_message_bit, // serial data
|
||||
output logic [g_BUS_WIDTH-1:0] o_data // message received, parallel data
|
||||
);
|
||||
|
||||
logic [g_BUS_WIDTH-1:0] w_reg_d;
|
||||
logic [g_BUS_WIDTH-1:0] r_reg_q;
|
||||
|
||||
flopenr #(g_BUS_WIDTH) shiftReg
|
||||
(.d(w_reg_d),
|
||||
.q(r_reg_q),
|
||||
.en(i_enable),
|
||||
.reset(rst),
|
||||
.clk(clk));
|
||||
|
||||
assign w_reg_d = {r_reg_q[g_BUS_WIDTH-2:0], i_message_bit};
|
||||
|
||||
assign o_data = r_reg_q;
|
||||
|
||||
endmodule
|
@ -1,45 +0,0 @@
|
||||
///////////////////////////////////////////
|
||||
// counter.sv
|
||||
//
|
||||
// Written: Ross Thompson
|
||||
// Modified:
|
||||
//
|
||||
// Purpose: basic up counter
|
||||
//
|
||||
// A component of the CORE-V-WALLY configurable RISC-V project.
|
||||
//
|
||||
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
|
||||
//
|
||||
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
|
||||
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
|
||||
// may obtain a copy of the License at
|
||||
//
|
||||
// https://solderpad.org/licenses/SHL-2.1/
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, any work distributed under the
|
||||
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||
// either express or implied. See the License for the specific language governing permissions
|
||||
// and limitations under the License.
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
`include "wally-config.vh"
|
||||
|
||||
module up_down_counter #(parameter integer WIDTH=32) (
|
||||
input logic [WIDTH-1:0] CountIn,
|
||||
output logic [WIDTH-1:0] CountOut,
|
||||
input logic Load,
|
||||
input logic Enable,
|
||||
input logic UpDown,
|
||||
input logic clk,
|
||||
input logic reset
|
||||
);
|
||||
|
||||
logic [WIDTH-1:0] NextCount;
|
||||
logic [WIDTH-1:0] CountP1;
|
||||
|
||||
assign CountP1 = UpDown ? CountOut + 1'b1 : CountOut - 1'b1;
|
||||
assign NextCount = Load ? CountIn : CountP1;
|
||||
flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut);
|
||||
endmodule
|
||||
|
||||
|
@ -799,7 +799,7 @@ module testbench;
|
||||
// For waveview convenience
|
||||
string InstrFName, InstrDName, InstrEName, InstrMName, InstrWName;
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.FinalInstrRawF[31:0],
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
@ -198,7 +198,7 @@ logic [3:0] dummy;
|
||||
|
||||
// Track names of instructions
|
||||
instrTrackerTB it(clk, reset, dut.core.ieu.dp.FlushE,
|
||||
dut.core.ifu.FinalInstrRawF[31:0],
|
||||
dut.core.ifu.InstrRawF[31:0],
|
||||
dut.core.ifu.InstrD, dut.core.ifu.InstrE,
|
||||
dut.core.ifu.InstrM, InstrW,
|
||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||
|
Loading…
Reference in New Issue
Block a user