SPI Preftech logic added
diff --git a/openlane/spi_master/base.sdc b/openlane/spi_master/base.sdc
index 10ad658..a531c30 100644
--- a/openlane/spi_master/base.sdc
+++ b/openlane/spi_master/base.sdc
@@ -53,15 +53,15 @@
set spi_input_delay_value [expr $::env(SPI_CLOCK_PERIOD) * 0.6]
set spi_output_delay_value [expr $::env(SPI_CLOCK_PERIOD) * 0.6]
-set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[5]]
-set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[4]]
set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[3]]
set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[2]]
+set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[1]]
+set_input_delay 6 -max -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[0]]
-set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[5]]
-set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[4]]
set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[3]]
set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[2]]
+set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[1]]
+set_input_delay 0 -min -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_in[0]]
#io_out[0] is spiclcok
#set_output_delay $wb_output_delay_value -clock [get_clocks $::env(SPI_CLOCK_PORT)] [get_port io_out[0]]
diff --git a/openlane/user_project_wrapper/gen_pdn.tcl b/openlane/user_project_wrapper/gen_pdn.tcl
new file mode 100644
index 0000000..74d61c4
--- /dev/null
+++ b/openlane/user_project_wrapper/gen_pdn.tcl
@@ -0,0 +1,34 @@
+read_lef $::env(MERGED_LEF_UNPADDED)
+read_def $::env(CURRENT_DEF)
+
+set ::env(_SPACING) 1.7
+set ::env(_WIDTH) 3
+
+set power_domains [list {vccd1 vssd1 1} {vccd2 vssd2 0} {vdda1 vssa1 0} {vdda2 vssa2 0}]
+
+set ::env(_VDD_NET_NAME) vccd1
+set ::env(_GND_NET_NAME) vssd1
+set ::env(_WITH_STRAPS) 1
+set ::env(_V_OFFSET) 14
+set ::env(_H_OFFSET) $::env(_V_OFFSET)
+set ::env(_V_PITCH) 80
+set ::env(_H_PITCH) 80
+set ::env(_V_PDN_OFFSET) 0
+set ::env(_H_PDN_OFFSET) 0
+
+foreach domain $power_domains {
+ set ::env(_VDD_NET_NAME) [lindex $domain 0]
+ set ::env(_GND_NET_NAME) [lindex $domain 1]
+ set ::env(_WITH_STRAPS) [lindex $domain 2]
+
+ pdngen $::env(PDN_CFG) -verbose
+
+ set ::env(_V_OFFSET) \
+ [expr $::env(_V_OFFSET) + 2*($::env(_WIDTH)+$::env(_SPACING))]
+ set ::env(_H_OFFSET) \
+ [expr $::env(_H_OFFSET) + 2*($::env(_WIDTH)+$::env(_SPACING))]
+ set ::env(_V_PDN_OFFSET) [expr $::env(_V_PDN_OFFSET)+6*$::env(_WIDTH)]
+ set ::env(_H_PDN_OFFSET) [expr $::env(_H_PDN_OFFSET)+6*$::env(_WIDTH)]
+}
+
+write_def $::env(SAVE_DEF)
diff --git a/openlane/user_project_wrapper/interactive.tcl b/openlane/user_project_wrapper/interactive.tcl
new file mode 100644
index 0000000..02f4516
--- /dev/null
+++ b/openlane/user_project_wrapper/interactive.tcl
@@ -0,0 +1,218 @@
+#!/usr/bin/tclsh
+# Copyright 2020 Efabless Corporation
+# Copyright 2020 Sylvain Munaut
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# 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.
+
+
+package require openlane;
+
+proc run_floorplan_yifive {args} {
+ puts_info "Running Floorplanning for yifive..."
+ # |----------------------------------------------------|
+ # |---------------- 2. FLOORPLAN ------------------|
+ # |----------------------------------------------------|
+ #
+ set script_dir [file dirname [file normalize [info script]]]
+ # intial fp
+ init_floorplan
+
+
+ # place io
+ if { [info exists ::env(FP_PIN_ORDER_CFG)] } {
+ place_io_ol
+ } else {
+ if { [info exists ::env(FP_CONTEXT_DEF)] && [info exists ::env(FP_CONTEXT_LEF)] } {
+ place_io
+ global_placement_or
+ place_contextualized_io \
+ -lef $::env(FP_CONTEXT_LEF) \
+ -def $::env(FP_CONTEXT_DEF)
+ } else {
+ place_io
+ }
+ }
+
+ apply_def_template
+
+ if { [info exist ::env(EXTRA_LEFS)] } {
+ if { [info exist ::env(MACRO_PLACEMENT_CFG)] } {
+ file copy -force $::env(MACRO_PLACEMENT_CFG) $::env(TMP_DIR)/macro_placement.cfg
+ manual_macro_placement f
+ } else {
+ global_placement_or
+ basic_macro_placement
+ }
+ }
+
+ # tapcell
+ tap_decap_or
+ scrot_klayout -layout $::env(CURRENT_DEF)
+ puts_info "Running pdn_gen for yifive..."
+ # power grid generation
+ #run_power_grid_generation
+ set ::env(SAVE_DEF) [index_file $::env(pdn_tmp_file_tag).def]
+ try_catch openroad -exit $script_dir/gen_pdn.tcl \
+ |& tee $::env(TERMINAL_OUTPUT) [index_file $::env(pdn_log_file_tag).log 0]
+
+ set_def $::env(SAVE_DEF)
+}
+
+proc run_power_grid_generation {args} {
+ if { [info exists ::env(VDD_NETS)] || [info exists ::env(GND_NETS)] } {
+ # they both must exist and be equal in length
+ # current assumption: they cannot have a common ground
+ if { ! [info exists ::env(VDD_NETS)] || ! [info exists ::env(GND_NETS)] } {
+ puts_err "VDD_NETS and GND_NETS must *both* either be defined or undefined"
+ return -code error
+ }
+ } elseif { [info exists ::env(SYNTH_USE_PG_PINS_DEFINES)] } {
+ set ::env(VDD_NETS) [list]
+ set ::env(GND_NETS) [list]
+ # get the pins that are in $yosys_tmp_file_tag.pg_define.v
+ # that are not in $yosys_result_file_tag.v
+ #
+ set full_pins {*}[extract_pins_from_yosys_netlist $::env(yosys_tmp_file_tag).pg_define.v]
+ puts_info $full_pins
+
+ set non_pg_pins {*}[extract_pins_from_yosys_netlist $::env(yosys_result_file_tag).v]
+ puts_info $non_pg_pins
+
+ # assumes the pins are ordered correctly (e.g., vdd1, vss1, vcc1, vss1, ...)
+ foreach {vdd gnd} $full_pins {
+ if { $vdd ne "" && $vdd ni $non_pg_pins } {
+ lappend ::env(VDD_NETS) $vdd
+ }
+ if { $gnd ne "" && $gnd ni $non_pg_pins } {
+ lappend ::env(GND_NETS) $gnd
+ }
+ }
+ } else {
+ set ::env(VDD_NETS) $::env(VDD_PIN)
+ set ::env(GND_NETS) $::env(GND_PIN)
+ }
+
+ puts_info "Power planning the following nets"
+ puts_info "Power: $::env(VDD_NETS)"
+ puts_info "Ground: $::env(GND_NETS)"
+
+ if { [llength $::env(VDD_NETS)] != [llength $::env(GND_NETS)] } {
+ puts_err "VDD_NETS and GND_NETS must be of equal lengths"
+ return -code error
+ }
+
+ # generate multiple power grids per pair of (VDD,GND)
+ # offseted by WIDTH + SPACING
+ foreach vdd $::env(VDD_NETS) gnd $::env(GND_NETS) {
+ set ::env(VDD_NET) $vdd
+ set ::env(GND_NET) $gnd
+
+ gen_pdn
+
+ set ::env(FP_PDN_ENABLE_RAILS) 0
+
+ # allow failure until open_pdks is up to date...
+ catch {set ::env(FP_PDN_VOFFSET) [expr $::env(FP_PDN_VOFFSET)+$::env(FP_PDN_VWIDTH)+$::env(FP_PDN_VSPACING)]}
+ catch {set ::env(FP_PDN_HOFFSET) [expr $::env(FP_PDN_HOFFSET)+$::env(FP_PDN_HWIDTH)+$::env(FP_PDN_HSPACING)]}
+
+ catch {set ::env(FP_PDN_CORE_RING_VOFFSET) \
+ [expr $::env(FP_PDN_CORE_RING_VOFFSET)\
+ +2*($::env(FP_PDN_CORE_RING_VWIDTH)\
+ +max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+ catch {set ::env(FP_PDN_CORE_RING_HOFFSET) [expr $::env(FP_PDN_CORE_RING_HOFFSET)\
+ +2*($::env(FP_PDN_CORE_RING_HWIDTH)+\
+ max($::env(FP_PDN_CORE_RING_VSPACING), $::env(FP_PDN_CORE_RING_HSPACING)))]}
+ }
+ set ::env(FP_PDN_ENABLE_RAILS) 1
+}
+
+proc run_flow {args} {
+ set script_dir [file dirname [file normalize [info script]]]
+
+ set options {
+ {-design required}
+ {-save_path optional}
+ {-no_lvs optional}
+ {-no_drc optional}
+ {-no_antennacheck optional}
+ }
+ set flags {-save}
+ parse_key_args "run_flow" args arg_values $options flags_map $flags -no_consume
+
+ prep {*}$args
+
+ run_synthesis
+ run_floorplan_yifive
+ run_placement
+ run_cts
+ run_routing
+
+ if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+ run_antenna_check
+ heal_antenna_violators; # modifies the routed DEF
+ }
+
+ if { $::env(LVS_INSERT_POWER_PINS) } {
+ write_powered_verilog
+ set_netlist $::env(lvs_result_file_tag).powered.v
+ }
+
+ run_magic
+
+ run_klayout
+
+ run_klayout_gds_xor
+
+ if { ! [info exists flags_map(-no_lvs)] } {
+ run_magic_spice_export
+ }
+
+ if { [info exists flags_map(-save) ] } {
+ if { ! [info exists arg_values(-save_path)] } {
+ set arg_values(-save_path) ""
+ }
+ save_views -lef_path $::env(magic_result_file_tag).lef \
+ -def_path $::env(tritonRoute_result_file_tag).def \
+ -gds_path $::env(magic_result_file_tag).gds \
+ -mag_path $::env(magic_result_file_tag).mag \
+ -maglef_path $::env(magic_result_file_tag).lef.mag \
+ -spice_path $::env(magic_result_file_tag).spice \
+ -verilog_path $::env(CURRENT_NETLIST) \
+ -save_path $arg_values(-save_path) \
+ -tag $::env(RUN_TAG)
+ }
+
+ # Physical verification
+ if { ! [info exists flags_map(-no_lvs)] } {
+ run_lvs; # requires run_magic_spice_export
+ }
+
+ if { ! [info exists flags_map(-no_drc)] } {
+ run_magic_drc
+ run_klayout_drc
+ }
+
+ if { ! [info exists flags_map(-no_antennacheck) ] } {
+ run_antenna_check
+ }
+
+ run_lef_cvc
+
+ calc_total_runtime
+ generate_final_summary_report
+
+ puts_success "Flow Completed Without Fatal Errors."
+
+}
+
+run_flow {*}$argv
diff --git a/openlane/user_project_wrapper/mod.tcl b/openlane/user_project_wrapper/mod.tcl
new file mode 100644
index 0000000..0e97ab8
--- /dev/null
+++ b/openlane/user_project_wrapper/mod.tcl
@@ -0,0 +1,73 @@
+# SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# 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.
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+
+
+set ::env(LIB_FASTEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ff_n40C_1v95.lib"
+set ::env(LIB_SLOWEST) "$::env(PDK_ROOT)/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__ss_100C_1v60.lib"
+set ::env(SYNTH_DRIVING_CELL) "sky130_fd_sc_hd__inv_8"
+set ::env(SYNTH_DRIVING_CELL_PIN) "Y"
+set ::env(SYNTH_CAP_LOAD) "17.65"
+set ::env(WIRE_RC_LAYER) "met1"
+
+#To disable empty filler cell black box get created
+#set link_make_black_boxes 0
+
+
+set_cmd_units -time ns -capacitance pF -current mA -voltage V -resistance kOhm -distance um
+define_corners wc bc
+read_liberty -corner bc $::env(LIB_FASTEST)
+read_liberty -corner wc $::env(LIB_SLOWEST)
+
+# Removing the decap and diode
+read_verilog ../../verilog/gl/clk_buf.v
+link_design clk_buf
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/clk_buf.v
+# Removing the decap and diode
+read_verilog ../../verilog/gl/clk_skew_adjust.v
+link_design clk_skew_adjust
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/clk_skew_adjust.v
+
+# Removing the decap and diode
+read_verilog ../../verilog/gl/glbl_cfg.v
+link_design glbl_cfg
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/glbl_cfg.v
+
+read_verilog ../../verilog/gl/sdram.v
+link_design sdrc_top
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/sdram.v
+
+read_verilog ../../verilog/gl/spi_master.v
+link_design spim_top
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/spi_master.v
+
+read_verilog ../../verilog/gl/syntacore.v
+link_design scr1_top_wb
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/syntacore.v
+
+read_verilog ../../verilog/gl/uart.v
+link_design uart_core
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/uart.v
+
+read_verilog ../../verilog/gl/wb_host.v
+link_design wb_host
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/wb_host.v
+
+read_verilog ../../verilog/gl/wb_interconnect.v
+link_design wb_interconnect
+write_verilog -remove_cells [get_lib_cells {sky130_fd_sc_hd__decap* sky130_fd_sc_hd__fill* sky130_fd_sc_hd__diode_* sky130_ef_sc_hd__fakediode* sky130_fd_sc_hd__tapvpwrvgnd*}] netlist/wb_interconnect.v
+
+
+exit
diff --git a/openlane/user_project_wrapper/pdn.tcl b/openlane/user_project_wrapper/pdn.tcl
new file mode 100644
index 0000000..d9bab11
--- /dev/null
+++ b/openlane/user_project_wrapper/pdn.tcl
@@ -0,0 +1,44 @@
+# Power nets
+set ::power_nets $::env(_VDD_NET_NAME)
+set ::ground_nets $::env(_GND_NET_NAME)
+
+set stdcell {
+ name grid
+ core_ring {
+ met5 {width $::env(_WIDTH) spacing $::env(_SPACING) core_offset $::env(_H_OFFSET)}
+ met4 {width $::env(_WIDTH) spacing $::env(_SPACING) core_offset $::env(_V_OFFSET)}
+ }
+ rails {
+ }
+ connect {{met4 met5}}
+}
+
+if { $::env(_WITH_STRAPS) } {
+ dict append stdcell straps {
+ met4 {width $::env(_WIDTH) pitch $::env(_V_PITCH) offset $::env(_V_PDN_OFFSET)}
+ met5 {width $::env(_WIDTH) pitch $::env(_H_PITCH) offset $::env(_H_PDN_OFFSET)}
+ }
+}
+
+pdngen::specify_grid stdcell $stdcell
+
+set macro {
+ orient {R0 R180 MX MY R90 R270 MXR90 MYR90}
+ power_pins "vccd1"
+ ground_pins "vssd1"
+ blockages "li1 met1 met2 met3 met4"
+ straps {
+ }
+ connect {{met4_PIN_ver met5}}
+}
+
+pdngen::specify_grid macro [subst $macro]
+
+set ::halo 10
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
+
diff --git a/signoff/spi_master/final_summary_report.csv b/signoff/spi_master/final_summary_report.csv
index 8d0d32b..099784f 100644
--- a/signoff/spi_master/final_summary_report.csv
+++ b/signoff/spi_master/final_summary_report.csv
@@ -1,2 +1,2 @@
,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
-0,/project/openlane/spi_master,spim_top,spi_master,Flow_completed,0h12m59s,0h8m21s,45758.33333333334,0.24,22879.16666666667,33,608.8,5491,0,0,0,0,0,0,0,2,4,-1,0,246103,42258,-0.01,-0.01,0.0,0.0,0.0,-0.01,-0.01,0.0,0.0,0.0,192084576,0.0,17.57,28.06,0.0,-1,-1,5427,5567,901,1041,0,0,0,5491,223,0,184,93,748,126,37,1613,982,921,24,424,2889,0,3313,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,3
+0,/project/openlane/spi_master,spim_top,spi_master,Flow_completed,0h10m24s,0h6m34s,64225.0,0.24,32112.5,47,650.94,7707,0,0,0,0,0,0,0,2,4,-1,0,340960,59901,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,257797329,0.0,27.62,36.77,0.2,-1,-1,7643,7783,1271,1411,0,0,0,7707,242,0,168,95,1009,216,28,2394,1352,1291,25,424,2889,0,3313,100.0,10.0,10,AREA 0,4,50,1,100,100,0.55,0,sky130_fd_sc_hd,4,3
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv
index f17a8a9..b025532 100644
--- a/signoff/user_project_wrapper/final_summary_report.csv
+++ b/signoff/user_project_wrapper/final_summary_report.csv
@@ -1,2 +1,2 @@
,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY
-0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,Flow_completed,0h37m42s,0h4m32s,3.3079078455790785,10.2784,1.6539539227895392,0,552.07,17,0,0,0,0,0,0,0,0,1,-1,-1,1189479,3954,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1,0.0,1.26,4.31,0.72,1.81,-1,848,1466,848,1466,0,0,0,17,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,80,0.55,0,sky130_fd_sc_hd,4,0
+0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,Flow_completed,0h39m39s,0h4m47s,3.3079078455790785,10.2784,1.6539539227895392,0,555.97,17,0,0,0,0,0,0,0,0,1,-1,-1,1189476,3936,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,-1,0.0,1.26,4.31,0.72,1.81,-1,848,1466,848,1466,0,0,0,17,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,100.0,10.0,10,AREA 0,5,50,1,80,80,0.55,0,sky130_fd_sc_hd,4,0
diff --git a/verilog/dv/model/s25fl256s.sv b/verilog/dv/model/s25fl256s.sv
index 748f037..7883af3 100644
--- a/verilog/dv/model/s25fl256s.sv
+++ b/verilog/dv/model/s25fl256s.sv
@@ -710,21 +710,21 @@
// Typical Byte Programming Time
specparam tdevice_BP = 4e8;//tBP
// Sector Erase Operation
- specparam tdevice_SE64 = 650e7;//tSE
+ specparam tdevice_SE64 = 10e7; // 650e7;//tSE Dinesh A
// Sector Erase Operation
- specparam tdevice_SE256 = 1875e7;//tSE
+ specparam tdevice_SE256 = 10e7; // 1875e7;//tSE Dinesh A
// Bulk Erase Operation
specparam tdevice_BE = 330e9;//tBE
// WRR Cycle Time
- specparam tdevice_WRR = 1; // 2e9;//tW
+ specparam tdevice_WRR = 1; // 2e9;//tW Dinesh A
// Erase Suspend/Erase Resume Time
specparam tdevice_ERSSUSP = 45e6;//tESL
// Program Suspend/Program Resume Time
- specparam tdevice_PRGSUSP = 1; // 40e6;//
+ specparam tdevice_PRGSUSP = 1; // 40e6;// Dinesh A
// VCC (min) to CS# Low
- specparam tdevice_PU = 1; // 3e8;//tPU
+ specparam tdevice_PU = 1; // 3e8;//tPU Dinesh A
// PPB Erase Time
- specparam tdevice_PPBERASE = 15e9;//
+ specparam tdevice_PPBERASE = 1; // 15e9;// Dinesh A
// Password Unlock Time
specparam tdevice_PASSULCK = 1e6;//
// Password Unlock to Password Unlock Time
@@ -2932,6 +2932,7 @@
end
end
WByte[i] = Byte_slv;
+ //$display("%m: Loc: %x Byte: %x",i,Byte_slv);
end
if (data_cnt > (PageSize+1)*BYTE)
@@ -3955,8 +3956,10 @@
begin
if (Viol != 0)
WData[i] = -1;
- else
- WData[i] = WByte[i];
+ else begin
+ WData[i] = WByte[i];
+ //$display("%m: Loc: %x WData: %x",i,WData[i]);
+ end
end
end
else
@@ -5069,6 +5072,7 @@
begin
new_int = WData[i];
old_int = Mem[Addr + i - cnt];
+ //$display("%m: New Loc: %x New Data: %x Old Data: %x",i,new_int,old_int);
if (new_int > -1)
begin
new_bit = new_int;
@@ -5109,6 +5113,7 @@
for (i=0;i<=wr_cnt;i=i+1)
begin
Mem[Addr_tmp + i - cnt] = WData[i];
+ //$display("%m => SFLASH WR Address: %x Data: %x",Addr_tmp + i - cnt, WData[i]);
if ((Addr_tmp + i) == AddrHi)
begin
Addr_tmp = AddrLo;
@@ -6035,6 +6040,7 @@
if (~EDONE)
begin
ADDRHILO_SEC(AddrLo, AddrHi, Addr);
+ $display("%m: Sector Erase Address: %x Start: %x End: %x",Addr,AddrLo,AddrHi);
for (i=AddrLo;i<=AddrHi;i=i+1)
begin
Mem[i] = -1;
diff --git a/verilog/dv/risc_boot/risc_boot_tb.v b/verilog/dv/risc_boot/risc_boot_tb.v
index 2cb80c3..169f2a8 100644
--- a/verilog/dv/risc_boot/risc_boot_tb.v
+++ b/verilog/dv/risc_boot/risc_boot_tb.v
@@ -158,7 +158,7 @@
$display("Monitor: Test User Risc Boot Started");
// Wait for user risc core to boot up
- repeat (35000) @(posedge clock);
+ repeat (25000) @(posedge clock);
tb_uart.uart_init;
tb_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity,
uart_stick_parity, uart_timeout, uart_divisor);
@@ -307,7 +307,8 @@
// Quard flash
s25fl256s #(.mem_file_name("user_uart.hex"),
- .otp_file_name("none"))
+ .otp_file_name("none"),
+ .TimingModel("S25FL512SAGMFI010_F_30pF"))
u_spi_flash_256mb (
// Data Inputs/Outputs
.SI (mprj_io[32]),
diff --git a/verilog/dv/user_risc_boot/user_risc_boot_tb.v b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
index aa4c71a..5abdac9 100644
--- a/verilog/dv/user_risc_boot/user_risc_boot_tb.v
+++ b/verilog/dv/user_risc_boot/user_risc_boot_tb.v
@@ -155,7 +155,7 @@
// Repeat cycles of 1000 clock edges as needed to complete testbench
- repeat (30) begin
+ repeat (20) begin
repeat (1000) @(posedge clock);
// $display("+1000 cycles");
end
@@ -374,7 +374,8 @@
// Quard flash
s25fl256s #(.mem_file_name("user_risc_boot.hex"),
- .otp_file_name("none"))
+ .otp_file_name("none"),
+ .TimingModel("S25FL512SAGMFI010_F_30pF"))
u_spi_flash_256mb (
// Data Inputs/Outputs
.SI (flash_io0),
diff --git a/verilog/dv/user_spi/user_spi_tb.v b/verilog/dv/user_spi/user_spi_tb.v
index 60ad1f9..65371ae 100644
--- a/verilog/dv/user_spi/user_spi_tb.v
+++ b/verilog/dv/user_spi/user_spi_tb.v
@@ -105,7 +105,52 @@
reg test_fail;
reg [31:0] read_data;
+/*************************************************************
+* SPI FSM State Control
+*
+* OPERATION COMMAND SEQUENCE
+*
+* ERASE P4E(0x20) -> COMMAND + ADDRESS
+* ERASE P8E(0x40) -> COMMAND + ADDRESS
+* ERASE SE(0xD8) -> COMMAND + ADDRESS
+* ERASE BE(0x60) -> COMMAND + ADDRESS
+* ERASE BE(0xC7) -> COMMAND
+* PROGRAM PP(0x02) -> COMMAND + ADDRESS + Write DATA
+* PROGRAM QPP(0x32) -> COMMAND + ADDRESS + Write DATA
+* READ READ(0x3) -> COMMAND + ADDRESS + READ DATA
+* READ FAST_READ(0xB) -> COMMAND + ADDRESS + DUMMY + READ DATA
+* READ DOR (0x3B) -> COMMAND + ADDRESS + DUMMY + READ DATA
+* READ QOR (0x6B) -> COMMAND + ADDRESS + DUMMY + READ DATA
+* READ DIOR (0xBB) -> COMMAND + ADDRESS + MODE + READ DATA
+* READ QIOR (0xEB) -> COMMAND + ADDRESS + MODE + DUMMY + READ DATA
+* READ RDID (0x9F) -> COMMAND + READ DATA
+* READ READ_ID (0x90) -> COMMAND + ADDRESS + READ DATA
+* WRITE WREN(0x6) -> COMMAND
+* WRITE WRDI -> COMMAND
+* STATUS RDSR(0x05) -> COMMAND + READ DATA
+* STATUS RCR(0x35) -> COMMAND + READ DATA
+* CONFIG WRR(0x01) -> COMMAND + WRITE DATA
+* CONFIG CLSR(0x30) -> COMMAND
+* Power Saving DP(0xB9) -> COMMAND
+* Power Saving RES(0xAB) -> COMMAND + READ DATA
+* OTP OTPP(0x42) -> COMMAND + ADDR+ WRITE DATA
+* OTP OTPR(0x4B) -> COMMAND + ADDR + DUMMY + READ DATA
+* ********************************************************************/
+parameter P_FSM_C = 4'b0000; // Command Phase Only
+parameter P_FSM_CW = 4'b0001; // Command + Write DATA Phase Only
+parameter P_FSM_CA = 4'b0010; // Command -> Address Phase Only
+parameter P_FSM_CAR = 4'b0011; // Command -> Address -> Read Data
+parameter P_FSM_CADR = 4'b0100; // Command -> Address -> Dummy -> Read Data
+parameter P_FSM_CAMR = 4'b0101; // Command -> Address -> Mode -> Read Data
+parameter P_FSM_CAMDR = 4'b0110; // Command -> Address -> Mode -> Dummy -> Read Data
+
+parameter P_FSM_CAW = 4'b0111; // Command -> Address ->Write Data
+parameter P_FSM_CADW = 4'b1000; // Command -> Address -> DUMMY + Write Data
+
+parameter P_FSM_CDR = 4'b1001; // COMMAND -> DUMMY -> READ
+parameter P_FSM_CDW = 4'b1010; // COMMAND -> DUMMY -> WRITE
+parameter P_FSM_CR = 4'b1011; // COMMAND -> READ
// External clock is used by default. Make this artificially fast for the
// simulation. Normally this would be a slow clock and the digital PLL
@@ -150,8 +195,198 @@
test_fail = 0;
repeat (200) @(posedge clock);
$display("#############################################");
- $display(" Testing Direct SPI Memory Read ");
+ $display(" Read Identification (RDID:0x9F) ");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h4,2'b00,2'b00,4'b1011,8'h00,8'h9F});
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00190201);
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read ");
+ $display(" SPI Mode: Normal/Single Bit ");
+ $display("Prefetch : 1DW, OPCODE:READ(0x3) ");
+ $display("SEQ: Command -> Address -> Read Data ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h04,2'b00,2'b10,4'h3,8'h00,8'h03});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read ");
+ $display(" SPI Mode: Normal/Single Bit ");
+ $display("Prefetch : 1DW, OPCODE:FASTREAD(0xB) ");
+ $display("SEQ: Command -> Address -> Dummy -> Read Data");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h04,2'b00,2'b10,4'h4,8'h00,8'h0B});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read ");
+ $display(" SPI Mode: Dual Mode ");
+ $display("Prefetch : 1DW, OPCODE:DOR(0x3B) ");
+ $display("SEQ: Command -> Address -> Dummy -> Read Data");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b10,2'b01,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h04,2'b00,2'b10,4'h4,8'h00,8'h3B});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read with Prefetch");
+ $display(" SPI Mode: Quad ");
+ $display("Prefetch : 8DW, OPCODE:URAD READ(0xEB) ");
+ $display("SEQ: Command -> Address -> Dummy -> Read Data");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h20,2'b01,2'b10,4'h6,8'h00,8'hEB});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read with Prefetch:3DW");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000008,{8'hC,2'b01,2'b10,4'h6,8'h00,8'hEB});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read with Prefetch:2DW");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h8,2'b01,2'b10,4'h6,8'h00,8'hEB});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read with Prefetch:1DW");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h4,2'b01,2'b10,4'h6,8'h00,8'hEB});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00000213);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00000293);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00000313);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00000393);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00000413);
+ wb_user_core_read_check(32'h00000400,read_data,32'h11223737);
+ wb_user_core_read_check(32'h00000404,read_data,32'h300007b7);
+ wb_user_core_read_check(32'h00000408,read_data,32'h34470293);
+ wb_user_core_read_check(32'h0000040C,read_data,32'h22334337);
+ wb_user_core_read_check(32'h00000410,read_data,32'h0057ac23);
+ wb_user_core_read_check(32'h00000414,read_data,32'h45530393);
+ wb_user_core_read_check(32'h00000418,read_data,32'h33445537);
+ wb_user_core_read_check(32'h0000041C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display("Testing Direct SPI Memory Read with Prefetch:7DW");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h10000004,{24'h0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000008,{8'h1C,2'b01,2'b10,4'h6,8'h00,8'hEB});
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
wb_user_core_read_check(32'h00000200,read_data,32'h00000093);
wb_user_core_read_check(32'h00000204,read_data,32'h00000113);
wb_user_core_read_check(32'h00000208,read_data,32'h00000193);
@@ -173,7 +408,6 @@
$display(" Testing Single Word Indirect SPI Memory Read");
$display("#############################################");
wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
-
wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'h4,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
@@ -212,6 +446,7 @@
$display("#############################################");
$display(" Testing Two Word Indirect SPI Memory Read");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'h8,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
@@ -242,6 +477,8 @@
$display("#############################################");
$display(" Testing Three Word Indirect SPI Memory Read");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'hC,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
wb_user_core_read_check(32'h1000001C,read_data,32'h00000093);
@@ -263,6 +500,8 @@
$display("#############################################");
$display(" Testing Four Word Indirect SPI Memory Read");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'h10,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
wb_user_core_read_check(32'h1000001C,read_data,32'h00000093);
@@ -288,6 +527,8 @@
$display("#############################################");
$display(" Testing Five Word Indirect SPI Memory Read");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'h14,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
wb_user_core_read_check(32'h1000001C,read_data,32'h00000093);
@@ -304,6 +545,8 @@
$display("#############################################");
$display(" Testing Eight Word Indirect SPI Memory Read");
$display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
wb_user_core_write(32'h10000010,{8'h20,2'b01,2'b10,4'b0110,8'h00,8'hEB});
wb_user_core_write(32'h10000014,32'h00000200);
wb_user_core_read_check(32'h1000001C,read_data,32'h00000093);
@@ -323,6 +566,464 @@
wb_user_core_read_check(32'h1000001C,read_data,32'h45530393);
wb_user_core_read_check(32'h1000001C,read_data,32'h33445537);
wb_user_core_read_check(32'h1000001C,read_data,32'h0077ae23);
+
+ $display("#############################################");
+ $display(" Sector Erase Command ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ // WEN COMMAND
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h0,2'b00,2'b00,4'b0000,8'h00,8'h06});
+ wb_user_core_write(32'h10000018,32'h0);
+ // Sector Erase
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h0,2'b00,2'b10,4'b0010,8'h00,8'hD8});
+ wb_user_core_write(32'h10000014,32'h00000000);
+ wb_user_core_write(32'h10000018,32'h0);
+
+ // RDSR
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h4,2'b00,2'b00,4'b1011,8'h00,8'h05});
+ read_data = 32'hFFFF_FFFF;
+ while (read_data[1:0] == 2'b11) begin
+ wb_user_core_read(32'h1000001C,read_data);
+ repeat (10) @(posedge clock);
+ end
+
+ $display("#############################################");
+ $display(" Page Write Command Address: 0x00 ");
+ $display("#############################################");
+ // WEN COMMAND
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h0,2'b00,2'b00,4'b0000,8'h00,8'h06});
+ wb_user_core_write(32'h10000018,32'h0);
+ // Page Programing
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'hF0,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+ wb_user_core_write(32'h10000014,32'h00000000);
+ wb_user_core_write(32'h10000018,32'h00010000);
+ wb_user_core_write(32'h10000018,32'h00010001);
+ wb_user_core_write(32'h10000018,32'h00010002);
+ wb_user_core_write(32'h10000018,32'h00010003);
+ wb_user_core_write(32'h10000018,32'h00010004);
+ wb_user_core_write(32'h10000018,32'h00010005);
+ wb_user_core_write(32'h10000018,32'h00010006);
+ wb_user_core_write(32'h10000018,32'h00010007);
+ wb_user_core_write(32'h10000018,32'h00010008);
+ wb_user_core_write(32'h10000018,32'h00010009);
+ wb_user_core_write(32'h10000018,32'h00010010);
+ wb_user_core_write(32'h10000018,32'h00010011);
+ wb_user_core_write(32'h10000018,32'h00010012);
+ wb_user_core_write(32'h10000018,32'h00010013);
+ wb_user_core_write(32'h10000018,32'h00010014);
+ wb_user_core_write(32'h10000018,32'h00010015);
+ wb_user_core_write(32'h10000018,32'h00010016);
+ wb_user_core_write(32'h10000018,32'h00010017);
+ wb_user_core_write(32'h10000018,32'h00010018);
+ wb_user_core_write(32'h10000018,32'h00010019);
+ wb_user_core_write(32'h10000018,32'h00010020);
+ wb_user_core_write(32'h10000018,32'h00010021);
+ wb_user_core_write(32'h10000018,32'h00010022);
+ wb_user_core_write(32'h10000018,32'h00010023);
+ wb_user_core_write(32'h10000018,32'h00010024);
+ wb_user_core_write(32'h10000018,32'h00010025);
+ wb_user_core_write(32'h10000018,32'h00010026);
+ wb_user_core_write(32'h10000018,32'h00010027);
+ wb_user_core_write(32'h10000018,32'h00010028);
+ wb_user_core_write(32'h10000018,32'h00010029);
+ wb_user_core_write(32'h10000018,32'h00010030);
+ wb_user_core_write(32'h10000018,32'h00010031);
+ wb_user_core_write(32'h10000018,32'h00010032);
+ wb_user_core_write(32'h10000018,32'h00010033);
+ wb_user_core_write(32'h10000018,32'h00010034);
+ wb_user_core_write(32'h10000018,32'h00010035);
+ wb_user_core_write(32'h10000018,32'h00010036);
+ wb_user_core_write(32'h10000018,32'h00010037);
+ wb_user_core_write(32'h10000018,32'h00010038);
+ wb_user_core_write(32'h10000018,32'h00010039);
+ wb_user_core_write(32'h10000018,32'h00010040);
+ wb_user_core_write(32'h10000018,32'h00010041);
+ wb_user_core_write(32'h10000018,32'h00010042);
+ wb_user_core_write(32'h10000018,32'h00010043);
+ wb_user_core_write(32'h10000018,32'h00010044);
+ wb_user_core_write(32'h10000018,32'h00010045);
+ wb_user_core_write(32'h10000018,32'h00010046);
+ wb_user_core_write(32'h10000018,32'h00010047);
+ wb_user_core_write(32'h10000018,32'h00010048);
+ wb_user_core_write(32'h10000018,32'h00010049);
+ wb_user_core_write(32'h10000018,32'h00010050);
+ wb_user_core_write(32'h10000018,32'h00010051);
+ wb_user_core_write(32'h10000018,32'h00010052);
+ wb_user_core_write(32'h10000018,32'h00010053);
+ wb_user_core_write(32'h10000018,32'h00010054);
+ wb_user_core_write(32'h10000018,32'h00010055);
+ wb_user_core_write(32'h10000018,32'h00010056);
+ wb_user_core_write(32'h10000018,32'h00010057);
+ wb_user_core_write(32'h10000018,32'h00010058);
+ wb_user_core_write(32'h10000018,32'h00010059);
+
+ // RDSR
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h4,2'b00,2'b00,4'b1011,8'h00,8'h05});
+ read_data = 32'hFFFF_FFFF;
+ while (read_data[1:0] == 2'b11) begin
+ wb_user_core_read(32'h1000001C,read_data);
+ repeat (10) @(posedge clock);
+ end
+
+ $display("#############################################");
+ $display(" Page Read through Direct Access ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000000,read_data,32'h00010000);
+ wb_user_core_read_check(32'h00000004,read_data,32'h00010001);
+ wb_user_core_read_check(32'h00000008,read_data,32'h00010002);
+ wb_user_core_read_check(32'h0000000C,read_data,32'h00010003);
+ wb_user_core_read_check(32'h00000010,read_data,32'h00010004);
+ wb_user_core_read_check(32'h00000014,read_data,32'h00010005);
+ wb_user_core_read_check(32'h00000018,read_data,32'h00010006);
+ wb_user_core_read_check(32'h0000001C,read_data,32'h00010007);
+ wb_user_core_read_check(32'h00000020,read_data,32'h00010008);
+ wb_user_core_read_check(32'h00000024,read_data,32'h00010009);
+ wb_user_core_read_check(32'h00000028,read_data,32'h00010010);
+ wb_user_core_read_check(32'h0000002C,read_data,32'h00010011);
+ wb_user_core_read_check(32'h00000030,read_data,32'h00010012);
+ wb_user_core_read_check(32'h00000034,read_data,32'h00010013);
+ wb_user_core_read_check(32'h00000038,read_data,32'h00010014);
+ wb_user_core_read_check(32'h0000003C,read_data,32'h00010015);
+ wb_user_core_read_check(32'h00000040,read_data,32'h00010016);
+ wb_user_core_read_check(32'h00000044,read_data,32'h00010017);
+ wb_user_core_read_check(32'h00000048,read_data,32'h00010018);
+ wb_user_core_read_check(32'h0000004C,read_data,32'h00010019);
+ wb_user_core_read_check(32'h00000050,read_data,32'h00010020);
+ wb_user_core_read_check(32'h00000054,read_data,32'h00010021);
+ wb_user_core_read_check(32'h00000058,read_data,32'h00010022);
+ wb_user_core_read_check(32'h0000005C,read_data,32'h00010023);
+ wb_user_core_read_check(32'h00000060,read_data,32'h00010024);
+ wb_user_core_read_check(32'h00000064,read_data,32'h00010025);
+ wb_user_core_read_check(32'h00000068,read_data,32'h00010026);
+ wb_user_core_read_check(32'h0000006C,read_data,32'h00010027);
+ wb_user_core_read_check(32'h00000070,read_data,32'h00010028);
+ wb_user_core_read_check(32'h00000074,read_data,32'h00010029);
+ wb_user_core_read_check(32'h00000078,read_data,32'h00010030);
+ wb_user_core_read_check(32'h0000007C,read_data,32'h00010031);
+ wb_user_core_read_check(32'h00000080,read_data,32'h00010032);
+ wb_user_core_read_check(32'h00000084,read_data,32'h00010033);
+ wb_user_core_read_check(32'h00000088,read_data,32'h00010034);
+ wb_user_core_read_check(32'h0000008C,read_data,32'h00010035);
+ wb_user_core_read_check(32'h00000090,read_data,32'h00010036);
+ wb_user_core_read_check(32'h00000094,read_data,32'h00010037);
+ wb_user_core_read_check(32'h00000098,read_data,32'h00010038);
+ wb_user_core_read_check(32'h0000009C,read_data,32'h00010039);
+ wb_user_core_read_check(32'h000000A0,read_data,32'h00010040);
+ wb_user_core_read_check(32'h000000A4,read_data,32'h00010041);
+ wb_user_core_read_check(32'h000000A8,read_data,32'h00010042);
+ wb_user_core_read_check(32'h000000AC,read_data,32'h00010043);
+ wb_user_core_read_check(32'h000000B0,read_data,32'h00010044);
+ wb_user_core_read_check(32'h000000B4,read_data,32'h00010045);
+ wb_user_core_read_check(32'h000000B8,read_data,32'h00010046);
+ wb_user_core_read_check(32'h000000BC,read_data,32'h00010047);
+ wb_user_core_read_check(32'h000000C0,read_data,32'h00010048);
+ wb_user_core_read_check(32'h000000C4,read_data,32'h00010049);
+ wb_user_core_read_check(32'h000000C8,read_data,32'h00010050);
+ wb_user_core_read_check(32'h000000CC,read_data,32'h00010051);
+ wb_user_core_read_check(32'h000000D0,read_data,32'h00010052);
+ wb_user_core_read_check(32'h000000D4,read_data,32'h00010053);
+ wb_user_core_read_check(32'h000000D8,read_data,32'h00010054);
+ wb_user_core_read_check(32'h000000DC,read_data,32'h00010055);
+ wb_user_core_read_check(32'h000000E0,read_data,32'h00010056);
+ wb_user_core_read_check(32'h000000E4,read_data,32'h00010057);
+ wb_user_core_read_check(32'h000000E8,read_data,32'h00010058);
+ wb_user_core_read_check(32'h000000EC,read_data,32'h00010059);
+
+ repeat (100) @(posedge clock);
+ $display("#############################################");
+ $display(" Page Read through Indirect Access ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000010,{8'hF0,2'b01,2'b10,4'b0110,8'h00,8'hEB});
+ wb_user_core_write(32'h10000014,32'h00000000);
+
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010000);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010001);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010002);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010003);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010004);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010005);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010006);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010007);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010008);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010009);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010010);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010011);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010012);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010013);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010014);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010015);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010016);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010017);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010018);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010019);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010020);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010021);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010022);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010023);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010024);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010025);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010026);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010027);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010028);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010029);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010030);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010031);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010032);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010033);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010034);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010035);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010036);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010037);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010038);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010039);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010040);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010041);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010042);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010043);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010044);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010045);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010046);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010047);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010048);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010049);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010050);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010051);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010052);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010053);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010054);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010055);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010056);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010057);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010058);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00010059);
+
+ repeat (100) @(posedge clock);
+ $display("#############################################");
+ $display(" Page Write Command Address: 0x200 ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ // WEN COMMAND
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h0,2'b00,2'b00,4'b0000,8'h00,8'h06});
+ wb_user_core_write(32'h10000018,32'h0);
+ // Page Programing
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'hF0,2'b00,2'b10,P_FSM_CAW,8'h00,8'h02});
+ wb_user_core_write(32'h10000014,32'h00000200);
+ wb_user_core_write(32'h10000018,32'h00020000);
+ wb_user_core_write(32'h10000018,32'h00020001);
+ wb_user_core_write(32'h10000018,32'h00020002);
+ wb_user_core_write(32'h10000018,32'h00020003);
+ wb_user_core_write(32'h10000018,32'h00020004);
+ wb_user_core_write(32'h10000018,32'h00020005);
+ wb_user_core_write(32'h10000018,32'h00020006);
+ wb_user_core_write(32'h10000018,32'h00020007);
+ wb_user_core_write(32'h10000018,32'h00020008);
+ wb_user_core_write(32'h10000018,32'h00020009);
+ wb_user_core_write(32'h10000018,32'h00020010);
+ wb_user_core_write(32'h10000018,32'h00020011);
+ wb_user_core_write(32'h10000018,32'h00020012);
+ wb_user_core_write(32'h10000018,32'h00020013);
+ wb_user_core_write(32'h10000018,32'h00020014);
+ wb_user_core_write(32'h10000018,32'h00020015);
+ wb_user_core_write(32'h10000018,32'h00020016);
+ wb_user_core_write(32'h10000018,32'h00020017);
+ wb_user_core_write(32'h10000018,32'h00020018);
+ wb_user_core_write(32'h10000018,32'h00020019);
+ wb_user_core_write(32'h10000018,32'h00020020);
+ wb_user_core_write(32'h10000018,32'h00020021);
+ wb_user_core_write(32'h10000018,32'h00020022);
+ wb_user_core_write(32'h10000018,32'h00020023);
+ wb_user_core_write(32'h10000018,32'h00020024);
+ wb_user_core_write(32'h10000018,32'h00020025);
+ wb_user_core_write(32'h10000018,32'h00020026);
+ wb_user_core_write(32'h10000018,32'h00020027);
+ wb_user_core_write(32'h10000018,32'h00020028);
+ wb_user_core_write(32'h10000018,32'h00020029);
+ wb_user_core_write(32'h10000018,32'h00020030);
+ wb_user_core_write(32'h10000018,32'h00020031);
+ wb_user_core_write(32'h10000018,32'h00020032);
+ wb_user_core_write(32'h10000018,32'h00020033);
+ wb_user_core_write(32'h10000018,32'h00020034);
+ wb_user_core_write(32'h10000018,32'h00020035);
+ wb_user_core_write(32'h10000018,32'h00020036);
+ wb_user_core_write(32'h10000018,32'h00020037);
+ wb_user_core_write(32'h10000018,32'h00020038);
+ wb_user_core_write(32'h10000018,32'h00020039);
+ wb_user_core_write(32'h10000018,32'h00020040);
+ wb_user_core_write(32'h10000018,32'h00020041);
+ wb_user_core_write(32'h10000018,32'h00020042);
+ wb_user_core_write(32'h10000018,32'h00020043);
+ wb_user_core_write(32'h10000018,32'h00020044);
+ wb_user_core_write(32'h10000018,32'h00020045);
+ wb_user_core_write(32'h10000018,32'h00020046);
+ wb_user_core_write(32'h10000018,32'h00020047);
+ wb_user_core_write(32'h10000018,32'h00020048);
+ wb_user_core_write(32'h10000018,32'h00020049);
+ wb_user_core_write(32'h10000018,32'h00020050);
+ wb_user_core_write(32'h10000018,32'h00020051);
+ wb_user_core_write(32'h10000018,32'h00020052);
+ wb_user_core_write(32'h10000018,32'h00020053);
+ wb_user_core_write(32'h10000018,32'h00020054);
+ wb_user_core_write(32'h10000018,32'h00020055);
+ wb_user_core_write(32'h10000018,32'h00020056);
+ wb_user_core_write(32'h10000018,32'h00020057);
+ wb_user_core_write(32'h10000018,32'h00020058);
+ wb_user_core_write(32'h10000018,32'h00020059);
+
+ // RDSR
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b00,2'b00,4'b0001});
+ wb_user_core_write(32'h10000010,{8'h4,2'b00,2'b00,4'b1011,8'h00,8'h05});
+ read_data = 32'hFFFF_FFFF;
+ while (read_data[1:0] == 2'b11) begin
+ wb_user_core_read(32'h1000001C,read_data);
+ repeat (10) @(posedge clock);
+ end
+
+ $display("#############################################");
+ $display(" Page Read through Direct Access ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h00); // Change the Bank Sel 00
+ wb_user_core_read_check(32'h00000200,read_data,32'h00020000);
+ wb_user_core_read_check(32'h00000204,read_data,32'h00020001);
+ wb_user_core_read_check(32'h00000208,read_data,32'h00020002);
+ wb_user_core_read_check(32'h0000020C,read_data,32'h00020003);
+ wb_user_core_read_check(32'h00000210,read_data,32'h00020004);
+ wb_user_core_read_check(32'h00000214,read_data,32'h00020005);
+ wb_user_core_read_check(32'h00000218,read_data,32'h00020006);
+ wb_user_core_read_check(32'h0000021C,read_data,32'h00020007);
+ wb_user_core_read_check(32'h00000220,read_data,32'h00020008);
+ wb_user_core_read_check(32'h00000224,read_data,32'h00020009);
+ wb_user_core_read_check(32'h00000228,read_data,32'h00020010);
+ wb_user_core_read_check(32'h0000022C,read_data,32'h00020011);
+ wb_user_core_read_check(32'h00000230,read_data,32'h00020012);
+ wb_user_core_read_check(32'h00000234,read_data,32'h00020013);
+ wb_user_core_read_check(32'h00000238,read_data,32'h00020014);
+ wb_user_core_read_check(32'h0000023C,read_data,32'h00020015);
+ wb_user_core_read_check(32'h00000240,read_data,32'h00020016);
+ wb_user_core_read_check(32'h00000244,read_data,32'h00020017);
+ wb_user_core_read_check(32'h00000248,read_data,32'h00020018);
+ wb_user_core_read_check(32'h0000024C,read_data,32'h00020019);
+ wb_user_core_read_check(32'h00000250,read_data,32'h00020020);
+ wb_user_core_read_check(32'h00000254,read_data,32'h00020021);
+ wb_user_core_read_check(32'h00000258,read_data,32'h00020022);
+ wb_user_core_read_check(32'h0000025C,read_data,32'h00020023);
+ wb_user_core_read_check(32'h00000260,read_data,32'h00020024);
+ wb_user_core_read_check(32'h00000264,read_data,32'h00020025);
+ wb_user_core_read_check(32'h00000268,read_data,32'h00020026);
+ wb_user_core_read_check(32'h0000026C,read_data,32'h00020027);
+ wb_user_core_read_check(32'h00000270,read_data,32'h00020028);
+ wb_user_core_read_check(32'h00000274,read_data,32'h00020029);
+ wb_user_core_read_check(32'h00000278,read_data,32'h00020030);
+ wb_user_core_read_check(32'h0000027C,read_data,32'h00020031);
+ wb_user_core_read_check(32'h00000280,read_data,32'h00020032);
+ wb_user_core_read_check(32'h00000284,read_data,32'h00020033);
+ wb_user_core_read_check(32'h00000288,read_data,32'h00020034);
+ wb_user_core_read_check(32'h0000028C,read_data,32'h00020035);
+ wb_user_core_read_check(32'h00000290,read_data,32'h00020036);
+ wb_user_core_read_check(32'h00000294,read_data,32'h00020037);
+ wb_user_core_read_check(32'h00000298,read_data,32'h00020038);
+ wb_user_core_read_check(32'h0000029C,read_data,32'h00020039);
+ wb_user_core_read_check(32'h000002A0,read_data,32'h00020040);
+ wb_user_core_read_check(32'h000002A4,read_data,32'h00020041);
+ wb_user_core_read_check(32'h000002A8,read_data,32'h00020042);
+ wb_user_core_read_check(32'h000002AC,read_data,32'h00020043);
+ wb_user_core_read_check(32'h000002B0,read_data,32'h00020044);
+ wb_user_core_read_check(32'h000002B4,read_data,32'h00020045);
+ wb_user_core_read_check(32'h000002B8,read_data,32'h00020046);
+ wb_user_core_read_check(32'h000002BC,read_data,32'h00020047);
+ wb_user_core_read_check(32'h000002C0,read_data,32'h00020048);
+ wb_user_core_read_check(32'h000002C4,read_data,32'h00020049);
+ wb_user_core_read_check(32'h000002C8,read_data,32'h00020050);
+ wb_user_core_read_check(32'h000002CC,read_data,32'h00020051);
+ wb_user_core_read_check(32'h000002D0,read_data,32'h00020052);
+ wb_user_core_read_check(32'h000002D4,read_data,32'h00020053);
+ wb_user_core_read_check(32'h000002D8,read_data,32'h00020054);
+ wb_user_core_read_check(32'h000002DC,read_data,32'h00020055);
+ wb_user_core_read_check(32'h000002E0,read_data,32'h00020056);
+ wb_user_core_read_check(32'h000002E4,read_data,32'h00020057);
+ wb_user_core_read_check(32'h000002E8,read_data,32'h00020058);
+ wb_user_core_read_check(32'h000002EC,read_data,32'h00020059);
+
+ repeat (10) @(posedge clock);
+ $display("#############################################");
+ $display(" Page Read through Indirect Access ");
+ $display("#############################################");
+ wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(32'h1000000C,{15'h0,1'b0,2'b01,2'b10,4'b0001});
+ wb_user_core_write(32'h10000010,{8'hF0,2'b01,2'b10,4'b0110,8'h00,8'hEB});
+ wb_user_core_write(32'h10000014,32'h00000200);
+
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020000);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020001);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020002);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020003);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020004);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020005);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020006);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020007);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020008);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020009);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020010);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020011);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020012);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020013);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020014);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020015);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020016);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020017);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020018);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020019);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020020);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020021);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020022);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020023);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020024);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020025);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020026);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020027);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020028);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020029);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020030);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020031);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020032);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020033);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020034);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020035);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020036);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020037);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020038);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020039);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020040);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020041);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020042);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020043);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020044);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020045);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020046);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020047);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020048);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020049);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020050);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020051);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020052);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020053);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020054);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020055);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020056);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020057);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020058);
+ wb_user_core_read_check(32'h1000001C,read_data,32'h00020059);
+
repeat (100) @(posedge clock);
// $display("+1000 cycles");
@@ -508,7 +1209,8 @@
// Quard flash
s25fl256s #(.mem_file_name("user_risc_boot.hex"),
- .otp_file_name("none"))
+ .otp_file_name("none"),
+ .TimingModel("S25FL512SAGMFI010_F_30pF"))
u_spi_flash_256mb (
// Data Inputs/Outputs
.SI (flash_io0),
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
index 10dca8b..3edeaba 100644
--- a/verilog/dv/user_uart/user_uart_tb.v
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -190,7 +190,7 @@
// Remove all the reset
wb_user_core_write('h3080_0000,'hF);
- repeat (20000) @(posedge clock); // wait for Processor Get Ready
+ repeat (16000) @(posedge clock); // wait for Processor Get Ready
tb_uart.uart_init;
wb_user_core_write(`ADDR_SPACE_UART+8'h0,{3'h0,2'b00,1'b1,1'b1,1'b1});
@@ -412,7 +412,10 @@
// Quard flash
- s25fl256s #(.mem_file_name("user_uart.hex"),.otp_file_name("none")) u_spi_flash_256mb
+ s25fl256s #(.mem_file_name("user_uart.hex"),
+ .otp_file_name("none"),
+ .TimingModel("S25FL512SAGMFI010_F_30pF"))
+ u_spi_flash_256mb
(
// Data Inputs/Outputs
.SI (flash_io0),
diff --git a/verilog/rtl/spi_master/src/spim_ctrl.sv b/verilog/rtl/spi_master/src/spim_ctrl.sv
index e53a531..42f7a5d 100644
--- a/verilog/rtl/spi_master/src/spim_ctrl.sv
+++ b/verilog/rtl/spi_master/src/spim_ctrl.sv
@@ -178,6 +178,7 @@
parameter P_FSM_CDR = 4'b1001; // COMMAND -> DUMMY -> READ
parameter P_FSM_CDW = 4'b1010; // COMMAND -> DUMMY -> WRITE
+parameter P_FSM_CR = 4'b1011; // COMMAND -> READ
//---------------------
parameter P_8BIT = 2'b00;
@@ -200,7 +201,6 @@
logic spi_en_rx;
- logic res_fifo_flush;
logic [15:0] counter_tx;
logic counter_tx_valid;
@@ -224,7 +224,6 @@
logic tx_clk_en;
logic rx_clk_en;
- logic en_quad_in;
logic [1:0] cnt; // counter for cs assertion and de-assertion
logic [1:0] nxt_cnt;
logic [1:0] gnt;
@@ -239,11 +238,10 @@
enum logic [2:0] {DATA_NULL,DATA_EMPTY,DATA_CMD,DATA_ADDR,DATA_MODE,DATA_FIFO} ctrl_data_mux;
enum logic [4:0] {FSM_IDLE,FSM_CS_ASSERT,FSM_CMD_PHASE,FSM_ADR_PHASE,FSM_DUMMY_PHASE,FSM_MODE_PHASE,FSM_WRITE_CMD,FSM_WRITE_PHASE,
- FSM_READ_WAIT,FSM_READ_PHASE,FSM_TX_DONE,FSM_CS_DEASEERT} state,next_state;
+ FSM_READ_WAIT,FSM_READ_PHASE,FSM_TX_DONE,FSM_FLUSH,FSM_CS_DEASEERT} state,next_state;
assign ctrl_state = state[3:0];
- assign en_quad_in = (s_spi_mode == SPI_STD) ? 1'b0 : 1'b1;
assign spi_mode = s_spi_mode;
@@ -299,13 +297,12 @@
// care of partial reading case.
//---------------------------------------------------------------------------
- assign m0_res_fifo_flush = (gnt == 2'b01) ? res_fifo_flush : 1'b0;
- assign m1_res_fifo_flush = (gnt == 2'b10) ? res_fifo_flush : 1'b0;
+ logic fsm_flush;
+ assign m0_res_fifo_flush = (gnt == 2'b01) ? fsm_flush : 1'b0;
+ assign m1_res_fifo_flush = (gnt == 2'b10) ? fsm_flush : 1'b0;
assign spi_clock_en = tx_clk_en | rx_clk_en;
- logic fsm_flush;
- assign fsm_flush = (state == FSM_IDLE);
spim_clkgen u_clkgen
(
@@ -329,8 +326,9 @@
.sdo1 ( spi_sdo1 ),
.sdo2 ( spi_sdo2 ),
.sdo3 ( spi_sdo3 ),
- .en_quad_in ( en_quad_in ),
+ .s_spi_mode ( s_spi_mode ),
.counter_in ( counter_tx ),
+ .counter_in_upd ( counter_tx_valid ),
.txdata ( data_to_tx ),
.data_valid ( data_to_tx_valid ),
.data_ready ( tx_data_ready ),
@@ -348,7 +346,7 @@
.sdi1 ( spi_sdi1 ),
.sdi2 ( spi_sdi2 ),
.sdi3 ( spi_sdi3 ),
- .en_quad_in ( en_quad_in ),
+ .s_spi_mode ( s_spi_mode ),
.counter_in ( counter_rx ),
.counter_in_upd ( counter_rx_valid ),
.data ( res_fifo_wdata ),
@@ -405,6 +403,7 @@
always_comb
begin
+ fsm_flush = 0;
counter_tx = '0;
counter_tx_valid = 1'b0;
counter_rx = '0;
@@ -416,7 +415,6 @@
spi_en_tx = 1'b0;
spi_status = '0;
cmd_fifo_rd = 1'b0;
- res_fifo_flush = 0;
nxt_cnt = cnt;
case(state)
FSM_IDLE:
@@ -430,6 +428,7 @@
// Asserted CS# low
FSM_CS_ASSERT: begin
+ fsm_flush=1; // Flush stale data in response fifo
if(cfg_cs_early == cnt) begin
next_state = FSM_CMD_PHASE;
end else begin
@@ -459,6 +458,7 @@
P_FSM_CADW: next_state = FSM_ADR_PHASE;
P_FSM_CDR: next_state = FSM_DUMMY_PHASE;
P_FSM_CDW: next_state = FSM_DUMMY_PHASE;
+ P_FSM_CR: next_state = FSM_READ_WAIT;
default : next_state = FSM_TX_DONE;
endcase
end
@@ -562,7 +562,6 @@
FSM_READ_WAIT: begin
spi_en_tx = 1'b1;
if (tx_done) begin
- res_fifo_flush = 1; // Flush any stall data in response fifo
next_state = FSM_READ_PHASE;
end
end
@@ -574,7 +573,7 @@
spi_en_rx = 1'b1;
if(!cmd_fifo_empty) begin
// If you see new command request, then abort the current request
- next_state = FSM_CS_DEASEERT;
+ next_state = FSM_FLUSH;
end else begin
if (rx_done && spi_rise) begin
next_state = FSM_CS_DEASEERT;
@@ -582,6 +581,13 @@
end
end
+ FSM_FLUSH: begin
+ fsm_flush = 1;
+ // Wait for safe SPI-clock de-assertion phase
+ if(spi_clock_en ==0) begin
+ next_state = FSM_CS_DEASEERT;
+ end
+ end
// Wait for TX Done
FSM_TX_DONE: begin
spi_en_tx = 1'b1;
@@ -666,7 +672,7 @@
s_spi_mode <= SPI_STD;
end else if(state == FSM_ADR_PHASE && cfg_spi_switch == P_MODE_SWITCH_AT_ADDR) begin
s_spi_mode <= cfg_spi_mode;
- end else if(state == FSM_DUMMY_PHASE && cfg_spi_switch == P_MODE_SWITCH_AT_DATA) begin
+ end else if(((state == FSM_READ_PHASE) || state == FSM_WRITE_CMD ) && cfg_spi_switch == P_MODE_SWITCH_AT_DATA) begin
s_spi_mode <= cfg_spi_mode;
end
end
diff --git a/verilog/rtl/spi_master/src/spim_if.sv b/verilog/rtl/spi_master/src/spim_if.sv
index e8c85e0..d47adcb 100644
--- a/verilog/rtl/spi_master/src/spim_if.sv
+++ b/verilog/rtl/spi_master/src/spim_if.sv
@@ -125,7 +125,8 @@
// State Machine state
parameter IDLE = 4'b000;
parameter ADR_PHASE = 4'b001;
-parameter READ_DATA = 4'b010;
+parameter CMD_WAIT = 4'b010;
+parameter READ_DATA = 4'b011;
/*************************************************************
* SPI FSM State Control
@@ -187,6 +188,9 @@
logic spim_mem_ack ;
logic [3:0] next_state ;
+logic NextPreDVal ;
+logic [7:0] NextPreDCnt ;
+logic [31:0] NextPreAddr ;
//---------------------------------------------------------------
@@ -266,7 +270,12 @@
next_state = state;
case(state)
IDLE: begin
- if(spim_mem_req && cmd_fifo_empty) begin
+ // Check If any prefetch data available and if see it matched with WB
+ // address, If yes, the move to data reading from response fifo, else
+ // generate command request
+ if(spim_mem_req && NextPreDVal && (spim_wb_addr == NextPreAddr)) begin
+ next_state = READ_DATA;
+ end else if(spim_mem_req && cmd_fifo_empty) begin
cmd_fifo_wdata = {SOC,NOC,cfg_data_cnt[7:0],cfg_dummy_cnt[1:0],cfg_addr_cnt[1:0],cfg_mem_seq[3:0],cfg_mode_reg[7:0],cfg_cmd_reg[7:0]};
cmd_fifo_wr = 1;
next_state = ADR_PHASE;
@@ -275,8 +284,13 @@
ADR_PHASE: begin
cmd_fifo_wdata = {NOC,EOC,spim_wb_addr[31:0]};
cmd_fifo_wr = 1;
- next_state = READ_DATA;
+ next_state = CMD_WAIT;
end
+ CMD_WAIT: begin
+ // Wait for Command Accepted, before reading data
+ // to take care of staled data being read due to pre-fetch logic
+ if(cmd_fifo_empty) next_state = READ_DATA;
+ end
READ_DATA: begin
@@ -289,7 +303,33 @@
end
endcase
end
+
+/*****************************************************************
+* This logic help to find any pre-fetch data available inside the response
+* FIFO and if the next data read request address matches with NextPreAddr, The read
+* the data from Response FIFO, else generate new request
+* Note: Basic Assumption is cmd_fifo_wr & res_fifo_rd does not occur in same
+* time as it's generation control through FSM
+* **********************************************************/
+always_ff @(negedge rst_n or posedge mclk) begin
+ if ( rst_n == 1'b0 ) begin
+ NextPreDVal <= 1'b0;
+ NextPreDCnt <= 'h0;
+ NextPreAddr <= 'h0;
+ end else if(cmd_fifo_wr) begin
+ NextPreDVal <= 1'b1;
+ NextPreDCnt <= cfg_data_cnt;
+ NextPreAddr <= spim_wb_addr;
+ end else if (res_fifo_rd) begin
+ if(NextPreDCnt == 4) begin
+ NextPreDVal <= 1'b0;
+ end else begin
+ NextPreDCnt <= NextPreDCnt-4;
+ NextPreAddr <= NextPreAddr+4;
+ end
+ end
+end
endmodule
diff --git a/verilog/rtl/spi_master/src/spim_regs.sv b/verilog/rtl/spi_master/src/spim_regs.sv
index f3fa7e1..545e3b3 100644
--- a/verilog/rtl/spi_master/src/spim_regs.sv
+++ b/verilog/rtl/spi_master/src/spim_regs.sv
@@ -221,6 +221,7 @@
parameter P_FSM_CDR = 4'b1001; // COMMAND -> DUMMY -> READ
parameter P_FSM_CDW = 4'b1010; // COMMAND -> DUMMY -> WRITE
+parameter P_FSM_CR = 4'b1011; // COMMAND -> READ
//---------------------------------------------------------
parameter P_CS0 = 4'b0001;
parameter P_CS1 = 4'b0010;
@@ -341,7 +342,7 @@
cfg_m0_spi_seq[3:0] <= P_FSM_CAMDR;
cfg_m0_addr_cnt[1:0] <= P_24BIT;
cfg_m0_dummy_cnt[1:0] <= P_16BIT;
- cfg_m0_data_cnt[7:0] <= 4; // 4 Byte
+ cfg_m0_data_cnt[7:0] <= 8'h20; // 32 Byte
cfg_m1_fsm_reset <= 'h0;
cfg_m1_cs_reg <= P_CS0;
@@ -607,74 +608,45 @@
case(state)
FSM_IDLE: begin
+ next_cnt = 0;
if(spim_fifo_req && cmd_fifo_empty) begin
case(cfg_m1_spi_seq)
P_FSM_C: begin
cmd_fifo_wdata = {SOC,EOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
+ spim_m1_wrdy = 1;
next_state = FSM_ACK_PHASE;
end
- P_FSM_CW: begin
+ P_FSM_CW,
+ P_FSM_CDW:
+ begin
cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
next_state = FSM_WRITE_PHASE;
end
- P_FSM_CA: begin
+ P_FSM_CA,
+ P_FSM_CAR,
+ P_FSM_CADR,
+ P_FSM_CAMR,
+ P_FSM_CAMDR,
+ P_FSM_CAW,
+ P_FSM_CADW:
+ begin
cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
next_state = FSM_ADR_PHASE;
end
- P_FSM_CAR: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CADR: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CAMR: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CAMDR: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CAW: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CADW: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_ADR_PHASE;
- end
- P_FSM_CDR: begin
+ P_FSM_CDR,
+ P_FSM_CR:
+ begin
cmd_fifo_wdata = {SOC,EOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
next_state = FSM_READ_PHASE;
end
- P_FSM_CDW: begin
- cmd_fifo_wdata = {SOC,NOC, cfg_m1_data_cnt[7:0],cfg_m1_dummy_cnt[1:0],
- cfg_m1_addr_cnt[1:0],cfg_m1_spi_seq[3:0],
- cfg_m1_mode_reg[7:0],cfg_m1_cmd_reg[7:0]};
- next_state = FSM_WRITE_PHASE;
- end
endcase
@@ -688,26 +660,12 @@
P_FSM_CA: // COMMAND + ADDRESS PHASE
begin
cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]};
+ spim_m1_wrdy = 1;
next_state = FSM_ACK_PHASE;
end
- P_FSM_CAR: // COMMAND + ADDRESS + READ PHASE
- begin
- cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]};
- next_cnt = 'h0;
- next_state = FSM_READ_PHASE;
- end
- P_FSM_CADR: // COMMAND + ADDRESS + DUMMY + READ PHASE
- begin
- cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]};
- next_cnt = 'h0;
- next_state = FSM_READ_PHASE;
- end
- P_FSM_CAMR: // COMMAND + ADDRESS + MODE + READ PHASE
- begin
- cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]};
- next_cnt = 'h0;
- next_state = FSM_READ_PHASE;
- end
+ P_FSM_CAR, // COMMAND + ADDRESS + READ PHASE
+ P_FSM_CADR, // COMMAND + ADDRESS + DUMMY + READ PHASE
+ P_FSM_CAMR, // COMMAND + ADDRESS + MODE + READ PHASE
P_FSM_CAMDR: // COMMAND + ADDRESS + MODE + DUMMY + READ PHASE
begin
cmd_fifo_wdata = {NOC,EOC,cfg_m1_addr[31:0]};
@@ -715,12 +673,9 @@
next_state = FSM_READ_PHASE;
end
- P_FSM_CAW:begin
- cmd_fifo_wdata = {NOC,NOC,cfg_m1_addr[31:0]};
- next_cnt = 'h0;
- next_state = FSM_WRITE_PHASE;
- end
- P_FSM_CADW: begin
+ P_FSM_CAW,
+ P_FSM_CADW:
+ begin
cmd_fifo_wdata = {NOC,NOC,cfg_m1_addr[31:0]};
next_cnt = 'h0;
next_state = FSM_WRITE_PHASE;
diff --git a/verilog/rtl/spi_master/src/spim_rx.sv b/verilog/rtl/spi_master/src/spim_rx.sv
index 6e183de..47c4922 100644
--- a/verilog/rtl/spi_master/src/spim_rx.sv
+++ b/verilog/rtl/spi_master/src/spim_rx.sv
@@ -77,7 +77,7 @@
input logic sdi1,
input logic sdi2,
input logic sdi3,
- input logic en_quad_in,
+ input logic [1:0] s_spi_mode,
input logic [15:0] counter_in,
input logic counter_in_upd,
output logic [31:0] data,
@@ -85,6 +85,16 @@
output logic data_valid,
output logic clk_en_o
);
+//------------------------------------------------------
+// Parameter Decleration
+// -----------------------------------------------------
+ parameter P_SINGLE = 2'b00;
+ parameter P_DOUBLE = 2'b01;
+ parameter P_QUAD = 2'b10;
+
+//------------------------------------------------------
+// Variable Decleration
+// -----------------------------------------------------
logic [31:0] data_int;
logic [31:0] data_int_next;
@@ -96,7 +106,9 @@
enum logic [1:0] { IDLE, RECEIVE, WAIT_FIFO, WAIT_FIFO_DONE } rx_CS, rx_NS;
- assign reg_done = (!en_quad_in && (counter[4:0] == 5'b11111)) || (en_quad_in && (counter[2:0] == 3'b111));
+ assign reg_done = (s_spi_mode == P_SINGLE && (counter[4:0] == 5'b11111)) ||
+ (s_spi_mode == P_DOUBLE && (counter[3:0] == 4'b1111)) ||
+ (s_spi_mode == P_QUAD && (counter[2:0] == 3'b111));
@@ -120,23 +132,24 @@
if (rx_edge) begin
counter_next = counter + 1;
- if (en_quad_in)
+ if (s_spi_mode == P_QUAD )
data_int_next = {data_int[27:0],sdi3,sdi2,sdi1,sdi0};
+ else if (s_spi_mode == P_DOUBLE )
+ data_int_next = {data_int[29:0],sdi1,sdi0};
else
data_int_next = {data_int[30:0],sdi1};
if (rx_done) begin
- counter_next = 0;
- data_valid_i = 1'b1;
-
- if (data_ready)
- rx_NS = IDLE;
- else
- rx_NS = WAIT_FIFO_DONE;
+ counter_next = 0;
+ if (data_ready) begin
+ data_valid_i = 1'b1;
+ rx_NS = IDLE;
+ end else
+ rx_NS = WAIT_FIFO_DONE;
end else if (reg_done) begin
- data_valid_i = 1'b1;
-
- if (~data_ready) begin
+ if (data_ready) begin
+ data_valid_i = 1'b1;
+ end else begin
// no space in the FIFO, wait for free space
rx_NS = WAIT_FIFO;
end
@@ -145,15 +158,17 @@
end
WAIT_FIFO_DONE: begin
- data_valid_i = 1'b1;
- if (data_ready)
- rx_NS = IDLE;
+ if (data_ready) begin
+ data_valid_i = 1'b1;
+ rx_NS = IDLE;
+ end
end
WAIT_FIFO: begin
- data_valid_i = 1'b1;
- if (data_ready)
- rx_NS = RECEIVE;
+ if (data_ready) begin
+ data_valid_i = 1'b1;
+ rx_NS = RECEIVE;
+ end
end
endcase
end
@@ -171,7 +186,7 @@
data <= 'b0;
data_valid <= 1'b0;
rx_CS <= IDLE;
- end else if(flush) begin
+ end else if(flush && rx_edge) begin
counter <= 0;
counter_trgt <= 'h8;
data_int <= '0;
@@ -191,7 +206,8 @@
clk_en_o <= (rx_NS == RECEIVE);
end
if (en && counter_in_upd) begin
- counter_trgt <= (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in;
+ counter_trgt <= (s_spi_mode ==P_QUAD ) ? {2'b00,counter_in[15:2]} :
+ (s_spi_mode ==P_DOUBLE ) ? {1'b0,counter_in[15:1]} : counter_in;
end
end
end
diff --git a/verilog/rtl/spi_master/src/spim_top.sv b/verilog/rtl/spi_master/src/spim_top.sv
index 515cc18..b1af420 100644
--- a/verilog/rtl/spi_master/src/spim_top.sv
+++ b/verilog/rtl/spi_master/src/spim_top.sv
@@ -34,10 +34,14 @@
//// accesss are supported. ////
//// Upto 255 Byte Read/Write Burst supported ////
//// Limitation: ////
-//// 1. Write/Read FIFO Abort case not managed, expect ////
-//// user to clearly close the busrt request ////
+//// 1. Write/Read FIFO Abort case not managed M1 port, ////
+//// expect user to clearly close the busrt request ////
//// 2. Wishbone Request abort not yet supported. ////
//// 3. Write access through M0 Port not supported ////
+//// 4. When Pre fetch feature used and both port m0 and ////
+//// m1 used, user need to make sure that data pre fetch////
+//// count is withing 8DW, less Read path can hang due ////
+//// to response FIFO full from one master port ////
//// ////
//// To Do: ////
//// 1. Add support for WishBone request timout ////
@@ -54,6 +58,14 @@
//// V.2 - July 6, 2021 ////
//// Added Hold fix cell for SPI data out signal to ////
//// met interface hold ////
+//// V.3 - July 13, 2021 ////
+//// Data Prefetch feature added in M0 port, If Only ////
+//// M0 Read used, then Prefetch read can be 255 Byte, ////
+//// But if the Both M0 and M1 read access enabled, ////
+//// then user need to make sure that M0 Prefetch is ////
+//// with in 8DW or 32 Byte, else there is chance ////
+//// data path can hang due to response FIFO full due ////
+//// to partial reading of data ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
@@ -380,7 +392,7 @@
);
// Master 0 Response FIFO
- spim_fifo #(.W(32), .DP(4)) u_m0_res_fifo (
+ spim_fifo #(.W(32), .DP(8)) u_m0_res_fifo (
.clk (mclk ),
.reset_n (rst_n ),
.flush (m0_res_fifo_flush ),
@@ -409,7 +421,7 @@
.rd_data (m1_cmd_fifo_rdata )
);
// Master 1 Response FIFO
- spim_fifo #(.W(32), .DP(2)) u_m1_res_fifo (
+ spim_fifo #(.W(32), .DP(8)) u_m1_res_fifo (
.clk (mclk ),
.reset_n (rst_n ),
.flush (m1_res_fifo_flush ),
diff --git a/verilog/rtl/spi_master/src/spim_tx.sv b/verilog/rtl/spi_master/src/spim_tx.sv
index b904d33..20c499f 100644
--- a/verilog/rtl/spi_master/src/spim_tx.sv
+++ b/verilog/rtl/spi_master/src/spim_tx.sv
@@ -81,29 +81,43 @@
output logic sdo1, // SPI Dout1
output logic sdo2, // SPI Dout2
output logic sdo3, // SPI Dout3
- input logic en_quad_in, // SPI quad mode indication
+ input logic [1:0] s_spi_mode, // SPI quad mode indication
input logic [15:0] counter_in, // Transmit counter
+ input logic counter_in_upd,
input logic [31:0] txdata, // 32 bit tranmsit data
input logic data_valid, // Input data valid
output logic data_ready, // Data in acepted, this for txfifo
output logic clk_en_o // Enable Tx clock
);
+//------------------------------------------------------
+// Parameter Decleration
+// -----------------------------------------------------
+ parameter P_SINGLE = 2'b00;
+ parameter P_DOUBLE = 2'b01;
+ parameter P_QUAD = 2'b10;
+
+//------------------------------------------------------
+// Variable Decleration
+// -----------------------------------------------------
logic [31:0] data_int ; // Data Input
logic [31:0] data_int_next ; // Next Data Input
logic [15:0] counter ; // Tx Counter
logic [15:0] counter_next ; // tx next counter
logic [15:0] counter_trgt ; // counter exit counter
logic tx32b_done ; // 32 bit Transmit done
- logic en_quad;
- logic en_quad_next;
+ logic [1:0] spi_mode ;
+ logic [1:0] spi_mode_next;
logic data_ready_i; // Data in acepted, this for txfifo
- enum logic [0:0] { IDLE, TRANSMIT } tx_CS, tx_NS;
+ logic next_data_ready_i;// Data in acepted, this for txfifo
+ enum logic [1:0] { IDLE, TRANSMIT,WAIT_FIFO_AVAIL } tx_CS, tx_NS;
// Indicate 32 bit data done, usefull for readining next 32b from txfifo
- assign tx32b_done = (!en_quad && (counter[4:0] == 5'b11111)) || (en_quad && (counter[2:0] == 3'b111));
+ assign tx32b_done = (spi_mode == P_SINGLE && (counter[4:0] == 5'b11111)) ||
+ (spi_mode == P_DOUBLE && (counter[3:0] == 4'b1111)) ||
+ (spi_mode == P_QUAD && (counter[2:0] == 3'b111));
assign tx_done = (counter == (counter_trgt-1)) && (tx_CS == TRANSMIT);
@@ -114,8 +128,9 @@
tx_NS = tx_CS;
data_int_next = data_int;
data_ready_i = 1'b0;
+ next_data_ready_i = 1'b0;
counter_next = counter;
- en_quad_next = en_quad;
+ spi_mode_next = spi_mode;
case (tx_CS)
IDLE: begin
@@ -123,7 +138,7 @@
counter_next = '0;
if (en && data_valid) begin
- en_quad_next = en_quad_in;
+ spi_mode_next = s_spi_mode;
data_ready_i = 1'b1;
tx_NS = TRANSMIT;
end
@@ -134,7 +149,7 @@
counter_next = 0;
// Check if there is next data
if (en && data_valid) begin
- en_quad_next = en_quad_in;
+ spi_mode_next = s_spi_mode;
data_int_next = txdata;
data_ready_i = 1'b1;
tx_NS = TRANSMIT;
@@ -143,18 +158,28 @@
end
end else if (tx32b_done) begin
if (en && data_valid) begin
- en_quad_next = en_quad_in;
+ spi_mode_next = s_spi_mode;
data_int_next = txdata;
- data_ready_i = 1'b1;
+ next_data_ready_i = 1'b1;
+ counter_next = counter + 1;
tx_NS = TRANSMIT;
end else begin
- tx_NS = IDLE;
+ tx_NS = WAIT_FIFO_AVAIL;
end
end else begin
counter_next = counter + 1;
- data_int_next = (en_quad) ? {data_int[27:0],4'b0000} : {data_int[30:0],1'b0};
+ data_int_next = (spi_mode == P_QUAD ) ? {data_int[27:0],4'b0000} :
+ (spi_mode == P_DOUBLE ) ? {data_int[29:0],2'b00} : {data_int[30:0],1'b0};
end
end
+ WAIT_FIFO_AVAIL: begin
+ if (en && data_valid) begin
+ spi_mode_next = s_spi_mode;
+ data_int_next = txdata;
+ data_ready_i = 1'b1;
+ tx_NS = TRANSMIT;
+ end
+ end
endcase
end
@@ -167,7 +192,6 @@
counter <= 0;
data_int <= 'h0;
tx_CS <= IDLE;
- en_quad <= 0;
sdo0 <= '0;
sdo1 <= '0;
sdo2 <= '1;
@@ -175,12 +199,12 @@
counter_trgt <= '0;
data_ready <= '0;
data_ready_f <= 0;
+ spi_mode <= P_SINGLE;
end
- else if(flush) begin
+ else if(flush && tx_edge) begin
counter <= 0;
data_int <= 'h0;
tx_CS <= IDLE;
- en_quad <= 0;
sdo0 <= '0;
sdo1 <= '0;
sdo2 <= '1;
@@ -188,9 +212,10 @@
counter_trgt <= '0;
data_ready <= '0;
data_ready_f <= 0;
+ spi_mode <= P_SINGLE;
end else begin
- data_ready_f <= data_ready_i;
- data_ready <= data_ready_f && !data_ready_i; // Generate Pulse at falling edge
+ data_ready_f <= data_ready_i | next_data_ready_i;
+ data_ready <= data_ready_f && !(data_ready_i | next_data_ready_i); // Generate Pulse at falling edge
if(tx_edge) begin
tx_CS <= tx_NS;
counter <= counter_next;
@@ -198,14 +223,15 @@
end
// Counter Exit condition, quad mode div-4 , else actual counter
if (en && data_ready_i && tx_edge) begin
- en_quad <= en_quad_in;
- counter_trgt <= (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in;
+ spi_mode <= s_spi_mode;
+ counter_trgt <= (s_spi_mode == P_QUAD ) ? {2'b00,counter_in[15:2]} :
+ (s_spi_mode == P_DOUBLE ) ? {1'b0, counter_in[15:1]} : counter_in;
end
if(tx_edge && tx_NS == TRANSMIT) begin
- sdo0 <= (en_quad_next) ? data_int_next[28] : data_int_next[31];
- sdo1 <= (en_quad_next) ? data_int_next[29] : 1'b0;
- sdo2 <= (en_quad_next) ? data_int_next[30] : 1'b1; // Protect
- sdo3 <= (en_quad_next) ? data_int_next[31] : 1'b1; // Hold need to '1'
+ sdo0 <= (spi_mode_next == P_QUAD) ? data_int_next[28] : (spi_mode_next == P_DOUBLE) ? data_int_next[30] : data_int_next[31];
+ sdo1 <= (spi_mode_next == P_QUAD) ? data_int_next[29] : (spi_mode_next == P_DOUBLE) ? data_int_next[31] : 1'b0;
+ sdo2 <= (spi_mode_next == P_QUAD) ? data_int_next[30] : 1'b1; // Protect
+ sdo3 <= (spi_mode_next == P_QUAD) ? data_int_next[31] : 1'b1; // Hold need to '1'
end
end
end