ADD: SPI core
diff --git a/verilog/dv/wb_spi/Makefile b/verilog/dv/wb_spi/Makefile
new file mode 100644
index 0000000..b07bb75
--- /dev/null
+++ b/verilog/dv/wb_spi/Makefile
@@ -0,0 +1,31 @@
+# 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
+
+
+
+PWDD := $(shell pwd)
+BLOCKS := $(shell basename $(PWDD))
+
+# ---- Include Partitioned Makefiles ----
+CARAVEL_PATH = $(CARAVEL_ROOT)
+CARAVEL_VERILOG_PATH = $(CARAVEL_ROOT)/verilog
+CONFIG = caravel_user_project
+
+
+include $(MCW_ROOT)/verilog/dv/make/env.makefile
+include $(MCW_ROOT)/verilog/dv/make/var.makefile
+include $(MCW_ROOT)/verilog/dv/make/cpu.makefile
+include $(MCW_ROOT)/verilog/dv/make/sim.makefile
diff --git a/verilog/dv/wb_spi/seed.h b/verilog/dv/wb_spi/seed.h
new file mode 100644
index 0000000..7c5f14f
--- /dev/null
+++ b/verilog/dv/wb_spi/seed.h
@@ -0,0 +1 @@
+#define seed 57893
\ No newline at end of file
diff --git a/verilog/dv/wb_spi/wb_spi.c b/verilog/dv/wb_spi/wb_spi.c
new file mode 100644
index 0000000..c4b94c3
--- /dev/null
+++ b/verilog/dv/wb_spi/wb_spi.c
@@ -0,0 +1,154 @@
+/*
+ * 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
+ */
+
+// This include is relative to $CARAVEL_PATH (see Makefile)
+#include <defs.h>
+#include "seed.h"
+#include <stub.c>
+
+/*
+ Wishbone Test:
+ - Configures MPRJ lower 8-IO pins as outputs
+ - Checks counter value through the wishbone port
+*/
+
+#define reg_SRAM ((volatile uint32_t *)0x30000000)
+
+#define reg_SPI_shiftReg (*(volatile uint32_t *)0x30003000)
+#define reg_SPI_buffReg (*(volatile uint32_t *)0x30003004)
+#define reg_SPI_statusReg (*(volatile uint32_t *)0x30003008)
+#define reg_SPI_confReg (*(volatile uint32_t *)0x3000300C)
+
+
+
+void main()
+{
+
+ /*
+ IO Control Registers
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit |
+ Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 |
+
+
+ Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL
+ | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN |
+ | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 |
+ */
+
+ /* Set up the housekeeping SPI to be connected internally so */
+ /* that external pin changes don't affect it. */
+
+ reg_spi_enable = 1;
+ reg_wb_enable = 1;
+ // reg_spimaster_config = 0xa002; // Enable, prescaler = 2,
+ // connect to housekeeping SPI
+
+ // Connect the housekeeping SPI to the SPI master
+ // so that the CSB line is not left floating. This allows
+ // all of the GPIO pins to be used for user functions.
+
+ reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT;
+ reg_mprj_io_16 = GPIO_MODE_USER_STD_OUTPUT;
+ reg_mprj_io_15 = GPIO_MODE_USER_STD_INPUT_NOPULL; //UART_RX
+ reg_mprj_io_14 = GPIO_MODE_USER_STD_INPUT_NOPULL; //MISO
+ reg_mprj_io_13 = GPIO_MODE_USER_STD_OUTPUT; //SCK
+ reg_mprj_io_12 = GPIO_MODE_USER_STD_OUTPUT; //MOSI
+
+
+ // //Verify SRAM
+ // for (int i = 0; i < 32; i++)
+ // {
+ // *(reg_SRAM+(i*4)) = i*1024;
+ // }
+
+ // for (int i = 0; i < 32; i++)
+ // {
+ // if(*(reg_SRAM+(i*4)) != i * 1024 )
+ // reg_mprj_datal = 0xAB800000;
+ // }
+
+
+
+ /* Apply configuration */
+ reg_mprj_xfer = 1;
+ while (reg_mprj_xfer == 1)
+ ;
+
+ reg_la2_oenb = reg_la2_iena = 0x00000000; // [95:64]
+
+ // Flag start of the test
+ reg_mprj_datal = 0xAB600000;
+
+ /* UART Setup: */
+ /* 8-N-1 115200B for 50Mhz System Clock */
+ int i = 0;
+ bool error = false;
+ unsigned baud, data, data_prev;
+ unsigned lfsr = seed;
+ unsigned bit;
+ unsigned period = 0;
+
+ unsigned rx_status = 0;
+
+ do
+ {
+ rx_status = 0;
+ /* taps: 16 14 13 11; characteristic polynomial: x^16 + x^14 + x^13 + x^11 + 1 */
+ bit = ((lfsr >> 0) ^ (lfsr >> 2) ^ (lfsr >> 3) ^ (lfsr >> 5)) & 1;
+ lfsr = (lfsr >> 1) | (bit << 15);
+
+ data = lfsr % 256;
+ reg_SPI_buffReg = data;
+
+ int i = 0;
+ while(rx_status == 0 )
+ rx_status = reg_SPI_statusReg;
+ if(period % 2 == 1)
+ if(reg_SPI_shiftReg != data_prev)
+ {
+ error = true;
+ break;
+ }
+ data_prev = data;
+ ++period;
+ } while (period < 10 && lfsr != seed);
+ if(error)
+ reg_mprj_datal = 0xAB800000;
+ else
+ reg_mprj_datal = 0xAB700000;
+
+
+
+}
+
diff --git a/verilog/dv/wb_spi/wb_spi_tb.v b/verilog/dv/wb_spi/wb_spi_tb.v
new file mode 100644
index 0000000..95cb373
--- /dev/null
+++ b/verilog/dv/wb_spi/wb_spi_tb.v
@@ -0,0 +1,236 @@
+// 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
+
+`default_nettype none
+
+`timescale 1 ns / 1 ps
+
+`define PER 25 // period
+
+
+module wb_spi_tb ();
+ reg clock ;
+ reg RSTB ;
+ reg CSB ;
+ reg power1, power2;
+ reg power3, power4;
+
+ wire gpio ;
+ wire [37:0] mprj_io ;
+ wire [ 7:0] mprj_io_0;
+ wire [15:0] checkbits;
+
+
+ integer fd ;
+ integer tmp;
+
+ reg [8*10:0] uart_data_in = "de 1b2";
+
+ reg [23:0] dec_baud;
+ reg [ 7:0] dec_data;
+
+
+ reg [7:0] tx_data;
+
+ wire sck_pin;
+ wire mosi_pin;
+ reg miso_pin;
+
+ task spi_transaction;
+ begin : task_block
+ integer i;
+ miso_pin = 1'b0;
+ for ( i=7 ;i > -1; i=i-1 )
+ begin : for_block
+ @(posedge sck_pin);
+ miso_pin = tx_data[i];
+ rx_data = {rx_data[6:0],mosi_pin};
+ end
+ @(negedge sck_pin);
+ miso_pin = 1'b0;
+ end
+ endtask
+
+ wire rx ;
+ reg [23:0] baud_clk = 8; // clk_freq is divided by for
+ reg [ 7:0] rx_data = 8'd0 ;
+
+ // task spi_receive;
+ // begin : rx_block
+ // repeat(8)
+ // begin
+ // @(posedge sck_pin);
+ // rx_data = {rx_data[6:0],mosi_pin};
+ // end
+ // end
+ // endtask
+
+
+
+
+ assign checkbits = mprj_io[31:16];
+
+ assign mprj_io[3] = 1'b1;
+ assign mosi_pin = mprj_io[12];
+ assign sck_pin = mprj_io[13];
+ assign mprj_io[14] = miso_pin;
+
+ // 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.
+
+ //50MHz
+ always #(`PER/2) clock <= (clock === 1'b0);
+
+ initial
+ begin
+ clock = 0;
+ end
+
+ initial
+ begin
+ $dumpfile("wb_spi.vcd");
+ $dumpvars(0, wb_spi_tb);
+
+ // Repeat cycles of 1000 clock edges as needed to complete testbench
+ repeat (70)
+ begin
+ repeat (10000) @(posedge clock);
+ // $display("+1000 cycles");
+ end
+ $display("%c[1;31m",27);
+`ifdef GL
+
+ $display ("Monitor: Timeout, Test Mega-Project WB Port (GL) Failed");
+`else
+ $display ("Monitor: Timeout, Test Mega-Project WB Port (RTL) Failed");
+`endif
+
+ $display("%c[0m",27);
+ $finish;
+ end
+
+ assign rx = uut.mprj.io_out[16];
+
+ initial
+ begin
+ tx_data = 8'd0;
+ wait(checkbits[15:4] == 12'hAB6);
+ $display("Monitor: MPRJ-Logic WB Started");
+ while(checkbits[15:4] != 12'hAB7)
+ begin
+ spi_transaction();
+ tx_data = rx_data;
+ end
+
+ end
+
+
+ initial
+ begin
+ wait(checkbits[15:4] == 12'hAB7 || checkbits[15:4] == 12'hAB8 );
+
+ if(checkbits[15:4] == 12'hAB8)
+ begin
+ $display("SPI failed!");
+ $finish;
+ end
+ else
+ begin
+ `ifdef GL
+ $display("Monitor: Mega-Project WB (GL) Passed");
+ `else
+ $display("Monitor: Mega-Project WB (RTL) Passed");
+ `endif
+ $finish;
+ end
+ end
+
+ initial
+ begin
+ RSTB <= 1'b0;
+ CSB <= 1'b1; // Force CSB high
+ #2000;
+ RSTB <= 1'b1; // Release reset
+ #100000;
+ CSB = 1'b0; // CSB can be released
+ end
+
+ initial
+ begin // Power-up sequence
+ power1 <= 1'b0;
+ power2 <= 1'b0;
+ #200;
+ power1 <= 1'b1;
+ #200;
+ power2 <= 1'b1;
+ end
+
+
+
+ wire flash_csb;
+ wire flash_clk;
+ wire flash_io0;
+ wire flash_io1;
+
+ wire VDD3V3 = power1;
+ wire VDD1V8 = power2;
+ wire USER_VDD3V3 = power3;
+ wire USER_VDD1V8 = power4;
+ wire VSS = 1'b0 ;
+
+ caravel uut (
+ .vddio (VDD3V3 ),
+ .vddio_2 (VDD3V3 ),
+ .vssio (VSS ),
+ .vssio_2 (VSS ),
+ .vdda (VDD3V3 ),
+ .vssa (VSS ),
+ .vccd (VDD1V8 ),
+ .vssd (VSS ),
+ .vdda1 (VDD3V3 ),
+ .vdda1_2 (VDD3V3 ),
+ .vdda2 (VDD3V3 ),
+ .vssa1 (VSS ),
+ .vssa1_2 (VSS ),
+ .vssa2 (VSS ),
+ .vccd1 (VDD1V8 ),
+ .vccd2 (VDD1V8 ),
+ .vssd1 (VSS ),
+ .vssd2 (VSS ),
+ .clock (clock ),
+ .gpio (gpio ),
+ .mprj_io (mprj_io ),
+ .flash_csb(flash_csb),
+ .flash_clk(flash_clk),
+ .flash_io0(flash_io0),
+ .flash_io1(flash_io1),
+ .resetb (RSTB )
+ );
+
+ spiflash #(.FILENAME("wb_spi.hex")) spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2( ), // not used
+ .io3( ) // not used
+ );
+
+
+
+endmodule
+
+`default_nettype wire
diff --git a/verilog/dv/wb_spi/wb_uart.elf b/verilog/dv/wb_spi/wb_uart.elf
new file mode 100755
index 0000000..eaaca29
--- /dev/null
+++ b/verilog/dv/wb_spi/wb_uart.elf
Binary files differ
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index 032b622..f473d82 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -2,6 +2,7 @@
-v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v
-v $(USER_PROJECT_VERILOG)/rtl/user_proj_example.v
-v $(USER_PROJECT_VERILOG)/rtl/sram/sram_wb_wrapper.sv
+-v $(USER_PROJECT_VERILOG)/rtl/spi/tiny_spi.v
-v $(USER_PROJECT_VERILOG)/rtl/wb_interconnect/wb_interconnect.sv
-v $(USER_PROJECT_VERILOG)/rtl/wbuart32/rxuart.v
-v $(USER_PROJECT_VERILOG)/rtl/wbuart32/txuart.v
diff --git a/verilog/rtl/spi/tiny_spi.v b/verilog/rtl/spi/tiny_spi.v
new file mode 100644
index 0000000..450276d
--- /dev/null
+++ b/verilog/rtl/spi/tiny_spi.v
@@ -0,0 +1,261 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// tiny_spi.v ////
+//// ////
+//// This file is part of the TINY SPI IP core project ////
+//// http://www.opencores.org/projects/tiny_spi/ ////
+//// ////
+//// Author(s): ////
+//// - Thomas Chou <thomas@wytron.com.tw> ////
+//// ////
+//// All additional information is avaliable in the README ////
+//// file. ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Copyright (C) 2010 Authors ////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module tiny_spi (
+`ifdef USE_POWER_PINS
+ input wire vccd1, // User area 1 1.8V supply
+ input wire vssd1, // User area 1 digital ground
+ `endif
+ // system
+ input wire rst_i,
+ input wire clk_i,
+ // memory mapped
+ input wire stb_i,
+ input wire we_i ,
+ output wire [31:0] dat_o,
+ input wire [31:0] dat_i,
+ output wire int_o,
+ input wire [ 2:0] adr_i,
+ input wire cyc_i, // comment out for avalon
+ output wire ack_o, // comment out for avalon
+ // spi
+ output wire MOSI ,
+ output wire SCLK ,
+ input wire MISO
+);
+
+ parameter BAUD_WIDTH = 8;
+ parameter BAUD_DIV = 8;
+ parameter SPI_MODE = 0;
+ parameter BC_WIDTH = 3;
+ //parameter DIV_WIDTH = BAUD_DIV ? $clog2(BAUD_DIV / 2 - 1) : BAUD_WIDTH;
+ parameter DIV_WIDTH = $clog2(BAUD_DIV / 2 - 1);
+
+ reg [ 7:0] sr8, bb8;
+ wire [ 7:0] sr8_sf;
+ reg [ BC_WIDTH-1:0] bc, bc_next;
+ reg [DIV_WIDTH-1:0] ccr ;
+ reg [DIV_WIDTH-1:0] cc, cc_next;
+ wire misod ;
+ wire cstb, wstb, bstb, istb;
+ reg sck ;
+ reg sf, ld;
+ reg bba ; // buffer flag
+ reg txren, txeen;
+ wire txr, txe;
+ wire cpol, cpha;
+ reg cpolr, cphar;
+ wire wr ;
+ // wire cyc_i; // comment out for wishbone
+ // wire ack_o; // comment out for wishbone
+ // assign cyc_i = 1'b1; // comment out for wishbone
+
+ assign ack_o = stb_i & cyc_i; // zero wait
+ assign wr = stb_i & cyc_i & we_i & ack_o;
+ assign wstb = wr & (adr_i == 1);
+ assign istb = wr & (adr_i == 2);
+ assign cstb = wr & (adr_i == 3);
+ assign bstb = wr & (adr_i == 4);
+ assign sr8_sf = { sr8[6:0],misod };
+ assign dat_o =
+ (sr8 & {8{(adr_i == 0)}})
+ | (bb8 & {8{(adr_i == 1)}})
+ | ({ txr, txe } & {8{(adr_i == 2)}})
+ ;
+
+ parameter
+ IDLE = 0,
+ PHASE1 = 1,
+ PHASE2 = 2
+ ;
+
+ reg [1:0] spi_seq, spi_seq_next;
+ always @(posedge clk_i )
+ if (rst_i)
+ spi_seq <= IDLE;
+ else
+ spi_seq <= spi_seq_next;
+
+ wire high_val, low_val;
+ assign high_val = 1'b1;
+ assign low_val = 1'b0;
+ always @(posedge clk_i)
+ begin
+ if(rst_i)
+ begin
+ cc <= {2{1'b0}};
+ bc <= {3{1'b0}};
+ end
+ else
+ begin
+ cc <= cc_next;
+ bc <= bc_next;
+ end
+
+ end
+
+ always @(/*AS*/bba or bc or cc or ccr or cpha or cpol or spi_seq)
+ begin
+ sck = cpol;
+ cc_next = BAUD_DIV ? (BAUD_DIV / 2 - 1) : ccr;
+ bc_next = bc;
+ ld = 1'b0;
+ sf = 1'b0;
+
+ case (spi_seq)
+ IDLE :
+ begin
+ if (bba)
+ begin
+ bc_next = 7;
+ ld = 1'b1;
+ spi_seq_next = PHASE2;
+ end
+ else
+ spi_seq_next = IDLE;
+ end
+ PHASE2 :
+ begin
+ sck = (cpol ^ cpha);
+ if (cc == 0)
+ spi_seq_next = PHASE1;
+ else
+ begin
+ cc_next = cc - 1;
+ spi_seq_next = PHASE2;
+ end
+ end
+ PHASE1 :
+ begin
+ sck = ~(cpol ^ cpha);
+ if (cc == 0)
+ begin
+ bc_next = bc -1;
+ sf = 1'b1;
+ if (bc == 0)
+ begin
+ if (bba)
+ begin
+ bc_next = 7;
+ ld = 1'b1;
+ spi_seq_next = PHASE2;
+ end
+ else
+ spi_seq_next = IDLE;
+ end
+ else
+ spi_seq_next = PHASE2;
+ end
+ else
+ begin
+ cc_next = cc - 1;
+ spi_seq_next = PHASE1;
+ end
+ end
+ endcase
+ end // always @ (...
+
+ always @(posedge clk_i)
+ begin
+ if(rst_i)
+ begin
+ { cpolr, cphar } <= 2'b0;
+ { txren, txeen } <= 2'b0;
+ ccr <= 8'd0;
+ sr8 <= 8'd0;
+ bb8 <= 8'd0;
+ end
+
+ else
+ begin
+ if (cstb) // control reg
+ { cpolr, cphar } <= dat_i;
+ else
+ { cpolr, cphar } <= { cpolr, cphar };
+
+ if (istb) // irq enable reg
+ { txren, txeen } <= dat_i;
+ else
+ { txren, txeen } <= { txren, txeen };
+
+ if (bstb) // baud reg
+ ccr <= dat_i;
+ else
+ ccr <= ccr;
+
+ if (ld) // shift reg
+ sr8 <= bb8;
+ else if (sf)
+ sr8 <= sr8_sf;
+ else
+ sr8 <= sr8;
+
+ if (wstb) // buffer reg
+ bb8 <= dat_i;
+ else if (ld)
+ bb8 <= (spi_seq == IDLE) ? sr8 : sr8_sf;
+ else
+ bb8 <= bb8;
+ end
+
+ end // always @ (posedge clk_i)
+
+ always @(posedge clk_i)
+ begin
+ if (rst_i)
+ bba <= 1'b0;
+ else if (wstb)
+ bba <= 1'b1;
+ else if (ld)
+ bba <= 1'b0;
+ else
+ bba <= bba;
+ end
+
+ assign { cpol, cpha } = ((SPI_MODE >= 0) & (SPI_MODE < 4)) ?
+ SPI_MODE : { cpolr, cphar };
+ assign txe = (spi_seq == IDLE);
+ assign txr = ~bba;
+ assign int_o = (txr & txren) | (txe & txeen);
+ assign SCLK = sck;
+ assign MOSI = sr8[7];
+ assign misod = MISO;
+
+endmodule
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
index f473a98..952b2cd 100644
--- a/verilog/rtl/user_proj_example.v
+++ b/verilog/rtl/user_proj_example.v
@@ -109,13 +109,27 @@
wire s1_wb_stb_i;
wire [ 8:0] s1_wb_adr_o;
wire s1_wb_we_i ;
- wire [ UART_DATA_WD-1:0] s1_wb_dat_i;
+ wire [ WB_WIDTH-1:0] s1_wb_dat_i;
wire [UART_DATA_WD/8-1:0] s1_wb_sel_i;
- wire [ UART_DATA_WD-1:0] s1_wb_dat_o;
+ wire [ WB_WIDTH-1:0] s1_wb_dat_o;
wire s1_wb_ack_o;
+ //---------------------------------------------------------------------
+ // SPI
+ //---------------------------------------------------------------------
+ wire s3_wb_cyc_i;
+ wire s3_wb_stb_i;
+ wire [ 8:0] s3_wb_adr_o;
+ wire s3_wb_we_i ;
+ wire [WB_WIDTH-1:0] s3_wb_dat_i;
+ //wire [UART_DATA_WD/8-1:0] s3_wb_sel_i;
+ wire [WB_WIDTH-1:0] s3_wb_dat_o;
+ wire s3_wb_ack_o;
+
+
+
wire [8:0] concat_s0_addr;
wire [8:0] concat_s1_addr;
@@ -156,7 +170,7 @@
.s1_wb_sel_o(s1_wb_sel_i),
.s1_wb_we_o (s1_wb_we_i ),
.s1_wb_cyc_o(s1_wb_cyc_i),
- .s1_wb_stb_o(s1_wb_stb_i)
+ .s1_wb_stb_o(s1_wb_stb_i),
// Slave 2 Interface
// .s2_wb_dat_i(),
@@ -169,14 +183,14 @@
// .s2_wb_stb_o(),
// Slave 3 Interface
- // .s3_wb_dat_i(),
- // .s3_wb_ack_i(),
- // .s3_wb_dat_o(),
- // .s3_wb_adr_o(),
- // .s3_wb_sel_o(),
- // .s3_wb_we_o (),
- // .s3_wb_cyc_o(),
- // .s3_wb_stb_o()
+ .s3_wb_dat_i(s3_wb_dat_o),
+ .s3_wb_ack_i(s3_wb_ack_o),
+ .s3_wb_dat_o(s3_wb_dat_i),
+ .s3_wb_adr_o(s3_wb_adr_o),
+ .s3_wb_sel_o(),
+ .s3_wb_we_o (s3_wb_we_i ),
+ .s3_wb_cyc_o(s3_wb_cyc_i),
+ .s3_wb_stb_o(s3_wb_stb_i)
);
@@ -218,7 +232,7 @@
- wbuart wbuart_dut (
+ wbuart wbuart_inst (
`ifdef USE_POWER_PINS
.vccd1 (vccd1 ), // User area 1 1.8V supply
.vssd1 (vssd1 ), // User area 1 digital ground
@@ -244,5 +258,34 @@
.o_uart_txfifo_int( )
);
+
+ tiny_spi #(
+ .BAUD_WIDTH(0),
+ .BAUD_DIV (8),
+ .SPI_MODE (0),
+ .BC_WIDTH (3),
+ .DIV_WIDTH (2),
+ .IDLE (0)
+ ) tiny_spi_inst (
+ `ifdef USE_POWER_PINS
+ .vccd1(vccd1 ), // User area 1 1.8V supply
+ .vssd1(vssd1 ), // User area 1 digital ground
+ `endif
+ .rst_i(wb_rst_i ),
+ .clk_i(wb_clk_i ),
+ .stb_i(s3_wb_stb_i ),
+ .we_i (s3_wb_we_i ),
+ .dat_o(s3_wb_dat_o ),
+ .dat_i(s3_wb_dat_i ),
+ .int_o( ),
+ .adr_i(s3_wb_adr_o[2:0]),
+ .cyc_i(s3_wb_cyc_i ),
+ .ack_o(s3_wb_ack_o ),
+ .MOSI (io_out[12] ),
+ .SCLK (io_out[13] ),
+ .MISO (io_in[14] )
+ );
+
+
endmodule
`default_nettype wire
diff --git a/verilog/rtl/wb_interconnect/wb_interconnect.sv b/verilog/rtl/wb_interconnect/wb_interconnect.sv
index 9de2f75..ae1cbff 100644
--- a/verilog/rtl/wb_interconnect/wb_interconnect.sv
+++ b/verilog/rtl/wb_interconnect/wb_interconnect.sv
@@ -56,7 +56,7 @@
output wire [ 3:0] s1_wb_sel_o,
output wire s1_wb_we_o ,
output wire s1_wb_cyc_o,
- output wire s1_wb_stb_o
+ output wire s1_wb_stb_o,
// Slave 2 Interface
// input logic [31:0] s2_wb_dat_i,
// input logic s2_wb_ack_i,
@@ -67,14 +67,16 @@
// output wire s2_wb_cyc_o,
// output wire s2_wb_stb_o,
// Slave 3 Interface
- // input logic [31:0] s3_wb_dat_i,
- // input logic s3_wb_ack_i,
- // output wire [31:0] s3_wb_dat_o,
- // output wire [8:0] s3_wb_adr_o,
- // output wire [3:0] s3_wb_sel_o,
- // output wire s3_wb_we_o,
- // output wire s3_wb_cyc_o,
- // output wire s3_wb_stb_o
+ input logic [31:0] s3_wb_dat_i,
+ input logic s3_wb_ack_i,
+ output wire [31:0] s3_wb_dat_o,
+ output wire [8:0] s3_wb_adr_o,
+ output wire [3:0] s3_wb_sel_o,
+ output wire s3_wb_we_o,
+ output wire s3_wb_cyc_o,
+ output wire s3_wb_stb_o
+
+
);
@@ -90,12 +92,12 @@
wire [31:0] s_bus_rd_wb_dat = (m0_wb_adr_i[13:12] == 2'b00) ? s0_wb_dat_i :
- (m0_wb_adr_i[13:12] == 2'b01) ? s1_wb_dat_i : 32'd0 ;// :
- //(m0_wb_adr_i[13:12] == 2'b10) ? s2_wb_dat_i :
+ (m0_wb_adr_i[13:12] == 2'b01) ? s1_wb_dat_i :
+ (m0_wb_adr_i[13:12] == 2'b11) ? s3_wb_dat_i : 32'd0;
//s3_wb_dat_i;
wire s_bus_rd_wb_ack = (m0_wb_adr_i[13:12] == 2'b00) ? s0_wb_ack_i :
- (m0_wb_adr_i[13:12] == 2'b01) ? s1_wb_ack_i : 1'b0 ; // :
- //(m0_wb_adr_i[13:12] == 2'b10) ? s2_wb_ack_i :
+ (m0_wb_adr_i[13:12] == 2'b01) ? s1_wb_ack_i :
+ (m0_wb_adr_i[13:12] == 2'b11) ? s3_wb_ack_i : 1'b0 ; // :
//s3_wb_ack_i;
//wire [31:0] s_bus_rd_wb_dat = s0_wb_dat_i;
@@ -141,12 +143,12 @@
// assign s2_wb_cyc_o = (m0_wb_tid_reg == 2'b10) ? m0_wb_cyc_reg : 2'b00;
// assign s2_wb_stb_o = (m0_wb_tid_reg == 2'b10) ? m0_wb_stb_reg : 2'b00;
- // assign s3_wb_dat_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_dat_i_reg : 2'b00;
- // assign s3_wb_adr_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_adr_reg : 2'b00;
- // assign s3_wb_sel_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_sel_reg : 2'b00;
- // assign s3_wb_we_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_we_reg : 2'b00;
- // assign s3_wb_cyc_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_cyc_reg : 2'b00;
- // assign s3_wb_stb_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_stb_reg : 2'b00;
+ assign s3_wb_dat_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_dat_i_reg : 2'b00;
+ assign s3_wb_adr_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_adr_reg : 2'b00;
+ assign s3_wb_sel_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_sel_reg : 2'b00;
+ assign s3_wb_we_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_we_reg : 2'b00;
+ assign s3_wb_cyc_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_cyc_reg : 2'b00;
+ assign s3_wb_stb_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_stb_reg : 2'b00;
assign m0_wb_dat_o = s_bus_rd_wb_dat;
assign m0_wb_ack_o = s_bus_rd_wb_ack;