ADD: replace the wbuart32 with simple UART
diff --git a/.gitignore b/.gitignore
index 9ccca4b..9619c0f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,6 @@
*.lst
*.vcd
*.gtkw
+*.vvp
+*.vcd.hier
+
diff --git a/openlane/user_proj_example/.config.tcl.swp b/openlane/user_proj_example/.config.tcl.swp
new file mode 100644
index 0000000..e06b751
--- /dev/null
+++ b/openlane/user_proj_example/.config.tcl.swp
Binary files differ
diff --git a/verilog/dv/wb_uart/wb_uart.c b/verilog/dv/wb_uart/wb_uart.c
index 754cdab..29db97b 100644
--- a/verilog/dv/wb_uart/wb_uart.c
+++ b/verilog/dv/wb_uart/wb_uart.c
@@ -28,12 +28,17 @@
#define reg_SRAM ((volatile uint32_t *)0x30000000)
-#define reg_UART_SETUP (*(volatile uint32_t *)0x30001000)
-#define reg_UART_FIFO (*(volatile uint32_t *)0x30001004)
-#define reg_UART_RX_DATA (*(volatile uint32_t *)0x30001008)
-#define reg_UART_TX_DATA (*(volatile uint32_t *)0x3000100C)
+// Register space for wbuart32
+// #define reg_UART_SETUP (*(volatile uint32_t *)0x30001000)
+// #define reg_UART_FIFO (*(volatile uint32_t *)0x30001004)
+// #define reg_UART_RX_DATA (*(volatile uint32_t *)0x30001008)
+// #define reg_UART_TX_DATA (*(volatile uint32_t *)0x3000100C)
+// Register space for simpleUART
+#define reg_UART_CLKDIV (*(volatile uint32_t *)0x30001000)
+#define reg_UART_DATA (*(volatile uint32_t *)0x30001004)
+#define reg_UART_CONFIG (*(volatile uint32_t *)0x30001008)
void main()
{
@@ -118,23 +123,35 @@
unsigned rx_status = 0;
- reg_UART_SETUP = 434; //115200 for 50MHz clock
+ //reg_UART_SETUP = 434; //115200 for 50MHz clock
+ reg_UART_CLKDIV = 434-2;
+ reg_UART_CONFIG = 1; //dummy write to CFG // todo: get rid of that changing the RTL
+
+ bool error = false;
do
{
- rx_status = 0;
+ rx_status = 0xFFFFFFFF;
/* 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);
++period;
data = lfsr % 256;
- reg_UART_TX_DATA = data;
- while(rx_status == 0)
- rx_status = reg_UART_FIFO & 0x00000001;
+ reg_UART_DATA = data;
+
+ while(rx_status == 0xFFFFFFFF)
+ rx_status = reg_UART_DATA;
+ if(rx_status != data)
+ {
+ error = true;
+ break;
+ }
+ } while (period < 10 && lfsr != seed && rx_status == data);
- } while (period < 2 && lfsr != seed && reg_UART_RX_DATA == data);
-
- reg_mprj_datal = 0xAB700000;
+ if(error)
+ reg_mprj_datal = 0xAB800000;
+ else
+ reg_mprj_datal = 0xAB700000;
diff --git a/verilog/dv/wb_uart/wb_uart.elf b/verilog/dv/wb_uart/wb_uart.elf
new file mode 100755
index 0000000..34b70df
--- /dev/null
+++ b/verilog/dv/wb_uart/wb_uart.elf
Binary files differ
diff --git a/verilog/dv/wb_uart/wb_uart_tb.v b/verilog/dv/wb_uart/wb_uart_tb.v
index 01ae97b..acdd318 100644
--- a/verilog/dv/wb_uart/wb_uart_tb.v
+++ b/verilog/dv/wb_uart/wb_uart_tb.v
@@ -112,7 +112,7 @@
// Repeat cycles of 1000 clock edges as needed to complete testbench
repeat (70)
begin
- repeat (10000) @(posedge clock);
+ repeat (3000) @(posedge clock);
// $display("+1000 cycles");
end
$display("%c[1;31m",27);
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index f473d82..48c2430 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -1,6 +1,7 @@
# Caravel user project includes
-v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v
-v $(USER_PROJECT_VERILOG)/rtl/user_proj_example.v
+-v $(USER_PROJECT_VERILOG)/rtl/simpleUART/simple_uart.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
diff --git a/verilog/rtl/simpleUART/simple_uart.v b/verilog/rtl/simpleUART/simple_uart.v
new file mode 100644
index 0000000..51b5fd0
--- /dev/null
+++ b/verilog/rtl/simpleUART/simple_uart.v
@@ -0,0 +1,228 @@
+`default_nettype none
+/*
+ * SPDX-FileCopyrightText: 2015 Clifford Wolf
+ * PicoSoC - A simple example SoC using PicoRV32
+ *
+ * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ *
+ * SPDX-License-Identifier: ISC
+ */
+
+module simpleuartA_wb(
+ `ifdef USE_POWER_PINS
+ input wire vccd1 , // User area 1 1.8V supply
+ input wire vssd1 , // User area 1 digital ground
+ `endif
+ input wb_clk_i,
+ input wb_rst_i,
+
+ input [1:0] wb_adr_i,
+ input [31:0] wb_dat_i,
+ input [3:0] wb_sel_i,
+ input wb_we_i,
+ input wb_cyc_i,
+ input wb_stb_i,
+
+ output wb_ack_o,
+ output [31:0] wb_dat_o,
+
+ output uart_enabled,
+ output ser_tx,
+ input ser_rx
+
+);
+
+ localparam CLK_DIV = 0;
+ localparam DATA = 1;
+ localparam CONFIG = 2;
+ wire [31:0] simpleuartA_reg_div_do;
+ wire [31:0] simpleuartA_reg_dat_do;
+ wire [31:0] simpleuartA_reg_cfg_do;
+ wire reg_dat_wait;
+
+ wire resetn = ~wb_rst_i;
+ wire valid = wb_stb_i && wb_cyc_i;
+ wire simpleuartA_reg_div_sel = valid && (wb_adr_i == CLK_DIV);
+ wire simpleuartA_reg_dat_sel = valid && (wb_adr_i == DATA);
+ wire simpleuartA_reg_cfg_sel = valid && (wb_adr_i == CONFIG);
+
+ wire [3:0] reg_div_we = simpleuartA_reg_div_sel ? (wb_sel_i & {4{wb_we_i}}): 4'b 0000;
+ wire reg_dat_we = simpleuartA_reg_dat_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0; // simpleuartA_reg_dat_sel ? mem_wstrb[0] : 1'b 0
+ wire reg_cfg_we = simpleuartA_reg_cfg_sel ? (wb_sel_i[0] & wb_we_i): 1'b 0;
+
+ wire [31:0] mem_wdata = wb_dat_i;
+ //wire reg_dat_re = simpleuartA_reg_dat_sel && !wb_sel_i && ~wb_we_i; // read_enable //original
+ wire reg_dat_re = simpleuartA_reg_dat_sel && ~wb_we_i; // read_enable //original
+
+ assign wb_dat_o = simpleuartA_reg_div_sel ? simpleuartA_reg_div_do:
+ simpleuartA_reg_cfg_sel ? simpleuartA_reg_cfg_do:
+ simpleuartA_reg_dat_do;
+ assign wb_ack_o = (simpleuartA_reg_div_sel || simpleuartA_reg_dat_sel
+ || simpleuartA_reg_cfg_sel) && (!reg_dat_wait);
+
+ simpleuartA simpleuartA (
+ .clk (wb_clk_i),
+ .resetn (resetn),
+
+ .ser_tx (ser_tx),
+ .ser_rx (ser_rx),
+ .enabled (uart_enabled),
+
+ .reg_div_we (reg_div_we),
+ .reg_div_di (mem_wdata),
+ .reg_div_do (simpleuartA_reg_div_do),
+
+ .reg_cfg_we (reg_cfg_we),
+ .reg_cfg_di (mem_wdata),
+ .reg_cfg_do (simpleuartA_reg_cfg_do),
+
+ .reg_dat_we (reg_dat_we),
+ .reg_dat_re (reg_dat_re),
+ .reg_dat_di (mem_wdata),
+ .reg_dat_do (simpleuartA_reg_dat_do),
+ .reg_dat_wait(reg_dat_wait)
+ );
+
+endmodule
+
+module simpleuartA (
+ input clk,
+ input resetn,
+
+ output enabled,
+ output ser_tx,
+ input ser_rx,
+
+ input [3:0] reg_div_we,
+ input [31:0] reg_div_di,
+ output [31:0] reg_div_do,
+
+ input reg_cfg_we,
+ input [31:0] reg_cfg_di,
+ output [31:0] reg_cfg_do,
+
+ input reg_dat_we,
+ input reg_dat_re,
+ input [31:0] reg_dat_di,
+ output [31:0] reg_dat_do,
+ output reg_dat_wait
+);
+ reg [31:0] cfg_divider;
+ reg enabled;
+
+ reg [3:0] recv_state;
+ reg [31:0] recv_divcnt;
+ reg [7:0] recv_pattern;
+ reg [7:0] recv_buf_data;
+ reg recv_buf_valid;
+
+ reg [9:0] send_pattern;
+ reg [3:0] send_bitcnt;
+ reg [31:0] send_divcnt;
+ reg send_dummy;
+
+ assign reg_div_do = cfg_divider;
+ assign reg_cfg_do = {31'd0, enabled};
+
+ assign reg_dat_wait = reg_dat_we && (send_bitcnt || send_dummy);
+ assign reg_dat_do = recv_buf_valid ? recv_buf_data : ~0;
+
+ always @(posedge clk) begin
+ if (!resetn) begin
+ cfg_divider <= 1;
+ enabled <= 1'b0;
+ end else begin
+ if (reg_div_we[0]) cfg_divider[ 7: 0] <= reg_div_di[ 7: 0];
+ if (reg_div_we[1]) cfg_divider[15: 8] <= reg_div_di[15: 8];
+ if (reg_div_we[2]) cfg_divider[23:16] <= reg_div_di[23:16];
+ if (reg_div_we[3]) cfg_divider[31:24] <= reg_div_di[31:24];
+ //if (reg_cfg_we) enabled <= reg_div_di[0]; // original one
+ if (reg_cfg_we) enabled <= reg_cfg_di[0];
+ end
+ end
+
+ always @(posedge clk) begin
+ if (!resetn) begin
+ recv_state <= 0;
+ recv_divcnt <= 0;
+ recv_pattern <= 0;
+ recv_buf_data <= 0;
+ recv_buf_valid <= 0;
+ end else begin
+ recv_divcnt <= recv_divcnt + 1;
+ if (reg_dat_re)
+ recv_buf_valid <= 0;
+ case (recv_state)
+ 0: begin
+ if (!ser_rx && enabled)
+ recv_state <= 1;
+ recv_divcnt <= 0;
+ end
+ 1: begin
+ if (2*recv_divcnt > cfg_divider) begin
+ recv_state <= 2;
+ recv_divcnt <= 0;
+ end
+ end
+ 10: begin
+ if (recv_divcnt > cfg_divider) begin
+ recv_buf_data <= recv_pattern;
+ recv_buf_valid <= 1;
+ recv_state <= 0;
+ end
+ end
+ default: begin
+ if (recv_divcnt > cfg_divider) begin
+ recv_pattern <= {ser_rx, recv_pattern[7:1]};
+ recv_state <= recv_state + 1;
+ recv_divcnt <= 0;
+ end
+ end
+ endcase
+ end
+ end
+
+ assign ser_tx = send_pattern[0];
+
+ always @(posedge clk) begin
+ if (reg_div_we && enabled)
+ send_dummy <= 1;
+ send_divcnt <= send_divcnt + 1;
+ if (!resetn) begin
+ send_pattern <= ~0;
+ send_bitcnt <= 0;
+ send_divcnt <= 0;
+ send_dummy <= 1;
+ end else begin
+ if (send_dummy && !send_bitcnt) begin
+ send_pattern <= ~0;
+ send_bitcnt <= 15;
+ send_divcnt <= 0;
+ send_dummy <= 0;
+ end else
+ if (reg_dat_we && !send_bitcnt) begin
+ send_pattern <= {1'b1, reg_dat_di[7:0], 1'b0};
+ send_bitcnt <= 10;
+ send_divcnt <= 0;
+ end else
+ if (send_divcnt > cfg_divider && send_bitcnt) begin
+ send_pattern <= {1'b1, send_pattern[9:1]};
+ send_bitcnt <= send_bitcnt - 1;
+ send_divcnt <= 0;
+ end
+ end
+ end
+endmodule
+`default_nettype wire
\ No newline at end of file
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
index 952b2cd..7b73223 100644
--- a/verilog/rtl/user_proj_example.v
+++ b/verilog/rtl/user_proj_example.v
@@ -109,13 +109,11 @@
wire s1_wb_stb_i;
wire [ 8:0] s1_wb_adr_o;
wire s1_wb_we_i ;
- wire [ WB_WIDTH-1:0] s1_wb_dat_i;
- wire [UART_DATA_WD/8-1:0] s1_wb_sel_i;
- wire [ WB_WIDTH-1:0] s1_wb_dat_o;
+ wire [WB_WIDTH-1:0] s1_wb_dat_i;
+ wire [WB_WIDTH/8-1:0] s1_wb_sel_i;
+ wire [WB_WIDTH-1:0] s1_wb_dat_o;
wire s1_wb_ack_o;
-
-
//---------------------------------------------------------------------
// SPI
//---------------------------------------------------------------------
@@ -129,11 +127,6 @@
wire s3_wb_ack_o;
-
- wire [8:0] concat_s0_addr;
- wire [8:0] concat_s1_addr;
-
-
wb_interconnect interconnect (
`ifdef USE_POWER_PINS
.vccd1 (vccd1 ), // User area 1 1.8V supply
@@ -230,35 +223,31 @@
assign io_oeb = {(`MPRJ_IO_PADS){1'b0}};
+
-
- wbuart wbuart_inst (
+ simpleuartA_wb
+ simpleuartA_wb_dut (
`ifdef USE_POWER_PINS
- .vccd1 (vccd1 ), // User area 1 1.8V supply
- .vssd1 (vssd1 ), // User area 1 digital ground
+ .vccd1 (vccd1 ), // User area 1 1.8V supply
+ .vssd1 (vssd1 ), // User area 1 digital ground
`endif
- .i_clk (wb_clk_i ),
- .i_reset (wb_rst_i ),
- .i_wb_cyc (s1_wb_cyc_i ),
- .i_wb_stb (s1_wb_stb_i ),
- .i_wb_we (s1_wb_we_i ),
- .i_wb_addr (s1_wb_adr_o[1:0]),
- .i_wb_data (s1_wb_dat_i ),
- .i_wb_sel (s1_wb_sel_i ),
- .o_wb_stall ( ),
- .o_wb_ack (s1_wb_ack_o ),
- .o_wb_data (s1_wb_dat_o ),
- .i_uart_rx (io_in[15] ),
- .o_uart_tx (io_out[16] ),
- .i_cts_n (1'b0 ),
- .o_rts_n ( ),
- .o_uart_rx_int ( ),
- .o_uart_tx_int ( ),
- .o_uart_rxfifo_int( ),
- .o_uart_txfifo_int( )
+ .wb_clk_i (wb_clk_i ),
+ .wb_rst_i (wb_rst_i ),
+ .wb_adr_i (s1_wb_adr_o[1:0]),
+ .wb_dat_i (s1_wb_dat_i ),
+ .wb_sel_i (s1_wb_sel_i ),
+ .wb_we_i (s1_wb_we_i ),
+ .wb_cyc_i (s1_wb_cyc_i ),
+ .wb_stb_i (s1_wb_stb_i ),
+ .wb_ack_o (s1_wb_ack_o ),
+ .wb_dat_o (s1_wb_dat_o ),
+ .uart_enabled ( ),
+ .ser_tx (io_out[16] ),
+ .ser_rx (io_in[15])
);
+
tiny_spi #(
.BAUD_WIDTH(0),
.BAUD_DIV (8),
diff --git a/verilog/rtl/wb_interconnect/wb_interconnect.sv b/verilog/rtl/wb_interconnect/wb_interconnect.sv
index ae1cbff..ad0ab15 100644
--- a/verilog/rtl/wb_interconnect/wb_interconnect.sv
+++ b/verilog/rtl/wb_interconnect/wb_interconnect.sv
@@ -52,7 +52,7 @@
input wire [31:0] s1_wb_dat_i,
input wire s1_wb_ack_i,
output wire [31:0] s1_wb_dat_o,
- output wire [ 8:0] s1_wb_adr_o,
+ output wire [8:0] s1_wb_adr_o,
output wire [ 3:0] s1_wb_sel_o,
output wire s1_wb_we_o ,
output wire s1_wb_cyc_o,
@@ -122,19 +122,19 @@
//assign s0_wb_cyc_o = m0_wb_cyc_reg;
//assign s0_wb_stb_o = m0_wb_stb_reg;
- assign s0_wb_dat_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_dat_i_reg : 2'b00;
- assign s0_wb_adr_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_adr_reg : 2'b00;
- assign s0_wb_sel_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_sel_reg : 2'b00;
- assign s0_wb_we_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_we_reg : 2'b00;
- assign s0_wb_cyc_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_cyc_reg : 2'b00;
- assign s0_wb_stb_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_stb_reg : 2'b00;
+ assign s0_wb_dat_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_dat_i_reg : 32'd00;
+ assign s0_wb_adr_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_adr_reg : 9'd0;
+ assign s0_wb_sel_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_sel_reg : 4'd0;
+ assign s0_wb_we_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_we_reg : 1'b0;
+ assign s0_wb_cyc_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_cyc_reg : 1'b0;
+ assign s0_wb_stb_o = (m0_wb_tid_reg == 2'b00) ? m0_wb_stb_reg : 1'b0;
- assign s1_wb_dat_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_dat_i_reg : 2'b00;
- assign s1_wb_adr_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_adr_reg : 2'b00;
- assign s1_wb_sel_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_sel_reg : 2'b00;
- assign s1_wb_we_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_we_reg : 2'b00;
- assign s1_wb_cyc_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_cyc_reg : 2'b00;
- assign s1_wb_stb_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_stb_reg : 2'b00;
+ assign s1_wb_dat_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_dat_i_reg : 32'd0;
+ assign s1_wb_adr_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_adr_reg : 9'd0;
+ assign s1_wb_sel_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_sel_reg : 4'd0;
+ assign s1_wb_we_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_we_reg : 1'b0;
+ assign s1_wb_cyc_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_cyc_reg : 1'b0;
+ assign s1_wb_stb_o = (m0_wb_tid_reg == 2'b01) ? m0_wb_stb_reg : 1'b0;
// assign s2_wb_dat_o = (m0_wb_tid_reg == 2'b10) ? m0_wb_dat_i_reg : 2'b00;
// assign s2_wb_adr_o = (m0_wb_tid_reg == 2'b10) ? m0_wb_adr_reg : 2'b00;
@@ -143,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 : 32'd0;
+ assign s3_wb_adr_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_adr_reg : 9'd0;
+ assign s3_wb_sel_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_sel_reg : 4'd0;
+ assign s3_wb_we_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_we_reg : 1'b0;
+ assign s3_wb_cyc_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_cyc_reg : 1'b0;
+ assign s3_wb_stb_o = (m0_wb_tid_reg == 2'b11) ? m0_wb_stb_reg : 1'b0;
assign m0_wb_dat_o = s_bus_rd_wb_dat;
assign m0_wb_ack_o = s_bus_rd_wb_ack;