spi isp mode added + mpw7 tool version
diff --git a/openlane/Makefile b/openlane/Makefile
index 865f452..c21989a 100644
--- a/openlane/Makefile
+++ b/openlane/Makefile
@@ -18,7 +18,7 @@
CONFIG = $(foreach block,$(BLOCKS), ./$(block)/config.tcl)
CLEAN = $(foreach block,$(BLOCKS), clean-$(block))
-OPENLANE_TAG = mpw5
+OPENLANE_TAG = mpw7
OPENLANE_IMAGE_NAME = riscduino/openlane:$(OPENLANE_TAG)
OPENLANE_BASIC_COMMAND = "cd $(PWD)/../openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite"
OPENLANE_INTERACTIVE_COMMAND = "cd $(PWD)/../openlane && flow.tcl -design ./$* -save_path .. -save -tag $* -overwrite -it -file ./$*/interactive.tcl"
@@ -43,15 +43,29 @@
@sleep 1
@if [ -f ./$*/interactive.tcl ]; then\
- docker run --rm \
+ docker run --rm -v $(OPENLANE_ROOT):/openlane \
+ -v $(PDK_ROOT):$(PDK_ROOT) \
-v $(PWD)/..:$(PWD)/.. \
+ -v $(MCW_ROOT):$(MCW_ROOT) \
+ -v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
+ -e MCW_ROOT=$(MCW_ROOT) \
+ -e PDK_ROOT=$(PDK_ROOT) \
+ -e CARAVEL_ROOT=$(CARAVEL_ROOT) \
+ -e PDK=$(PDK) \
-e TEST_MISMATCHES=tools \
-e MISMATCHES_OK=1 \
-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
$(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_INTERACTIVE_COMMAND);\
else\
- docker run --rm \
+ docker run --rm -v $(OPENLANE_ROOT):/openlane \
+ -v $(PDK_ROOT):$(PDK_ROOT) \
-v $(PWD)/..:$(PWD)/.. \
+ -v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
+ -v $(MCW_ROOT):$(MCW_ROOT) \
+ -e MCW_ROOT=$(MCW_ROOT) \
+ -e PDK=$(PDK) \
+ -e PDK_ROOT=$(PDK_ROOT) \
+ -e CARAVEL_ROOT=$(CARAVEL_ROOT) \
-e TEST_MISMATCHES=tools \
-e MISMATCHES_OK=1 \
-u $(shell id -u $(USER)):$(shell id -g $(USER)) \
diff --git a/openlane/pinmux/config.tcl b/openlane/pinmux/config.tcl
index 19c5a63..26ce028 100755
--- a/openlane/pinmux/config.tcl
+++ b/openlane/pinmux/config.tcl
@@ -85,6 +85,9 @@
set ::env(PL_TARGET_DENSITY) "0.38"
set ::env(CELL_PAD) "4"
+set ::env(FP_IO_VEXTEND) {6}
+set ::env(FP_IO_HEXTEND) {6}
+
# helps in anteena fix
set ::env(USE_ARC_ANTENNA_CHECK) "0"
@@ -105,6 +108,6 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
-set ::env(QUIT_ON_MAGIC_DRC) "0"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/pinmux/pin_order.cfg b/openlane/pinmux/pin_order.cfg
index ae96bb8..bc898c8 100644
--- a/openlane/pinmux/pin_order.cfg
+++ b/openlane/pinmux/pin_order.cfg
@@ -60,6 +60,10 @@
usb_intr
uartm_rxd
uartm_txd
+spis_sck
+spis_ssn
+spis_miso
+spis_mosi
pinmux_debug\[0\] 0100 0 2
pinmux_debug\[1\]
diff --git a/openlane/qspim_top/config.tcl b/openlane/qspim_top/config.tcl
index f17f63d..187e486 100755
--- a/openlane/qspim_top/config.tcl
+++ b/openlane/qspim_top/config.tcl
@@ -101,5 +101,5 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/sar_adc/config.tcl b/openlane/sar_adc/config.tcl
index e63b7fd..b2e9554 100644
--- a/openlane/sar_adc/config.tcl
+++ b/openlane/sar_adc/config.tcl
@@ -84,4 +84,4 @@
set ::env(SYNTH_USE_PG_PINS_DEFINES) "USE_POWER_PINS"
## LVS mismatch is to be solved manually by shorting VDD and VSS pins to the core ring
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
diff --git a/openlane/uart_i2cm_usb_spi_top/config.tcl b/openlane/uart_i2cm_usb_spi_top/config.tcl
index a97080d..802f0cf 100644
--- a/openlane/uart_i2cm_usb_spi_top/config.tcl
+++ b/openlane/uart_i2cm_usb_spi_top/config.tcl
@@ -128,5 +128,5 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
index a96d256..5b5ee9b 100644
--- a/openlane/user_project_wrapper/macro.cfg
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -1,6 +1,6 @@
u_qspi_master 2250 650 N
u_uart_i2c_usb_spi 2250 1350 N
-u_pinmux 2250 2150 N
+u_pinmux 2250 2200 N
u_riscv_top.i_core_top_0 75 1400 N
u_riscv_top.i_core_top_1 1200 1400 FN
@@ -15,4 +15,4 @@
u_intercon 1850 650 N
u_wb_host 1750 100 N
-u_pll 2200 100 N
+u_pll 2300 100 N
diff --git a/openlane/wb_host/config.tcl b/openlane/wb_host/config.tcl
index 0d8ff81..4b29f05 100755
--- a/openlane/wb_host/config.tcl
+++ b/openlane/wb_host/config.tcl
@@ -56,6 +56,9 @@
$script_dir/../../verilog/rtl/uart2wb/src/uart2wb.sv \
$script_dir/../../verilog/rtl/uart2wb/src/uart2_core.sv \
$script_dir/../../verilog/rtl/uart2wb/src/uart_msg_handler.v \
+ $script_dir/../../verilog/rtl/sspis/src/sspis_top.sv \
+ $script_dir/../../verilog/rtl/sspis/src/sspis_if.sv \
+ $script_dir/../../verilog/rtl/sspis/src/spi2wb.sv \
"
set ::env(SYNTH_READ_BLACKBOX_LIB) 1
@@ -75,7 +78,7 @@
set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 350 425"
+set ::env(DIE_AREA) "0 0 450 425"
# If you're going to use multiple power domains, then keep this disabled.
@@ -85,7 +88,7 @@
set ::env(PL_TIME_DRIVEN) 1
-set ::env(PL_TARGET_DENSITY) "0.40"
+set ::env(PL_TARGET_DENSITY) "0.45"
@@ -109,5 +112,5 @@
set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) "1"
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/wb_host/pin_order.cfg b/openlane/wb_host/pin_order.cfg
index 17b3e01..d0a5a57 100644
--- a/openlane/wb_host/pin_order.cfg
+++ b/openlane/wb_host/pin_order.cfg
@@ -188,6 +188,12 @@
uartm_rxd 300 0 2
uartm_txd
+sclk
+ssn
+sdin
+sdout
+sdout_oen
+
dbg_clk_mon
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl
index 33ac3c6..55b38f4 100755
--- a/openlane/wb_interconnect/config.tcl
+++ b/openlane/wb_interconnect/config.tcl
@@ -119,7 +119,7 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "0"
diff --git a/openlane/ycr4_iconnect/base.sdc b/openlane/ycr4_iconnect/base.sdc
index e30007e..e6bacf6 100644
--- a/openlane/ycr4_iconnect/base.sdc
+++ b/openlane/ycr4_iconnect/base.sdc
@@ -4,7 +4,7 @@
create_clock -name core_clk -period 10.0000 [get_ports {core_clk}]
set_clock_transition 0.1500 [all_clocks]
-set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -setup 0.5000 [all_clocks]
set_clock_uncertainty -hold 0.2500 [all_clocks]
set ::env(SYNTH_TIMING_DERATE) 0.05
diff --git a/openlane/ycr4_iconnect/config.tcl b/openlane/ycr4_iconnect/config.tcl
index 7775090..54face4 100644
--- a/openlane/ycr4_iconnect/config.tcl
+++ b/openlane/ycr4_iconnect/config.tcl
@@ -65,13 +65,20 @@
#set ::env(PDN_CFG) $script_dir/pdn_cfg.tcl
#set ::env(MACRO_PLACEMENT_CFG) $script_dir/macro_placement.cfg
set ::env(PL_TARGET_DENSITY) 0.20
-set ::env(CELL_PAD) "2"
+#set ::env(CELL_PAD) "2"
set ::env(GLB_RT_ADJUSTMENT) {0.2}
#set ::env(PL_ROUTABILITY_DRIVEN) "1"
set ::env(PL_TIME_DRIVEN) "1"
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) {1}
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) {1}
+set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) {1}
+set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) {1}
+set ::env(GLB_OPTIMIZE_MIRRORING) {1}
+set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) {1}
+
### PDN
#set ::env(FP_PDN_CHECK_NODES) "0"
#set ::env(FP_PDN_HORIZONTAL_HALO) "10"
@@ -96,7 +103,7 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/ycr_core_top/base.sdc b/openlane/ycr_core_top/base.sdc
index 0a05d50..f804cf0 100644
--- a/openlane/ycr_core_top/base.sdc
+++ b/openlane/ycr_core_top/base.sdc
@@ -4,8 +4,8 @@
create_clock -name core_clk -period 10.0000 [get_ports {clk}]
set_clock_transition 0.1500 [all_clocks]
-set_clock_uncertainty -setup 0.2500 [all_clocks]
-set_clock_uncertainty -hold 0.2500 [all_clocks]
+set_clock_uncertainty -setup 0.5000 [all_clocks]
+set_clock_uncertainty -hold 0.2500 [all_clocks]
set ::env(SYNTH_TIMING_DERATE) 0.05
puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %"
@@ -15,7 +15,7 @@
#IMEM Constraints
set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_cmd_o}]
set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_req_o}]
-set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_addr_o[*]}]
+set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_addr_o[*]}]
set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_bl_o[*]}]
set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2imem_cmd_o}]
@@ -32,11 +32,11 @@
set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {imem2core_resp_i[*]}]
#DMEM Constraints
-set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_cmd_o}]
+set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_cmd_o}]
set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_req_o}]
set_output_delay -max 2.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_addr_o[*]}]
set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_wdata_o[*]}]
-set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_width_o[*]}]
+set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_width_o[*]}]
set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_cmd_o}]
set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_req_o}]
diff --git a/openlane/ycr_core_top/config.tcl b/openlane/ycr_core_top/config.tcl
index a482c0e..6be1e18 100644
--- a/openlane/ycr_core_top/config.tcl
+++ b/openlane/ycr_core_top/config.tcl
@@ -88,7 +88,7 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
#Need to cross-check why global timing opimization creating setup vio with hugh hold fix
diff --git a/openlane/ycr_intf/base.sdc b/openlane/ycr_intf/base.sdc
index 2774794..db8fbe6 100644
--- a/openlane/ycr_intf/base.sdc
+++ b/openlane/ycr_intf/base.sdc
@@ -11,7 +11,7 @@
create_generated_clock -name icache_mem_clk1 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {icache mem clock1} [get_ports icache_mem_clk1]
set_clock_transition 0.1500 [all_clocks]
-set_clock_uncertainty -setup 0.2500 [all_clocks]
+set_clock_uncertainty -setup 0.5000 [all_clocks]
set_clock_uncertainty -hold 0.2500 [all_clocks]
set ::env(SYNTH_TIMING_DERATE) 0.05
diff --git a/openlane/ycr_intf/config.tcl b/openlane/ycr_intf/config.tcl
index 08ea3db..92f8034 100644
--- a/openlane/ycr_intf/config.tcl
+++ b/openlane/ycr_intf/config.tcl
@@ -81,7 +81,7 @@
set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
set ::env(QUIT_ON_MAGIC_DRC) "1"
-set ::env(QUIT_ON_LVS_ERROR) "0"
+set ::env(QUIT_ON_LVS_ERROR) "1"
set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
#Need to cross-check why global timing opimization creating setup vio with hugh hold fix
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv
index a75fa06..b81db37 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,/home/dinesha/workarea/opencore/git/riscduino_qcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,1h32m18s0ms,0h4m35s0ms,-2.0,-1,-1,-1,590.5,15,0,0,0,0,0,0,-1,0,0,-1,-1,1528755,14508,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,7.38,8.83,1.75,2.51,0.0,409,4330,409,4330,0,0,0,15,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,90,0.55,0.3,sky130_fd_sc_hd,4,0
+0,/home/dinesha/workarea/opencore/git/riscduino_qcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,1h5m19s0ms,0h4m16s0ms,-2.0,-1,-1,-1,602.16,15,0,0,0,0,0,0,-1,0,0,-1,-1,1545431,14283,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,7.52,9.31,1.62,2.13,0.0,413,4334,413,4334,0,0,0,15,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,90,0.55,0.3,sky130_fd_sc_hd,4,0
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
index ad07006..84ee8f8 100644
--- a/verilog/dv/Makefile
+++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@
.SUFFIXES:
.SILENT: clean all
-PATTERNS = wb_port risc_boot user_risc_boot user_uart user_uart1 user_qspi user_i2cm riscv_regress user_basic user_usb user_pwm user_timer user_uart_master uart_master user_mcore user_sram_exec user_cache_bypass user_gpio arduino_risc_boot arduino_hello_world arduino_ascii_table arduino_multi_serial
+PATTERNS = wb_port risc_boot user_risc_boot user_uart user_uart1 user_qspi user_i2cm riscv_regress user_basic user_usb user_pwm user_timer user_uart_master uart_master user_mcore user_sram_exec user_cache_bypass user_gpio arduino_risc_boot arduino_hello_world arduino_ascii_table arduino_multi_serial user_spi_isp
all: ${PATTERNS}
for i in ${PATTERNS}; do \
diff --git a/verilog/dv/agents/uart_agent.v b/verilog/dv/agents/uart_agent.v
index 9d647c8..c9f11b4 100644
--- a/verilog/dv/agents/uart_agent.v
+++ b/verilog/dv/agents/uart_agent.v
@@ -414,6 +414,81 @@
endtask
+
+// Read Task without Timeout
+task read_char3;
+output [7:0] rxd_data;
+reg [7:0] rxd_data;
+integer i;
+reg [7:0] data;
+reg parity;
+
+begin
+ data <= 8'h0;
+ parity <= 1;
+
+
+fork
+ begin : loop_2
+
+// start cycle
+ @(negedge rxd)
+ read <= 1;
+
+// data cycle
+ @(posedge uart_rx_clk);
+ for (i = 0; i < data_bit_number; i = i + 1)
+ begin
+ @(posedge uart_rx_clk)
+ data[i] <= rxd;
+ parity <= parity ^ rxd;
+ end
+
+// parity cycle
+ if(control_setup.parity_en)
+ begin
+ @(posedge uart_rx_clk);
+ if ((control_setup.even_odd_parity && (rxd == parity)) ||
+ (!control_setup.even_odd_parity && (rxd != parity)))
+ begin
+ $display ("%m: >>>>> Parity Error");
+ -> error_detected;
+ -> uart_parity_error;
+ end
+ end
+
+// stop cycle 1
+ @(posedge uart_rx_clk);
+ if (!rxd)
+ begin
+ $display ("%m: >>>>> Stop signal 1 Error");
+ -> error_detected;
+ -> uart_stop_error1;
+ end
+
+// stop cycle 2
+ if (control_setup.stop_bit_number)
+ begin
+ @(posedge uart_rx_clk); // stop cycle 2
+ if (!rxd)
+ begin
+ $display ("%m: >>>>> Stop signal 2 Error");
+ -> error_detected;
+ -> uart_stop_error2;
+ end
+ end
+
+ read <= 0;
+ -> uart_read_done;
+
+ rxd_data = data;
+ end
+join
+
+end
+
+endtask
+
////////////////////////////////////////////////////////////////////////////////
task write_char;
input [7:0] data;
diff --git a/verilog/dv/user_i2cm/user_i2cm_tb.v b/verilog/dv/user_i2cm/user_i2cm_tb.v
index e0f8219..e41e0d2 100644
--- a/verilog/dv/user_i2cm/user_i2cm_tb.v
+++ b/verilog/dv/user_i2cm/user_i2cm_tb.v
@@ -146,7 +146,7 @@
wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h01);
// Enable I2C Multi Functional Ports
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_MULTI_FUNC,'h4000);
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_MULTI_FUNC,'h8000);
// Remove i2m reset
wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_CFG0,'h010);
diff --git a/verilog/dv/user_sspi/user_sspi_tb.v b/verilog/dv/user_sspi/user_sspi_tb.v
index 1e81542..c8e3f5c 100644
--- a/verilog/dv/user_sspi/user_sspi_tb.v
+++ b/verilog/dv/user_sspi/user_sspi_tb.v
@@ -140,7 +140,9 @@
wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1);
// Enable SPI Multi Functional Ports
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_MULTI_FUNC,'h3C00);
+ // wire cfg_spim_enb = cfg_multi_func_sel[10];
+ // wire [3:0] cfg_spim_cs_enb = cfg_multi_func_sel[14:11];
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_MULTI_FUNC,'h7C00);
repeat (2) @(posedge clock);
#1;
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index bf8f349..23923a7 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -53,6 +53,9 @@
-v $(USER_PROJECT_VERILOG)/rtl/lib/ser_shift.sv
-v $(USER_PROJECT_VERILOG)/rtl/digital_core/src/glbl_cfg.sv
-v $(USER_PROJECT_VERILOG)/rtl/wb_host/src/wb_host.sv
+-v $(USER_PROJECT_VERILOG)/rtl/sspis/src/sspis_top.sv
+-v $(USER_PROJECT_VERILOG)/rtl/sspis/src/sspis_if.sv
+-v $(USER_PROJECT_VERILOG)/rtl/sspis/src/spi2wb.sv
-v $(USER_PROJECT_VERILOG)/rtl/lib/async_wb.sv
-v $(USER_PROJECT_VERILOG)/rtl/lib/sync_wbb.sv
-v $(USER_PROJECT_VERILOG)/rtl/lib/sync_fifo2.sv
@@ -115,4 +118,3 @@
-v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v
-v $(USER_PROJECT_VERILOG)/rtl/lib/clk_skew_adjust.gv
-v $(USER_PROJECT_VERILOG)/rtl/lib/ctech_cells.sv
-
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
index f00d432..33bc3d1 100755
--- a/verilog/rtl/pinmux/src/pinmux.sv
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -37,6 +37,14 @@
//// 0.2 - 6 April 2021, Dinesh A ////
//// 1. SSPI CS# increased from 1 to 4 ////
// 2. UART I/F increase from 1 to 2 ////
+//// 0.3 - 8 July 2022, Dinesh A ////
+//// In ardunio, SPI chip select are control through ////
+//// GPIO, So we have moved the Auto generated SPI CS ////
+//// different config bit. I2C config position moved from////
+//// bit[14] to bit [15] ////
+//// 0.4 - 20 July 2022, Dinesh A ////
+//// On Power On, If RESET* = 0, then system will enter ////
+//// in to SPIS slave mode to support boot ////
//////////////////////////////////////////////////////////////////////
module pinmux (
@@ -125,6 +133,12 @@
input logic [3:0] spim_ssn,
input logic spim_miso,
output logic spim_mosi,
+
+ // SPI SLAVE
+ output logic spis_sck,
+ output logic spis_ssn,
+ input logic spis_miso,
+ output logic spis_mosi,
// UART MASTER I/F
output logic uartm_rxd ,
@@ -548,8 +562,9 @@
assign cfg_pwm_enb = cfg_multi_func_sel[5:0];
wire [1:0] cfg_int_enb = cfg_multi_func_sel[7:6];
wire [1:0] cfg_uart_enb = cfg_multi_func_sel[9:8];
-wire [3:0] cfg_spim_enb = cfg_multi_func_sel[13:10];
-wire cfg_i2cm_enb = cfg_multi_func_sel[14];
+wire cfg_spim_enb = cfg_multi_func_sel[10];
+wire [3:0] cfg_spim_cs_enb = cfg_multi_func_sel[14:11];
+wire cfg_i2cm_enb = cfg_multi_func_sel[15];
wire [7:0] cfg_port_a_dir_sel = cfg_gpio_dir_sel[7:0];
wire [7:0] cfg_port_b_dir_sel = cfg_gpio_dir_sel[15:8];
@@ -557,6 +572,14 @@
wire [7:0] cfg_port_d_dir_sel = cfg_gpio_dir_sel[31:24];
+// This logic to create spi slave interface
+logic pin_resetn,spis_boot;
+
+// On Reset internal SPI Master is disabled, If pin_reset = 0, then we are in
+// SPIS Boot Mode
+assign spis_boot = (cfg_spim_enb ) ? 1'b0: !pin_resetn;
+assign spis_ssn = (spis_boot ) ? pin_resetn : 1'b1;
+
// datain selection
always_comb begin
port_a_in = 'h0;
@@ -571,6 +594,7 @@
//Pin-1 PC6/RESET* digital_io[0]
port_c_in[6] = digital_io_in[0];
+ pin_resetn = digital_io_in[0];
//Pin-2 PD0/RXD[0] digital_io[1]
port_d_in[0] = digital_io_in[1];
@@ -618,13 +642,15 @@
//Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
port_b_in[3] = digital_io_in[14];
- if(cfg_spim_enb[0]) spim_mosi = digital_io_in[14];
+ if(cfg_spim_enb) spim_mosi = digital_io_in[14]; // SPIM MOSI (Input) = SPIS MISO (Output)
//Pin-18 PB4/MISO digital_io[15]
port_b_in[4] = digital_io_in[15];
+ spis_mosi = (spis_boot) ? digital_io_in[15] : 1'b0; // SPIM MISO (Output) = SPIS MOSI (Input)
//Pin-19 PB5/SCK digital_io[16]
port_b_in[5]= digital_io_in[16];
+ spis_sck = (spis_boot) ? digital_io_in[16] : 1'b1; // SPIM SCK (Output) = SPIS SCK (Input)
//Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
port_c_in[0] = digital_io_in[18];
@@ -692,12 +718,12 @@
//Pin-11 PD5/SS[3]/OC0B(PWM1)/T1 digital_io[8]
if(cfg_pwm_enb[1]) digital_io_out[8] = pwm_wfm[1];
- else if(cfg_spim_enb[3]) digital_io_out[8] = spim_ssn[3];
+ else if(cfg_spim_cs_enb[3]) digital_io_out[8] = spim_ssn[3];
else if(cfg_port_d_dir_sel[5]) digital_io_out[8] = port_d_out[5];
//Pin-12 PD6/SS[2]/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
if(cfg_pwm_enb[2]) digital_io_out[9] = pwm_wfm[2];
- else if(cfg_spim_enb[2]) digital_io_out[9] = spim_ssn[2];
+ else if(cfg_spim_cs_enb[2]) digital_io_out[9] = spim_ssn[2];
else if(cfg_port_d_dir_sel[6]) digital_io_out[9] = port_d_out[6];
@@ -709,24 +735,25 @@
//Pin-15 PB1/SS[1]/OC1A(PWM3) digital_io[12]
if(cfg_pwm_enb[3]) digital_io_out[12] = pwm_wfm[3];
- else if(cfg_spim_enb[1]) digital_io_out[12] = spim_ssn[1];
+ else if(cfg_spim_cs_enb[1]) digital_io_out[12] = spim_ssn[1];
else if(cfg_port_b_dir_sel[1]) digital_io_out[12] = port_b_out[1];
//Pin-16 PB2/SS[0]/OC1B(PWM4) digital_io[13]
if(cfg_pwm_enb[4]) digital_io_out[13] = pwm_wfm[4];
- else if(cfg_spim_enb[0]) digital_io_out[13] = spim_ssn[0];
+ else if(cfg_spim_cs_enb[0]) digital_io_out[13] = spim_ssn[0];
else if(cfg_port_b_dir_sel[2]) digital_io_out[13] = port_b_out[2];
//Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
if(cfg_pwm_enb[5]) digital_io_out[14] = pwm_wfm[5];
else if(cfg_port_b_dir_sel[3]) digital_io_out[14] = port_b_out[3];
+ else if(spis_boot) digital_io_out[14] = spis_miso; // SPIM MOSI (Input) = SPIS MISO (Output)
//Pin-18 PB4/MISO digital_io[15]
- if(cfg_spim_enb[0]) digital_io_out[15] = spim_miso;
+ if(cfg_spim_enb) digital_io_out[15] = spim_miso; // SPIM MISO (Output) = SPIS MOSI (Input)
else if(cfg_port_b_dir_sel[4]) digital_io_out[15] = port_b_out[4];
//Pin-19 PB5/SCK digital_io[16]
- if(cfg_spim_enb[0]) digital_io_out[16] = spim_sck;
+ if(cfg_spim_enb) digital_io_out[16] = spim_sck; // SPIM SCK (Output) = SPIS SCK (Input)
else if(cfg_port_b_dir_sel[5]) digital_io_out[16] = port_b_out[5];
//Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
@@ -808,12 +835,12 @@
//Pin-11 PD5/SS[3]/OC0B(PWM1)/T1 digital_io[8]
if(cfg_pwm_enb[1]) digital_io_oen[8] = 1'b0;
- else if(cfg_spim_enb[3]) digital_io_oen[8] = 1'b0;
+ else if(cfg_spim_cs_enb[3]) digital_io_oen[8] = 1'b0;
else if(cfg_port_d_dir_sel[5]) digital_io_oen[8] = 1'b0;
//Pin-12 PD6/SS[2]/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
if(cfg_pwm_enb[2]) digital_io_oen[9] = 1'b0;
- else if(cfg_spim_enb[2]) digital_io_oen[9] = 1'b0;
+ else if(cfg_spim_cs_enb[2]) digital_io_oen[9] = 1'b0;
else if(cfg_port_d_dir_sel[6]) digital_io_oen[9] = 1'b0;
//Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
@@ -824,26 +851,29 @@
//Pin-15 PB1/SS[1]/OC1A(PWM3) digital_io[12]
if(cfg_pwm_enb[3]) digital_io_oen[12] = 1'b0;
- else if(cfg_spim_enb[1]) digital_io_oen[12] = 1'b0;
+ else if(cfg_spim_cs_enb[1]) digital_io_oen[12] = 1'b0;
else if(cfg_port_b_dir_sel[1]) digital_io_oen[12] = 1'b0;
//Pin-16 PB2/SS[0]/OC1B(PWM4) digital_io[13]
if(cfg_pwm_enb[4]) digital_io_oen[13] = 1'b0;
- else if(cfg_spim_enb[0]) digital_io_oen[13] = 1'b0;
+ else if(cfg_spim_cs_enb[0]) digital_io_oen[13] = 1'b0;
else if(cfg_port_b_dir_sel[2]) digital_io_oen[13] = 1'b0;
//Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
- if(cfg_spim_enb[0]) digital_io_oen[14] = 1'b1;
+ if(cfg_spim_enb) digital_io_oen[14] = 1'b1; // SPIM MOSI (Input)
else if(cfg_pwm_enb[5]) digital_io_oen[14] = 1'b0;
else if(cfg_port_b_dir_sel[3]) digital_io_oen[14] = 1'b0;
+ else if(spis_boot) digital_io_oen[14] = 1'b0; // SPIS MISO (Output)
//Pin-18 PB4/MISO digital_io[15]
- if(cfg_spim_enb[0]) digital_io_oen[15] = 1'b0;
+ if(cfg_spim_enb) digital_io_oen[15] = 1'b0; // SPIM MISO (Output)
else if(cfg_port_b_dir_sel[4]) digital_io_oen[15] = 1'b0;
+ else if(spis_boot) digital_io_oen[15] = 1'b1; // SPIS MOSI (Input)
//Pin-19 PB5/SCK digital_io[16]
- if(cfg_spim_enb[0]) digital_io_oen[16] = 1'b0;
+ if(cfg_spim_enb) digital_io_oen[16] = 1'b0; // SPIM SCK (Output)
else if(cfg_port_b_dir_sel[5]) digital_io_oen[16] = 1'b0;
+ else if(spis_boot) digital_io_oen[16] = 1'b1; // SPIS SCK (Input)
//Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
if(cfg_port_c_dir_sel[0]) digital_io_oen[18] = 1'b0;
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/pinmux_reg.sv
index 552ff6f..ed02e71 100644
--- a/verilog/rtl/pinmux/src/pinmux_reg.sv
+++ b/verilog/rtl/pinmux/src/pinmux_reg.sv
@@ -718,7 +718,7 @@
//-----------------------------------------
// Software Reg-2, Release date: <DAY><MONTH><YEAR>
// ----------------------------------------
-gen_32b_reg #(32'h1306_2022) u_reg_23 (
+gen_32b_reg #(32'h2007_2022) u_reg_23 (
//List of Inputs
.reset_n (h_reset_n ),
.clk (mclk ),
@@ -731,9 +731,9 @@
);
//-----------------------------------------
-// Software Reg-3: Poject Revison 4.6 = 0004600
+// Software Reg-3: Poject Revison 4.7 = 0004800
// ----------------------------------------
-gen_32b_reg #(32'h0004_6000) u_reg_24 (
+gen_32b_reg #(32'h0004_8000) u_reg_24 (
//List of Inputs
.reset_n (h_reset_n ),
.clk (mclk ),
diff --git a/verilog/rtl/sspis/src/spi2wb.sv b/verilog/rtl/sspis/src/spi2wb.sv
new file mode 100644
index 0000000..76f52d6
--- /dev/null
+++ b/verilog/rtl/sspis/src/spi2wb.sv
@@ -0,0 +1,76 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Reg2WB Interface ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description : This module contains Register To Wishbone ////
+//// Translation ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesh.annayya@gmail.com ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th July 2022, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module spi2wb(
+
+ //spis_if Interface
+ input logic reg_wr , // write request
+ input logic reg_rd , // read request
+ input logic [31:0] reg_addr , // address
+ input logic [3:0] reg_be , // Byte enable
+ input logic [31:0] reg_wdata , // write data
+ output logic [31:0] reg_rdata , // read data
+ output logic reg_ack , // read valid
+
+ // WB Master Port
+ output logic wbm_cyc_o , // strobe/request
+ output logic wbm_stb_o , // strobe/request
+ output logic [31:0] wbm_adr_o , // address
+ output logic wbm_we_o , // write
+ output logic [31:0] wbm_dat_o , // data output
+ output logic [3:0] wbm_sel_o , // byte enable
+ input logic [31:0] wbm_dat_i , // data input
+ input logic wbm_ack_i , // acknowlegement
+ input logic wbm_err_i // error
+
+);
+
+
+
+assign wbm_cyc_o = reg_wr | reg_rd;
+assign wbm_stb_o = reg_wr | reg_rd;
+assign wbm_adr_o = reg_addr;
+assign wbm_we_o = reg_wr;
+assign wbm_sel_o = reg_be;
+assign wbm_dat_o = reg_wdata;
+assign reg_rdata = wbm_dat_i;
+assign reg_ack = wbm_ack_i;
+
+
+endmodule
diff --git a/verilog/rtl/sspis/src/sspis_if.sv b/verilog/rtl/sspis/src/sspis_if.sv
new file mode 100644
index 0000000..10a5d1d
--- /dev/null
+++ b/verilog/rtl/sspis/src/sspis_if.sv
@@ -0,0 +1,310 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// SPI Interface ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description : This module contains SPI interface ////
+//// state machine ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesh.annayya@gmail.com ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th July 2022, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+/*********************************************************************
+ CMD Decoding [7:0]
+ [7:4] = 4'b1 - READ REGISTER
+ = 4'b2 - WRITE REGISTER
+ [3:0] = Byte Enable valid only during Write Command
+*********************************************************************/
+
+module sspis_if (
+
+ input logic sys_clk ,
+ input logic rst_n ,
+
+ input logic sclk ,
+ input logic ssn ,
+ input logic sdin ,
+ output logic sdout ,
+ output logic sdout_oen ,
+
+ //spi_sm Interface
+ output logic reg_wr , // write request
+ output logic reg_rd , // read request
+ output logic [31:0] reg_addr , // address
+ output logic [3:0] reg_be , // Byte enable
+ output logic [31:0] reg_wdata , // write data
+ input logic [31:0] reg_rdata , // read data
+ input logic reg_ack // read valid
+ );
+
+
+//--------------------------------------------------------
+// Wire and reg definitions
+// -------------------------------------------------------
+
+reg [5:0] bitcnt ;
+reg [7:0] cmd_reg ;
+reg [31:0] RegSdOut ;
+reg [2:0] spi_if_st ;
+
+parameter idle_st = 3'b000,
+ cmd_st = 3'b001,
+ adr_st = 3'b010,
+ wr_st = 3'b011,
+ wwait_st = 3'b100,
+ rwait_st = 3'b101,
+ rd_st = 3'b110;
+
+parameter READ_CMD = 4'h1,
+ WRITE_CMD = 4'h2;
+
+
+wire adr_phase = (spi_if_st == adr_st);
+wire cmd_phase = (spi_if_st == cmd_st);
+wire wr_phase = (spi_if_st == wr_st);
+wire rd_phase = (spi_if_st == rd_st);
+wire cnt_phase = (spi_if_st != wwait_st) && (spi_if_st != rwait_st);
+wire wwait_phase = (spi_if_st == wwait_st);
+wire rwait_phase = (spi_if_st == rwait_st);
+
+
+
+
+// sclk pos and ned edge generation
+logic sck_l0,sck_l1,sck_l2;
+
+assign sck_pdetect = (!sck_l2 && sck_l1) ? 1'b1: 1'b0;
+assign sck_ndetect = (sck_l2 && !sck_l1) ? 1'b1: 1'b0;
+
+always @ (posedge sys_clk or negedge rst_n) begin
+if (!rst_n) begin
+ sck_l0 <= 1'b1;
+ sck_l1 <= 1'b1;
+ sck_l2 <= 1'b1;
+ end
+ else begin
+ sck_l0 <= sclk;
+ sck_l1 <= sck_l0; // double sync
+ sck_l2 <= sck_l1;
+ end
+end
+
+// SSN double sync
+logic ssn_l0,ssn_l1, ssn_ss;
+
+assign ssn_ss = ssn_l1;
+
+always @ (posedge sys_clk or negedge rst_n) begin
+if (!rst_n) begin
+ ssn_l0 <= 1'b1;
+ ssn_l1 <= 1'b1;
+ end
+ else begin
+ ssn_l0 <= ssn;
+ ssn_l1 <= ssn_l0; // double sync
+ end
+end
+
+
+//command register accumation
+assign reg_be = cmd_reg[3:0];
+
+always @(negedge rst_n or posedge sys_clk)
+begin
+ if (!rst_n)
+ cmd_reg[7:0] <= 8'b0;
+ else if (cmd_phase & (sck_pdetect))
+ cmd_reg[7:0] <= {cmd_reg[6:0], sdin};
+end
+
+
+// address accumation at posedge sclk
+always @(negedge rst_n or posedge sys_clk)
+begin
+ if (!rst_n)
+ reg_addr[31:0] <= 32'b0;
+ else if (adr_phase & (sck_pdetect))
+ reg_addr[31:0] <= {reg_addr[30:0], sdin};
+end
+
+// write data accumation at posedge sclk
+always @(negedge rst_n or posedge sys_clk)
+begin
+ if (!rst_n)
+ reg_wdata[31:0] <= 32'b0;
+ else if (wr_phase & (sck_pdetect))
+ reg_wdata[31:0] <= {reg_wdata[30:0], sdin};
+end
+
+
+
+// drive sdout at negedge sclk
+always @(negedge rst_n or posedge sys_clk)
+begin
+ if (!rst_n) begin
+ RegSdOut[31:0] <= 32'b0;
+ sdout <= 1'b0;
+ end else begin
+ if (reg_ack)
+ RegSdOut <= reg_rdata[31:0];
+ else if (rd_phase && sck_ndetect)
+ RegSdOut <= {RegSdOut[30:0], 1'b0};
+
+ sdout <= (rd_phase && sck_ndetect) ? RegSdOut[31] : sdout;
+ end
+end
+
+
+// SPI State Machine
+always @(negedge rst_n or posedge sys_clk)
+begin
+ if (!rst_n) begin
+ reg_wr <= 1'b0;
+ reg_rd <= 1'b0;
+ sdout_oen <= 1'b1;
+ bitcnt <= 6'b0;
+ spi_if_st <= idle_st;
+ end else if(ssn_ss) begin
+ reg_wr <= 1'b0;
+ reg_rd <= 1'b0;
+ sdout_oen <= 1'b1;
+ bitcnt <= 6'b0;
+ spi_if_st <= idle_st;
+ end else begin
+ case (spi_if_st)
+ idle_st : begin // Idle State
+ reg_wr <= 1'b0;
+ reg_rd <= 1'b0;
+ sdout_oen <= 1'b1;
+ bitcnt <= 6'b0;
+ if (ssn_ss == 1'b0) begin
+ spi_if_st <= cmd_st;
+ end
+ end
+
+ cmd_st : begin // Command State
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if(bitcnt == 6'b000111) begin
+ bitcnt <= 6'b0;
+ spi_if_st <= adr_st;
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+
+ adr_st : begin // Address Phase
+ reg_wr <= 1'b0;
+ reg_rd <= 1'b0;
+ sdout_oen <= 1'b1;
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if (bitcnt == 6'b011111) begin
+ bitcnt <= 6'b0;
+ if(cmd_reg[7:4] == READ_CMD) begin
+ spi_if_st <= rwait_st;
+ reg_rd <= 1'b1;
+ end else if(cmd_reg[7:4] == WRITE_CMD) begin
+ spi_if_st <= wr_st;
+ end else begin
+ spi_if_st <= cmd_st;
+ end
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+
+ wr_st : begin // Write State
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if (bitcnt == 6'b011111) begin
+ bitcnt <= 6'b0;
+ spi_if_st <= wwait_st;
+ reg_wr <= 1;
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+ wwait_st : begin // Register Bus Busy Check State
+ if(reg_ack) reg_wr <= 0;
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if (bitcnt == 6'b000111) begin
+ bitcnt <= 6'b0;
+ spi_if_st <= cmd_st;
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+
+ rwait_st : begin // Read Wait State
+ if(reg_ack) reg_rd <= 1'b0;
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if (bitcnt == 6'b000111) begin
+ reg_rd <= 1'b0;
+ bitcnt <= 6'b0;
+ sdout_oen <= 1'b0;
+ spi_if_st <= rd_st;
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+
+ rd_st : begin // Send Data to SPI
+ if (ssn_ss == 1'b1) begin
+ spi_if_st <= idle_st;
+ end else if (sck_pdetect) begin
+ if (bitcnt == 6'b011111) begin
+ bitcnt <= 6'b0;
+ sdout_oen <= 1'b1;
+ spi_if_st <= cmd_st;
+ end else begin
+ bitcnt <= bitcnt +1;
+ end
+ end
+ end
+
+ default : spi_if_st <= idle_st;
+ endcase
+ end
+end
+
+endmodule
diff --git a/verilog/rtl/sspis/src/sspis_top.sv b/verilog/rtl/sspis/src/sspis_top.sv
new file mode 100644
index 0000000..e42d630
--- /dev/null
+++ b/verilog/rtl/sspis/src/sspis_top.sv
@@ -0,0 +1,119 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// SPI With Wishbone ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description : This module contains SPI interface + WB Master////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesh.annayya@gmail.com ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th July 2022, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module sspis_top (
+
+ input logic sys_clk ,
+ input logic rst_n ,
+
+ input logic sclk ,
+ input logic ssn ,
+ input logic sdin ,
+ output logic sdout ,
+ output logic sdout_oen ,
+
+ // WB Master Port
+ output logic wbm_cyc_o , // strobe/request
+ output logic wbm_stb_o , // strobe/request
+ output logic [31:0] wbm_adr_o , // address
+ output logic wbm_we_o , // write
+ output logic [31:0] wbm_dat_o , // data output
+ output logic [3:0] wbm_sel_o , // byte enable
+ input logic [31:0] wbm_dat_i , // data input
+ input logic wbm_ack_i , // acknowlegement
+ input logic wbm_err_i // error
+ );
+
+//-----------------------------------
+// Register I/F
+//-----------------------------------
+
+logic reg_wr ; // write request
+logic reg_rd ; // read request
+logic [31:0] reg_addr ; // address
+logic [3:0] reg_be ; // Byte enable
+logic [31:0] reg_wdata ; // write data
+logic [31:0] reg_rdata ; // read data
+logic reg_ack ; // read valid
+
+sspis_if u_if (
+
+ .sys_clk (sys_clk ),
+ .rst_n (rst_n ),
+
+ .sclk (sclk ),
+ .ssn (ssn ),
+ .sdin (sdin ),
+ .sdout (sdout ),
+ .sdout_oen (sdout_oen ),
+
+ //spi_sm Interface
+ .reg_wr (reg_wr ), // write request
+ .reg_rd (reg_rd ), // read request
+ .reg_addr (reg_addr ), // address
+ .reg_be (reg_be ), // Byte enable
+ .reg_wdata (reg_wdata ), // write data
+ .reg_rdata (reg_rdata ), // read data
+ .reg_ack (reg_ack ) // read valid
+ );
+
+spi2wb u_spi2wb (
+
+ //spis_if Interface
+ .reg_wr (reg_wr ), // write request
+ .reg_rd (reg_rd ), // read request
+ .reg_addr (reg_addr ), // address
+ .reg_be (reg_be ), // Byte enable
+ .reg_wdata (reg_wdata ), // write data
+ .reg_rdata (reg_rdata ), // read data
+ .reg_ack (reg_ack ), // read valid
+
+ // WB Master Port
+ .wbm_cyc_o (wbm_cyc_o ), // strobe/request
+ .wbm_stb_o (wbm_stb_o ), // strobe/request
+ .wbm_adr_o (wbm_adr_o ), // address
+ .wbm_we_o (wbm_we_o ), // write
+ .wbm_dat_o (wbm_dat_o ), // data output
+ .wbm_sel_o (wbm_sel_o ), // byte enable
+ .wbm_dat_i (wbm_dat_i ), // data input
+ .wbm_ack_i (wbm_ack_i ), // acknowlegement
+ .wbm_err_i (wbm_err_i ) // error
+
+);
+
+endmodule
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 469d4c6..9fd4166 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -40,7 +40,7 @@
//// nothing ////
//// ////
//// Author(s): ////
-//// - Dinesh Annayya, dinesha@opencores.org ////
+//// - Dinesh Annayya, dinesh.annayya@gmail.com ////
//// ////
//// Revision : ////
//// 0.1 - 16th Feb 2021, Dinesh A ////
@@ -208,9 +208,16 @@
//// core logic are timing optimized to 100mhz ////
//// 4.4 May 29 2022, Dinesh A ////
//// 1. Digital PLL integrated and clock debug signal add ////
-//// @digitial io [33] port
+//// @digitial io [33] port ////
//// 4.6 June 13 2022, Dinesh A ////
//// 1. icache and dcache bypass config addded ////
+//// 4.7 July 08 2022, Dinesh A ////
+//// Pinmux changes to support SPI CS port matching to ////
+//// arduino ////
+//// 4.8 July 20 2022, Dinesh A ////
+//// SPI ISP boot option added in wb_host, spi slave uses ////
+//// same spi master interface, but will be active only ////
+//// when internal SPI config disabled + RESET PIN = 0 ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
@@ -587,6 +594,12 @@
wire sspim_si ; // serial data in
wire [3:0] sspim_ssn ; // cs_n
+// SPIS I/F
+wire sspis_sck ; // clock out
+wire sspis_so ; // serial data out
+wire sspis_si ; // serial data in
+wire sspis_ssn ; // cs_n
+
wire usb_intr_o ;
wire i2cm_intr_o ;
@@ -695,6 +708,12 @@
.uartm_rxd (uartm_rxd ),
.uartm_txd (uartm_txd ),
+ .sclk (sspis_sck ),
+ .ssn (sspis_ssn ),
+ .sdin (sspis_si ),
+ .sdout (sspis_so ),
+ .sdout_oen ( ),
+
.dbg_clk_mon (dbg_clk_mon )
@@ -1279,6 +1298,12 @@
.spim_ssn (sspim_ssn ),
.spim_miso (sspim_so ),
.spim_mosi (sspim_si ),
+
+ // SPI SLAVE
+ .spis_sck (sspis_sck ),
+ .spis_ssn (sspis_ssn ),
+ .spis_miso (sspis_so ),
+ .spis_mosi (sspis_si ),
// UART MASTER I/F
.uartm_rxd (uartm_rxd ),
diff --git a/verilog/rtl/user_reg_map.v b/verilog/rtl/user_reg_map.v
index 22a25c0..42f9e73 100644
--- a/verilog/rtl/user_reg_map.v
+++ b/verilog/rtl/user_reg_map.v
@@ -76,3 +76,15 @@
`define QSPIM_IMEM_RDATA 8'h2C
`define QSPIM_SPI_STATUS 8'h30
+//----------------------------------------------------------
+// UART Register Map
+//----------------------------------------------------------
+`define UART_CTRL 8'h00 // Reg-0
+`define UART_INTR_STAT 8'h04 // Reg-1
+`define UART_BAUD_CTRL1 8'h08 // Reg-2
+`define UART_BAUD_CTRL2 8'h0C // Reg-3
+`define UART_STATUS 8'h10 // Reg-4
+`define UART_TDATA 8'h14 // Reg-5
+`define UART_RDATA 8'h18 // Reg-6
+`define UART_TFIFO_STAT 8'h1C // Reg-7
+`define UART_RFIFO_STAT 8'h20 // Reg-8
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
index 8256742..26029c2 100644
--- a/verilog/rtl/wb_host/src/wb_host.sv
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -139,6 +139,12 @@
input logic uartm_rxd ,
output logic uartm_txd ,
+ input logic sclk ,
+ input logic ssn ,
+ input logic sdin ,
+ output logic sdout ,
+ output logic sdout_oen ,
+
output logic dbg_clk_mon
);
@@ -188,6 +194,17 @@
logic wbm_uart_ack_o ; // acknowlegement
logic wbm_uart_err_o ; // error
+// SPI SLAVE Port
+logic wbm_spi_cyc_i ; // strobe/request
+logic wbm_spi_stb_i ; // strobe/request
+logic [31:0] wbm_spi_adr_i ; // address
+logic wbm_spi_we_i ; // write
+logic [31:0] wbm_spi_dat_i ; // data output
+logic [3:0] wbm_spi_sel_i ; // byte enable
+logic [31:0] wbm_spi_dat_o ; // data input
+logic wbm_spi_ack_o ; // acknowlegement
+logic wbm_spi_err_o ; // error
+
// Selected Master Port
logic wb_cyc_i ; // strobe/request
logic wb_stb_i ; // strobe/request
@@ -292,33 +309,57 @@
);
+sspis_top u_spi2wb(
+
+ .sys_clk (wbm_clk_i ),
+ .rst_n (wbm_rst_n ),
+
+ .sclk (sclk ),
+ .ssn (ssn ),
+ .sdin (sdin ),
+ .sdout (sdout ),
+ .sdout_oen (sdout_oen ),
+
+ // WB Master Port
+ .wbm_cyc_o (wbm_spi_cyc_i ), // strobe/request
+ .wbm_stb_o (wbm_spi_stb_i ), // strobe/request
+ .wbm_adr_o (wbm_spi_adr_i ), // address
+ .wbm_we_o (wbm_spi_we_i ), // write
+ .wbm_dat_o (wbm_spi_dat_i ), // data output
+ .wbm_sel_o (wbm_spi_sel_i ), // byte enable
+ .wbm_dat_i (wbm_spi_dat_o ), // data input
+ .wbm_ack_i (wbm_spi_ack_o ), // acknowlegement
+ .wbm_err_i (wbm_spi_err_o ) // error
+ );
// Arbitor to select between external wb vs uart wb
wire [1:0] grnt;
wb_arb u_arb(
.clk (wbm_clk_i),
.rstn (wbm_rst_n),
- .req ({2'b0,wbm_uart_stb_i,(wbm_stb_i & wbm_cyc_i)}),
+ .req ({1'b0,wbm_spi_stb_i,wbm_uart_stb_i,(wbm_stb_i & wbm_cyc_i)}),
.gnt (grnt)
);
// Select the master based on the grant
-assign wb_cyc_i = (grnt == 2'b00) ? wbm_cyc_i : wbm_uart_cyc_i;
-assign wb_stb_i = (grnt == 2'b00) ? (wbm_cyc_i & wbm_stb_i) : wbm_uart_stb_i;
-assign wb_adr_i = (grnt == 2'b00) ? wbm_adr_i : wbm_uart_adr_i;
-assign wb_we_i = (grnt == 2'b00) ? wbm_we_i : wbm_uart_we_i;
-assign wb_dat_i = (grnt == 2'b00) ? wbm_dat_i : wbm_uart_dat_i;
-assign wb_sel_i = (grnt == 2'b00) ? wbm_sel_i : wbm_uart_sel_i;
+assign wb_cyc_i = (grnt == 2'b00) ? wbm_cyc_i :(grnt == 2'b01) ? wbm_uart_cyc_i :wbm_spi_cyc_i;
+assign wb_stb_i = (grnt == 2'b00) ? (wbm_cyc_i & wbm_stb_i) :(grnt == 2'b01) ? wbm_uart_stb_i :wbm_spi_stb_i;
+assign wb_adr_i = (grnt == 2'b00) ? wbm_adr_i :(grnt == 2'b01) ? wbm_uart_adr_i :wbm_spi_adr_i;
+assign wb_we_i = (grnt == 2'b00) ? wbm_we_i :(grnt == 2'b01) ? wbm_uart_we_i :wbm_spi_we_i ;
+assign wb_dat_i = (grnt == 2'b00) ? wbm_dat_i :(grnt == 2'b01) ? wbm_uart_dat_i :wbm_spi_dat_i;
+assign wb_sel_i = (grnt == 2'b00) ? wbm_sel_i :(grnt == 2'b01) ? wbm_uart_sel_i :wbm_spi_sel_i;
assign wbm_dat_o = (grnt == 2'b00) ? wb_dat_o : 'h0;
assign wbm_ack_o = (grnt == 2'b00) ? wb_ack_o : 'h0;
assign wbm_err_o = (grnt == 2'b00) ? wb_err_o : 'h0;
-
assign wbm_uart_dat_o = (grnt == 2'b01) ? wb_dat_o : 'h0;
assign wbm_uart_ack_o = (grnt == 2'b01) ? wb_ack_o : 'h0;
assign wbm_uart_err_o = (grnt == 2'b01) ? wb_err_o : 'h0;
+assign wbm_spi_dat_o = (grnt == 2'b10) ? wb_dat_o : 'h0;
+assign wbm_spi_ack_o = (grnt == 2'b10) ? wb_ack_o : 'h0;
+assign wbm_spi_err_o = (grnt == 2'b10) ? wb_err_o : 'h0;