spi isp option added
diff --git a/README.md b/README.md
index 67f7841..5a02926 100644
--- a/README.md
+++ b/README.md
@@ -37,7 +37,7 @@
# Overview
-Riscduino is a Dual 32 bit RISC V based SOC design pin compatible to arduino platform and this soc targetted for efabless Shuttle program. This project uses only open source tool set for simulation,synthesis and backend tools. The SOC flow follow the openlane methodology and SOC environment is compatible with efabless/carvel methodology.
+Riscduino is a Dual 32 bit RISC V based SOC design pin compatible to arduino platform and this soc targeted for efabless Shuttle program. This project uses only open source tool set for simulation,synthesis and backend tools. The SOC flow follow the openlane methodology and SOC environment is compatible with efabless/carvel methodology.
<table>
<tr>
<td align="center"><img src="./docs/source/_static/Riscduino_Integration.png" ></td>
diff --git a/gds/pinmux.gds.gz b/gds/pinmux.gds.gz
index 0dcc1ab..e5568d9 100644
--- a/gds/pinmux.gds.gz
+++ b/gds/pinmux.gds.gz
Binary files differ
diff --git a/gds/user_project_wrapper.gds.gz b/gds/user_project_wrapper.gds.gz
index 5cc9441..e22f90b 100644
--- a/gds/user_project_wrapper.gds.gz
+++ b/gds/user_project_wrapper.gds.gz
Binary files differ
diff --git a/gds/wb_host.gds.gz b/gds/wb_host.gds.gz
index 4f92c4e..1d4bd55 100644
--- a/gds/wb_host.gds.gz
+++ b/gds/wb_host.gds.gz
Binary files differ
diff --git a/lef/pinmux.lef.gz b/lef/pinmux.lef.gz
index 69ed348..631d1ef 100644
--- a/lef/pinmux.lef.gz
+++ b/lef/pinmux.lef.gz
Binary files differ
diff --git a/lef/user_project_wrapper.lef.gz b/lef/user_project_wrapper.lef.gz
index 764d9e6..cb2dd5f 100644
--- a/lef/user_project_wrapper.lef.gz
+++ b/lef/user_project_wrapper.lef.gz
Binary files differ
diff --git a/lef/wb_host.lef.gz b/lef/wb_host.lef.gz
index c7d2d85..100cc37 100644
--- a/lef/wb_host.lef.gz
+++ b/lef/wb_host.lef.gz
Binary files differ
diff --git a/openlane/pinmux/pin_order.cfg b/openlane/pinmux/pin_order.cfg
index b3273bf..baa31fd 100644
--- a/openlane/pinmux/pin_order.cfg
+++ b/openlane/pinmux/pin_order.cfg
@@ -58,6 +58,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/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg
index 2352db6..d82daa9 100644
--- a/openlane/user_project_wrapper/macro.cfg
+++ b/openlane/user_project_wrapper/macro.cfg
@@ -13,4 +13,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 4116b09..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"
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/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv
index c469d16..21ae94f 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_dcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,0h51m28s0ms,0h3m44s0ms,-2.0,-1,-1,-1,557.84,13,0,0,0,0,0,0,-1,0,0,-1,-1,1416054,10511,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,5.38,6.15,1.46,2.65,0.0,367,3710,367,3710,0,0,0,13,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_dcore/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow completed,0h53m49s0ms,0h3m55s0ms,-2.0,-1,-1,-1,555.07,13,0,0,0,0,0,0,-1,0,0,-1,-1,1423269,10484,0.0,-1,-1,0.0,0.0,0.0,-1,-1,0.0,0.0,-1,0.0,5.38,6.4,1.54,2.35,0.0,371,3714,371,3714,0,0,0,13,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/spef/pinmux.spef.gz b/spef/pinmux.spef.gz
index 3bbd95a..4b80252 100644
--- a/spef/pinmux.spef.gz
+++ b/spef/pinmux.spef.gz
Binary files differ
diff --git a/spef/user_project_wrapper.spef.gz b/spef/user_project_wrapper.spef.gz
index 2073de0..4a83b5a 100644
--- a/spef/user_project_wrapper.spef.gz
+++ b/spef/user_project_wrapper.spef.gz
Binary files differ
diff --git a/spef/wb_host.spef.gz b/spef/wb_host.spef.gz
index e852567..8f54b28 100644
--- a/spef/wb_host.spef.gz
+++ b/spef/wb_host.spef.gz
Binary files differ
diff --git a/spi/lvs/pinmux.spice.gz b/spi/lvs/pinmux.spice.gz
index 7b00a0f..5841e52 100644
--- a/spi/lvs/pinmux.spice.gz
+++ b/spi/lvs/pinmux.spice.gz
Binary files differ
diff --git a/spi/lvs/user_project_wrapper.spice.gz b/spi/lvs/user_project_wrapper.spice.gz
index 0ad418b..8a1a1d2 100644
--- a/spi/lvs/user_project_wrapper.spice.gz
+++ b/spi/lvs/user_project_wrapper.spice.gz
Binary files differ
diff --git a/spi/lvs/wb_host.spice.gz b/spi/lvs/wb_host.spice.gz
index a909136..e21f872 100644
--- a/spi/lvs/wb_host.spice.gz
+++ b/spi/lvs/wb_host.spice.gz
Binary files differ
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/bfm/bfm_spim.v b/verilog/dv/bfm/bfm_spim.v
new file mode 100644
index 0000000..f04f8b9
--- /dev/null
+++ b/verilog/dv/bfm/bfm_spim.v
@@ -0,0 +1,260 @@
+
+
+// SPI Master BFM
+// Command-1 : 0x10,
+// SI : <CMD[7:0]> <ADDR[31:0]><Dummy[7:0]>
+// SO : ------------------------------------<RDATA[31:0]>
+// Command-2 : 0x2F ,
+// SI : <CMD[7:0]> <ADDR[31:0]><WDATA[31:0]><Dummy[7:0]>
+// SO : ---------------------------------------------
+
+`timescale 1 ns / 1 ps
+`define TB_SPI_CLK_PW 100
+
+module bfm_spim (
+
+ // SPI
+ spi_clk,
+ spi_sel_n,
+ spi_din,
+ spi_dout
+
+ );
+
+output spi_clk;
+output spi_sel_n;
+output spi_din;
+input spi_dout;
+
+reg spi_clk;
+reg spi_sel_n;
+reg spi_din;
+reg error_ind;
+
+event error_detected;
+integer err_cnt;
+
+
+initial begin
+
+spi_clk = 0;
+spi_sel_n = 1;
+spi_din = 0;
+error_ind = 0;
+err_cnt = 0;
+
+end
+
+task init;
+begin
+ spi_clk=1;
+ spi_sel_n=1;
+ spi_din=1;
+end
+endtask
+
+
+always @error_detected begin
+ error_ind = 1;
+ err_cnt = err_cnt + 1;
+end
+
+
+
+task set_spi_sel_n;
+begin
+ #10;
+ spi_sel_n=0;
+ #100;
+end
+endtask
+
+task reset_spi_sel_n;
+begin
+ #10;
+ spi_sel_n=1;
+ #100;
+end
+endtask
+
+
+
+
+//-----------------------------
+// Reg Write 32 Bit
+//-----------------------------
+
+task reg_wr_dword;
+input [31:0] addr;
+input [31:0] dword;
+reg [31:0] addr;
+reg [31:0] dword;
+begin
+
+ set_spi_sel_n;
+ send_cmd(8'h2F);
+ send_dword(addr);
+ send_dword(dword);
+ send_byte(8'h0); // Dummy byte
+
+ $display("STATUS: At time %t: SPI WRITE : ADDR = %h DATA = %h ", $time, addr, dword);
+
+ reset_spi_sel_n;
+
+end
+endtask
+
+//-----------------------------
+// Reg Read 32 Bit
+//-----------------------------
+task reg_rd_dword;
+input [31:0] addr;
+output [31:0] dword;
+reg [31:0] addr;
+reg [31:0] dword;
+integer i;
+begin
+
+ set_spi_sel_n;
+ send_cmd(8'h10);
+ send_dword(addr);
+ send_byte(8'h0); // Dummy byte
+ receive_dword(dword);
+
+ $display("STATUS: At time %t: SPI READ :addr = %h data = %h ", $time, addr, dword);
+
+ reset_spi_sel_n;
+end
+endtask
+
+//-----------------------------
+// Reg Read 32 Bit compare
+//-----------------------------
+task reg_rd_dword_cmp;
+input [31:0] addr;
+input [31:0] exp_dword;
+reg [31:0] addr;
+reg [31:0] dword;
+integer i;
+begin
+
+ set_spi_sel_n;
+ send_cmd(8'h10);
+ send_dword(addr);
+ send_byte(8'h0); // Dummy byte
+ receive_dword(dword);
+
+ if (exp_dword !== dword)
+ begin
+ $display("ERROR: At time %t: SPI READ FAILED ADDR: %x EXP = %x RXD : %x ",$time,addr,exp_dword,dword);
+ -> error_detected;
+ end else begin
+ $display("STATUS: At time %t: SPI READ ADDR: %x RXD : %x ",$time,addr,dword);
+
+ end
+
+ reset_spi_sel_n;
+end
+endtask
+
+
+//-----------------------------
+// Command Byte
+//-----------------------------
+task send_cmd;
+input [7:0] data;
+begin
+begin
+ send_byte(data[7:0]);
+end
+
+end
+endtask
+// Write 4 Byte
+task send_dword;
+input dword;
+reg [31:0] dword;
+begin
+ send_word(dword[31:16]);
+ send_word(dword[15:0]);
+end
+endtask
+
+// Write 2 Byte
+task send_word;
+input word;
+reg [15:0] word;
+begin
+ send_byte(word[15:8]);
+ send_byte(word[7:0]);
+end
+endtask // spi_send_word
+
+
+
+// Write 1 Byte
+task send_byte;
+input data;
+reg [7:0] data;
+integer i;
+begin
+
+ for (i=7; i>=0; i=i-1)
+ begin
+ spi_clk=0;
+ spi_din = data[i];
+ #`TB_SPI_CLK_PW;
+ spi_clk=1;
+ // if (i != 0)
+ #`TB_SPI_CLK_PW;
+ end
+
+end
+endtask
+//----------------------------
+// READ TASK
+//----------------------------
+
+// READ 4 BYTE
+task receive_dword;
+output dword;
+reg [31:0] dword;
+begin
+ receive_word(dword[31:16]);
+ receive_word(dword[15:0]);
+end
+endtask
+
+// READ 2 BYTE
+task receive_word;
+output word;
+reg [15:0] word;
+begin
+ receive_byte(word[15:8]);
+ receive_byte(word[7:0]);
+end
+endtask
+
+
+
+// READ 1 BYTE
+task receive_byte;
+output data;
+reg [7:0] data;
+integer i;
+begin
+ for (i=7; i>=0; i=i-1)
+ begin
+ spi_clk=0;
+ #`TB_SPI_CLK_PW;
+ spi_clk=1;
+ data[i] = spi_dout;
+// if (i !=0)
+ #`TB_SPI_CLK_PW;
+ end
+
+end
+endtask
+
+endmodule
+
diff --git a/verilog/dv/user_basic/user_basic_tb.v b/verilog/dv/user_basic/user_basic_tb.v
index 1d2a372..bcd24cd 100644
--- a/verilog/dv/user_basic/user_basic_tb.v
+++ b/verilog/dv/user_basic/user_basic_tb.v
@@ -282,8 +282,8 @@
wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1);
wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_1,read_data,32'h8273_8343);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_2,read_data,32'h0807_2022);
- wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_3,read_data,32'h0004_7000);
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_2,read_data,32'h2007_2022);
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_3,read_data,32'h0004_8000);
end
diff --git a/verilog/dv/user_spi_isp/Makefile b/verilog/dv/user_spi_isp/Makefile
new file mode 100644
index 0000000..f655404
--- /dev/null
+++ b/verilog/dv/user_spi_isp/Makefile
@@ -0,0 +1,88 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# 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
+
+
+# ---- Include Partitioned Makefiles ----
+
+CONFIG = caravel_user_project
+
+#######################################################################
+## Caravel Verilog for Integration Tests
+#######################################################################
+
+DESIGNS?=../../..
+
+export USER_PROJECT_VERILOG ?= $(DESIGNS)/verilog
+## YIFIVE FIRMWARE
+YIFIVE_FIRMWARE_PATH = $(USER_PROJECT_VERILOG)/dv/firmware
+GCC_PREFIX?=riscv32-unknown-elf
+
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+### To Enable IVERILOG FST DUMP
+export IVERILOG_DUMPER = fst
+
+
+.SUFFIXES:
+
+PATTERN = user_spi_isp
+
+all: ${PATTERN:=.vcd}
+
+
+vvp: ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+ ifeq ($(DUMP),OFF)
+ iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib \
+ $< -o $@
+ else
+ iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib \
+ $< -o $@
+ endif
+else
+ ifeq ($(DUMP),OFF)
+ iverilog -g2012 -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+ $< -o $@
+ else
+ iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+ -f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+ $< -o $@
+ endif
+endif
+
+%.vcd: %.vvp
+ vvp $<
+
+
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean all
diff --git a/verilog/dv/user_spi_isp/run_iverilog b/verilog/dv/user_spi_isp/run_iverilog
new file mode 100755
index 0000000..e461fd1
--- /dev/null
+++ b/verilog/dv/user_spi_isp/run_iverilog
@@ -0,0 +1,42 @@
+# //////////////////////////////////////////////////////////////////////////////
+# // 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: Dinesh Annayya <dinesha@opencores.org>
+# // //////////////////////////////////////////////////////////////////////////
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common user_uart.c -o user_uart.o
+
+riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -D__ASSEMBLY__=1 -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common/ ../../rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o crt_tcm.o
+
+riscv64-unknown-elf-gcc -o user_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32
+
+riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex
+
+riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump
+
+rm crt_tcm.o user_uart.o
+
+#iverilog with waveform dump
+iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I ../../../verilog/rtl/usb1_host/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+
+#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+# GLS
+#iverilog -g2005-sv -D GL -D FUNCTIONAL -I $PDK_PATH -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/gl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp
+#
+
+vvp user_uart_tb.vvp | tee test.log
+
+\rm -rf user_uart_tb.vvp
diff --git a/verilog/dv/user_spi_isp/user_spi_isp_tb.v b/verilog/dv/user_spi_isp/user_spi_isp_tb.v
new file mode 100644
index 0000000..a0e0fb5
--- /dev/null
+++ b/verilog/dv/user_spi_isp/user_spi_isp_tb.v
@@ -0,0 +1,254 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Modified by Dinesh Annayya <dinesha@opencores.org>
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Standalone User validation Test bench ////
+//// ////
+//// This file is part of the Riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// This is a standalone test bench to validate the ////
+//// Digital core using spi isp i/f. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th Feb 2022, Dinesh A ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
+//// ////
+//// This source file may be used and distributed without ////
+//// restriction provided that this copyright statement is not ////
+//// removed from the file and that any derivative work contains ////
+//// the original copyright notice and the associated disclaimer. ////
+//// ////
+//// This source file is free software; you can redistribute it ////
+//// and/or modify it under the terms of the GNU Lesser General ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any ////
+//// later version. ////
+//// ////
+//// This source is distributed in the hope that it will be ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR ////
+//// PURPOSE. See the GNU Lesser General Public License for more ////
+//// details. ////
+//// ////
+//// You should have received a copy of the GNU Lesser General ////
+//// Public License along with this source; if not, download it ////
+//// from http://www.opencores.org/lgpl.shtml ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+`default_nettype wire
+
+`timescale 1 ns / 1 ps
+
+`include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+`include "bfm_spim.v"
+
+module user_spi_isp_tb;
+
+reg clock ;
+reg wb_rst_i ;
+reg power1, power2;
+reg power3, power4;
+
+reg wbd_ext_cyc_i; // strobe/request
+reg wbd_ext_stb_i; // strobe/request
+reg [31:0] wbd_ext_adr_i; // address
+reg wbd_ext_we_i; // write
+reg [31:0] wbd_ext_dat_i; // data output
+reg [3:0] wbd_ext_sel_i; // byte enable
+
+wire [31:0] wbd_ext_dat_o; // data input
+wire wbd_ext_ack_o; // acknowlegement
+wire wbd_ext_err_o; // error
+
+// User I/O
+wire [37:0] io_oeb ;
+wire [37:0] io_out ;
+wire [37:0] io_in ;
+
+wire [37:0] mprj_io ;
+wire [7:0] mprj_io_0 ;
+reg test_fail ;
+reg [31:0] read_data ;
+
+reg [127:0] la_data_in;
+reg flag;
+
+// SCLK
+wire sclk;
+wire ssn;
+wire sdi;
+wire sdo;
+wire sd_oen;
+
+integer i,j;
+
+ // External clock is used by default. Make this artificially fast for the
+ // simulation. Normally this would be a slow clock and the digital PLL
+ // would be the fast clock.
+
+ always #12.5 clock <= (clock === 1'b0);
+
+ initial begin
+ clock = 0;
+ la_data_in = 1;
+ end
+
+ `ifdef WFDUMP
+ initial begin
+ $dumpfile("simx.vcd");
+ $dumpvars(0, user_spi_isp_tb);
+ end
+ `endif
+
+ initial begin
+ clock = 0;
+ wbd_ext_cyc_i ='h0; // strobe/request
+ wbd_ext_stb_i ='h0; // strobe/request
+ wbd_ext_adr_i ='h0; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='h0; // data output
+ wbd_ext_sel_i ='h0; // byte enable
+ end
+initial
+begin
+ wb_rst_i <= 1'b1;
+
+ #100;
+ wb_rst_i <= 1'b0; // Release reset
+
+ $display("Monitor: Standalone User SPI ISP Test Started");
+
+
+ // Remove Wb Reset
+ u_spim.reg_wr_dword(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1);
+
+ repeat (2) @(posedge clock);
+ #1;
+
+ $display("Monitor: Writing expected value");
+
+ test_fail = 0;
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_1,32'h11223344);
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_2,32'h22334455);
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_3,32'h33445566);
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_4,32'h44556677);
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_5,32'h55667788);
+ u_spim.reg_wr_dword(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_6,32'h66778899);
+
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_1,32'h11223344);
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_2,32'h22334455);
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_3,32'h33445566);
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_4,32'h44556677);
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_5,32'h55667788);
+ u_spim.reg_rd_dword_cmp(`ADDR_SPACE_PINMUX+`PINMUX_SOFT_REG_6,32'h66778899);
+
+
+
+ $display("###################################################");
+ if(u_spim.err_cnt == 0) begin
+ `ifdef GL
+ $display("Monitor: Standalone User SPI ISP (GL) Passed");
+ `else
+ $display("Monitor: Standalone User SPI ISP (RTL) Passed");
+ `endif
+ end else begin
+ `ifdef GL
+ $display("Monitor: Standalone User SPI ISP (GL) Failed");
+ `else
+ $display("Monitor: Standalone User SPI ISP (RTL) Failed");
+ `endif
+ end
+ $display("###################################################");
+ #100
+ $finish;
+end
+
+
+wire USER_VDD1V8 = 1'b1;
+wire VSS = 1'b0;
+
+
+user_project_wrapper u_top(
+`ifdef USE_POWER_PINS
+ .vccd1(USER_VDD1V8), // User area 1 1.8V supply
+ .vssd1(VSS), // User area 1 digital ground
+`endif
+ .wb_clk_i (clock), // System clock
+ .user_clock2 (1'b1), // Real-time clock
+ .wb_rst_i (wb_rst_i), // Regular Reset signal
+
+ .wbs_cyc_i (wbd_ext_cyc_i), // strobe/request
+ .wbs_stb_i (wbd_ext_stb_i), // strobe/request
+ .wbs_adr_i (wbd_ext_adr_i), // address
+ .wbs_we_i (wbd_ext_we_i), // write
+ .wbs_dat_i (wbd_ext_dat_i), // data output
+ .wbs_sel_i (wbd_ext_sel_i), // byte enable
+
+ .wbs_dat_o (wbd_ext_dat_o), // data input
+ .wbs_ack_o (wbd_ext_ack_o), // acknowlegement
+
+
+ // Logic Analyzer Signals
+ .la_data_in (la_data_in) ,
+ .la_data_out (),
+ .la_oenb ('0),
+
+
+ // IOs
+ .io_in (io_in) ,
+ .io_out (io_out) ,
+ .io_oeb (io_oeb) ,
+
+ .user_irq ()
+
+);
+
+`ifndef GL // Drive Power for Hold Fix Buf
+ // All standard cell need power hook-up for functionality work
+ initial begin
+ end
+`endif
+
+assign io_in[0] = 1'b0;
+assign io_in[16] = sclk;
+assign io_in[15] = sdi;
+assign sdo = io_out[14];
+
+bfm_spim u_spim (
+ // SPI
+ .spi_clk (sclk ),
+ .spi_sel_n (ssn ),
+ .spi_din (sdi ),
+ .spi_dout (sdo )
+
+ );
+
+
+endmodule
+`default_nettype wire
diff --git a/verilog/gl/pinmux.v.gz b/verilog/gl/pinmux.v.gz
index bc2dd2b..623d3ea 100644
--- a/verilog/gl/pinmux.v.gz
+++ b/verilog/gl/pinmux.v.gz
Binary files differ
diff --git a/verilog/gl/user_project_wrapper.v.gz b/verilog/gl/user_project_wrapper.v.gz
index c0c7183..7e522a9 100644
--- a/verilog/gl/user_project_wrapper.v.gz
+++ b/verilog/gl/user_project_wrapper.v.gz
Binary files differ
diff --git a/verilog/gl/wb_host.v.gz b/verilog/gl/wb_host.v.gz
index c8cabda..8e642ae 100644
--- a/verilog/gl/wb_host.v.gz
+++ b/verilog/gl/wb_host.v.gz
Binary files differ
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index 4efed12..5e4aeb0 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
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
index 2f1ba44..e36556c 100755
--- a/verilog/rtl/pinmux/src/pinmux.sv
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -42,6 +42,9 @@
//// 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 (
@@ -130,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 ,
@@ -563,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;
@@ -577,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];
@@ -624,13 +642,15 @@
//Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
port_b_in[3] = digital_io_in[14];
- if(cfg_spim_enb) 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];
@@ -726,13 +746,14 @@
//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) 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) 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]
@@ -839,17 +860,20 @@
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) 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) 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) 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 8ad8bd2..744c07b 100644
--- a/verilog/rtl/pinmux/src/pinmux_reg.sv
+++ b/verilog/rtl/pinmux/src/pinmux_reg.sv
@@ -716,7 +716,7 @@
//-----------------------------------------
// Software Reg-2, Release date: <DAY><MONTH><YEAR>
// ----------------------------------------
-gen_32b_reg #(32'h0807_2022) u_reg_23 (
+gen_32b_reg #(32'h2007_2022) u_reg_23 (
//List of Inputs
.reset_n (h_reset_n ),
.clk (mclk ),
@@ -729,9 +729,9 @@
);
//-----------------------------------------
-// Software Reg-3: Poject Revison 4.7 = 0004700
+// Software Reg-3: Poject Revison 4.7 = 0004800
// ----------------------------------------
-gen_32b_reg #(32'h0004_7000) 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 16297b2..34c8794 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 ////
@@ -212,6 +212,10 @@
//// 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 ////
@@ -588,6 +592,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 ;
@@ -696,6 +706,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 )
@@ -1280,6 +1296,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;