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;