Merge branch 'mpw5-sub'
diff --git a/docs/source/_static/secure_memory.png b/docs/source/_static/secure_memory.png
new file mode 100644
index 0000000..31f057f
--- /dev/null
+++ b/docs/source/_static/secure_memory.png
Binary files differ
diff --git a/docs/source/_static/trng.png b/docs/source/_static/trng.png
new file mode 100644
index 0000000..08243c2
--- /dev/null
+++ b/docs/source/_static/trng.png
Binary files differ
diff --git a/openlane/sram_wb_wrapper/config.tcl b/openlane/sram_wb_wrapper/config.tcl
deleted file mode 100644
index 5bffdca..0000000
--- a/openlane/sram_wb_wrapper/config.tcl
+++ /dev/null
@@ -1,40 +0,0 @@
-# User config
-set ::env(DESIGN_NAME) sram_wb_wrapper
-
-# Change if needed
-set ::env(VERILOG_FILES) "\
- $::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
- $::env(DESIGN_DIR)/../../verilog/rtl/sram/sram_wb_wrapper.sv"
-
-# Fill this
-set ::env(CLOCK_PERIOD) "10.0"
-set ::env(CLOCK_PORT) "wb_clk_i"
-
-set ::env(PDK) "sky130A"
-set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
-
-# Black-box verilog and views
-# set ::env(VERILOG_FILES_BLACKBOX) "\
-# $::env(DESIGN_DIR)/../../verilog/rtl/sram/sky130_sram_1kbyte_1rw1r_32x256_8.v"
-
-# set ::env(EXTRA_LEFS) "\
-# $::env(DESIGN_DIR)/../../lef/sky130_sram_1kbyte_1rw1r_32x256_8.lef"
-
-# set ::env(EXTRA_GDS_FILES) "\
-# $::env(DESIGN_DIR)/../../gds/sky130_sram_1kbyte_1rw1r_32x256_8.gds"
-
-# Preserve gate instances in the rtl of the design.
-
-set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 100 333"
-
-set ::env(PL_BASIC_PLACEMENT) 1
-set ::env(PL_TARGET_DENSITY) 0.50
-
-set ::env(VDD_PIN) [list {vccd1}]
-set ::env(GND_PIN) [list {vssd1}]
-set ::env(RT_MAX_LAYER) {met4}
-set ::env(DIODE_INSERTION_STRATEGY) 4
-set ::env(RUN_CVC) 1
-set ::env(ROUTING_CORES) "8"
-
diff --git a/openlane/user_proj_example/config.tcl b/openlane/user_proj_example/config.tcl
index 81e4e28..4e09ef1 100644
--- a/openlane/user_proj_example/config.tcl
+++ b/openlane/user_proj_example/config.tcl
@@ -20,7 +20,7 @@
# Fill this
-set ::env(CLOCK_PERIOD) "20.0"
+set ::env(CLOCK_PERIOD) "50.0"
set ::env(CLOCK_PORT) "wb_clk_i"
set ::env(CLOCK_NET) "wb_clk_i"
@@ -41,7 +41,7 @@
set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 1500 1000"
+set ::env(DIE_AREA) "0 0 2000 2500"
#set ::env(PL_BASIC_PLACEMENT) 1
set ::env(PL_TARGET_DENSITY) 0.50
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl
deleted file mode 100644
index 5c57399..0000000
--- a/openlane/wb_interconnect/config.tcl
+++ /dev/null
@@ -1,32 +0,0 @@
-# User config
-set ::env(DESIGN_NAME) wb_interconnect
-
-# Change if needed
-set ::env(VERILOG_FILES) "\
- $::env(CARAVEL_ROOT)/verilog/rtl/defines.v \
- $::env(DESIGN_DIR)/../../verilog/rtl/wb_interconnect/wb_interconnect.sv"
-
-# Fill this
-set ::env(CLOCK_PERIOD) "20.0"
-set ::env(CLOCK_PORT) "clk_i"
-
-set ::env(PDK) "sky130A"
-set ::env(STD_CELL_LIBRARY) "sky130_fd_sc_hd"
-
-
-# Preserve gate instances in the rtl of the design.
-
-
-set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 200 400"
-
-set ::env(PL_BASIC_PLACEMENT) 1
-set ::env(PL_TARGET_DENSITY) 0.50
-
-set ::env(VDD_PIN) [list {vccd1}]
-set ::env(GND_PIN) [list {vssd1}]
-
-set ::env(RT_MAX_LAYER) {met4}
-set ::env(DIODE_INSERTION_STRATEGY) 4
-set ::env(RUN_CVC) 1
-set ::env(ROUTING_CORES) "8"
diff --git a/openlane/wbuart32/config.tcl b/openlane/wbuart32/config.tcl
deleted file mode 100644
index fd4cbc3..0000000
--- a/openlane/wbuart32/config.tcl
+++ /dev/null
@@ -1,15 +0,0 @@
-# User config
-set ::env(DESIGN_NAME) user_proj_example
-
-# Change if needed
-set ::env(VERILOG_FILES) [glob $::env(DESIGN_DIR)/src/*.v]
-
-# Fill this
-set ::env(CLOCK_PERIOD) "10.0"
-set ::env(CLOCK_PORT) "clk"
-
-set filename $::env(DESIGN_DIR)/$::env(PDK)_$::env(STD_CELL_LIBRARY)_config.tcl
-if { [file exists $filename] == 1} {
- source $filename
-}
-
diff --git a/openlane/wbuart32/src/wbuart.v b/openlane/wbuart32/src/wbuart.v
deleted file mode 100644
index 27d38c4..0000000
--- a/openlane/wbuart32/src/wbuart.v
+++ /dev/null
@@ -1,528 +0,0 @@
-////////////////////////////////////////////////////////////////////////////////
-//
-// Filename: wbuart.v
-// {{{
-// Project: wbuart32, a full featured UART with simulator
-//
-// Purpose: Unlilke wbuart-insert.v, this is a full blown wishbone core
-// with integrated FIFO support to support the UART transmitter
-// and receiver found within here. As a result, it's usage may be
-// heavier on the bus than the insert, but it may also be more useful.
-//
-// Creator: Dan Gisselquist, Ph.D.
-// Gisselquist Technology, LLC
-//
-////////////////////////////////////////////////////////////////////////////////
-// }}}
-// Copyright (C) 2015-2021, Gisselquist Technology, LLC
-// {{{
-// This program is free software (firmware): you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as published
-// by the Free Software Foundation, either version 3 of the License, or (at
-// your option) any later version.
-//
-// This program is distributed in the hope that it will be useful, but WITHOUT
-// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
-// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
-// for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program. (It's in the $(ROOT)/doc directory. Run make with no
-// target there if the PDF file isn't present.) If not, see
-// <http://www.gnu.org/licenses/> for a copy.
-// }}}
-// License: GPL, v3, as defined and found on www.gnu.org,
-// {{{
-// http://www.gnu.org/licenses/gpl.html
-//
-//
-////////////////////////////////////////////////////////////////////////////////
-//
-//
-//`default_nettype none
-// }}}
-`define USE_LITE_UART
-module wbuart #(
- // {{{
- // 4MB 8N1, when using 100MHz clock
- parameter [30:0] INITIAL_SETUP = 31'd25,
- parameter [3:0] LGFLEN = 4,
- parameter [0:0] HARDWARE_FLOW_CONTROL_PRESENT = 1'b1
- // Perform a simple/quick bounds check on the log FIFO length,
- // to make sure its within the bounds we can support with our
- // current interface.
-
- // }}}
- ) (
- // {{{
- input wire i_clk, i_reset,
- // Wishbone inputs
- input wire i_wb_cyc,
- input wire i_wb_stb, i_wb_we,
- input wire [1:0] i_wb_addr,
- input wire [31:0] i_wb_data,
- input wire [3:0] i_wb_sel,
- output wire o_wb_stall,
- output reg o_wb_ack,
- output reg [31:0] o_wb_data,
- //
- input wire i_uart_rx,
- output wire o_uart_tx,
- input wire i_cts_n,
- output reg o_rts_n,
- output wire o_uart_rx_int, o_uart_tx_int,
- o_uart_rxfifo_int, o_uart_txfifo_int
- // }}}
- );
-
- localparam [3:0] LCLLGFLEN = (LGFLEN > 4'ha)? 4'ha
- : ((LGFLEN < 4'h2) ? 4'h2 : LGFLEN);
-
- localparam [1:0] UART_SETUP = 2'b00,
- UART_FIFO = 2'b01,
- UART_RXREG = 2'b10,
- UART_TXREG = 2'b11;
-
- // Register and signal declarations
- // {{{
- wire tx_busy;
- reg [30:0] uart_setup;
- // Receiver
- wire rx_stb, rx_break, rx_perr, rx_ferr, ck_uart;
- wire [7:0] rx_uart_data;
- reg rx_uart_reset;
- // Receive FIFO
- wire rx_empty_n, rx_fifo_err;
- wire [7:0] rxf_wb_data;
- wire [15:0] rxf_status;
- reg rxf_wb_read;
- //
- wire [(LCLLGFLEN-1):0] check_cutoff;
- reg r_rx_perr, r_rx_ferr;
- wire [31:0] wb_rx_data;
- // The transmitter
- wire tx_empty_n, txf_err, tx_break;
- wire [7:0] tx_data;
- wire [15:0] txf_status;
- reg txf_wb_write, tx_uart_reset;
- reg [7:0] txf_wb_data;
- //
- wire [31:0] wb_tx_data;
- wire [31:0] wb_fifo_data;
- reg [1:0] r_wb_addr;
- reg r_wb_ack;
- // }}}
-
- // uart_setup
- // {{{
- // The UART setup parameters: bits per byte, stop bits, parity, and
- // baud rate are all captured within this uart_setup register.
- //
- initial uart_setup = INITIAL_SETUP
- | ((HARDWARE_FLOW_CONTROL_PRESENT==1'b0)? 31'h40000000 : 0);
- always @(posedge i_clk)
- // Under wishbone rules, a write takes place any time i_wb_stb
- // is high. If that's the case, and if the write was to the
- // setup address, then set us up for the new parameters.
- if ((i_wb_stb)&&(i_wb_addr == UART_SETUP)&&(i_wb_we))
- begin
- if (i_wb_sel[0])
- uart_setup[7:0] <= i_wb_data[7:0];
- if (i_wb_sel[1])
- uart_setup[15:8] <= i_wb_data[15:8];
- if (i_wb_sel[2])
- uart_setup[23:16] <= i_wb_data[23:16];
- if (i_wb_sel[3])
- uart_setup[30:24] <= { (i_wb_data[30])
- ||(!HARDWARE_FLOW_CONTROL_PRESENT),
- i_wb_data[29:24] };
- end
- // }}}
- ////////////////////////////////////////////////////////////////////////
- //
- // The UART receiver
- // {{{
- ////////////////////////////////////////////////////////////////////////
- //
- //
-
- // The receiver itself
- // {{{
- // Here's our UART receiver. Basically, it accepts our setup wires,
- // the UART input, a clock, and a reset line, and produces outputs:
- // a stb (true when new data is ready), and an 8-bit data out value
- // valid when stb is high.
-`ifdef USE_LITE_UART
- // {{{
- rxuartlite #(.CLOCKS_PER_BAUD(INITIAL_SETUP[23:0]))
- rx(i_clk, i_uart_rx, rx_stb, rx_uart_data);
- assign rx_break = 1'b0;
- assign rx_perr = 1'b0;
- assign rx_ferr = 1'b0;
- assign ck_uart = 1'b0;
- // }}}
-`else
- // {{{
- // The full receiver also produces a break value (true during a break
- // cond.), and parity/framing error flags--also valid when stb is true.
- rxuart #(.INITIAL_SETUP(INITIAL_SETUP)) rx(i_clk, (i_reset)||(rx_uart_reset),
- uart_setup, i_uart_rx,
- rx_stb, rx_uart_data, rx_break,
- rx_perr, rx_ferr, ck_uart);
- // The real trick is ... now that we have this extra data, what do we do
- // with it?
- // }}}
-`endif
- // }}}
-
- // The receive FIFO
- // {{{
- // We place new arriving data into a receiver FIFO.
- //
- // And here's the FIFO proper.
- //
- // Note that the FIFO will be cleared upon any reset: either if there's
- // a UART break condition on the line, the receiver is in reset, or an
- // external reset is issued.
- //
- // The FIFO accepts strobe and data from the receiver.
- // We issue another wire to it (rxf_wb_read), true when we wish to read
- // from the FIFO, and we get our data in rxf_wb_data. The FIFO outputs
- // four status-type values: 1) is it non-empty, 2) is the FIFO over half
- // full, 3) a 16-bit status register, containing info regarding how full
- // the FIFO truly is, and 4) an error indicator.
- ufifo #(.LGFLEN(LCLLGFLEN), .RXFIFO(1))
- rxfifo(i_clk, (i_reset)||(rx_break)||(rx_uart_reset),
- rx_stb, rx_uart_data,
- rx_empty_n,
- rxf_wb_read, rxf_wb_data,
- rxf_status, rx_fifo_err);
- // }}}
-
- assign o_uart_rxfifo_int = rxf_status[1];
-
- // We produce four interrupts. One of the receive interrupts indicates
- // whether or not the receive FIFO is non-empty. This should wake up
- // the CPU.
- assign o_uart_rx_int = rxf_status[0];
-
- // o_rts_n
- // {{{
- // The clear to send line, which may be ignored, but which we set here
- // to be true any time the FIFO has fewer than N-2 items in it.
- // Why not N-1? Because at N-1 we are totally full, but already so full
- // that if the transmit end starts sending we won't have a location to
- // receive it. (Transmit might've started on the next character by the
- // time we set this--thus we need to set it to one, one character before
- // necessary).
- assign check_cutoff = -3;
- always @(posedge i_clk)
- o_rts_n <= ((HARDWARE_FLOW_CONTROL_PRESENT)
- &&(!uart_setup[30])
- &&(rxf_status[(LCLLGFLEN+1):2] > check_cutoff));
- // }}}
-
- // rxf_wb_read
- // {{{
- // If the bus requests that we read from the receive FIFO, we need to
- // tell this to the receive FIFO. Note that because we are using a
- // clock here, the output from the receive FIFO will necessarily be
- // delayed by an extra clock.
- initial rxf_wb_read = 1'b0;
- always @(posedge i_clk)
- rxf_wb_read <= (i_wb_stb)&&(i_wb_addr[1:0]== UART_RXREG)
- &&(!i_wb_we);
- // }}}
-
- // r_rx_perr, r_rx_ferr -- parity and framing errors
- // {{{
- // Now, let's deal with those RX UART errors: both the parity and frame
- // errors. As you may recall, these are valid only when rx_stb is
- // valid, so we need to hold on to them until the user reads them via
- // a UART read request..
- initial r_rx_perr = 1'b0;
- initial r_rx_ferr = 1'b0;
- always @(posedge i_clk)
- if ((rx_uart_reset)||(rx_break))
- begin
- // Clear the error
- r_rx_perr <= 1'b0;
- r_rx_ferr <= 1'b0;
- end else if ((i_wb_stb)
- &&(i_wb_addr[1:0]== UART_RXREG)&&(i_wb_we))
- begin
- // Reset the error lines if a '1' is ever written to
- // them, otherwise leave them alone.
- //
- if (i_wb_sel[1])
- begin
- r_rx_perr <= (r_rx_perr)&&(~i_wb_data[9]);
- r_rx_ferr <= (r_rx_ferr)&&(~i_wb_data[10]);
- end
- end else if (rx_stb)
- begin
- // On an rx_stb, capture any parity or framing error
- // indications. These aren't kept with the data rcvd,
- // but rather kept external to the FIFO. As a result,
- // if you get a parity or framing error, you will never
- // know which data byte it was associated with.
- // For now ... that'll work.
- r_rx_perr <= (r_rx_perr)||(rx_perr);
- r_rx_ferr <= (r_rx_ferr)||(rx_ferr);
- end
- // }}}
-
- // rx_uart_reset
- // {{{
- initial rx_uart_reset = 1'b1;
- always @(posedge i_clk)
- if ((i_reset)||((i_wb_stb)&&(i_wb_addr[1:0]== UART_SETUP)&&(i_wb_we)))
- // The receiver reset, always set on a master reset
- // request.
- rx_uart_reset <= 1'b1;
- else if ((i_wb_stb)&&(i_wb_addr[1:0]== UART_RXREG)&&(i_wb_we)&&i_wb_sel[1])
- // Writes to the receive register will command a receive
- // reset anytime bit[12] is set.
- rx_uart_reset <= i_wb_data[12];
- else
- rx_uart_reset <= 1'b0;
- // }}}
-
- // wb_rx_data
- // {{{
- // Finally, we'll construct a 32-bit value from these various wires,
- // to be returned over the bus on any read. These include the data
- // that would be read from the FIFO, an error indicator set upon
- // reading from an empty FIFO, a break indicator, and the frame and
- // parity error signals.
- assign wb_rx_data = { 16'h00,
- 3'h0, rx_fifo_err,
- rx_break, rx_ferr, r_rx_perr, !rx_empty_n,
- rxf_wb_data};
- // }}}
- // }}}
- ////////////////////////////////////////////////////////////////////////
- //
- // The UART transmitter
- // {{{
- ////////////////////////////////////////////////////////////////////////
- //
- //
-
- // txf_wb_write, txf_wb_data
- // {{{
- // Unlike the receiver which goes from RXUART -> UFIFO -> WB, the
- // transmitter basically goes WB -> UFIFO -> TXUART. Hence, to build
- // support for the transmitter, we start with the command to write data
- // into the FIFO. In this case, we use the act of writing to the
- // UART_TXREG address as our indication that we wish to write to the
- // FIFO. Here, we create a write command line, and latch the data for
- // the extra clock that it'll take so that the command and data can be
- // both true on the same clock.
- initial txf_wb_write = 1'b0;
- always @(posedge i_clk)
- begin
- txf_wb_write <= (i_wb_stb)&&(i_wb_addr == UART_TXREG)
- &&(i_wb_we)&&(i_wb_sel[0]);
- txf_wb_data <= i_wb_data[7:0];
- end
- // }}}
-
- // Transmit FIFO
- // {{{
- // Most of this is just wire management. The TX FIFO is identical in
- // implementation to the RX FIFO (theyre both UFIFOs), but the TX
- // FIFO is fed from the WB and read by the transmitter. Some key
- // differences to note: we reset the transmitter on any request for a
- // break. We read from the FIFO any time the UART transmitter is idle.
- // and ... we just set the values (above) for controlling writing into
- // this.
- // ufifo #(.LGFLEN(LGFLEN), .RXFIFO(0))
- // txfifo(i_clk, (tx_break)||(tx_uart_reset),
- // txf_wb_write, txf_wb_data,
- // tx_empty_n,
- // (!tx_busy)&&(tx_empty_n), tx_data,
- // txf_status, txf_err);
- // }}}
-
- // Transmit interrupts
- // {{{
- // Let's create two transmit based interrupts from the FIFO for the CPU.
- // The first will be true any time the FIFO has at least one open
- // position within it.
- assign o_uart_tx_int = 1'b0;
- // The second will be true any time the FIFO is less than half
- // full, allowing us a change to always keep it (near) fully
- // charged.
- assign o_uart_txfifo_int = 1'b0;
- // }}}
-
- // Break logic
-`ifndef USE_LITE_UART
- // {{{
- // A break in a UART controller is any time the UART holds the line
- // low for an extended period of time. Here, we capture the wb_data[9]
- // wire, on writes, as an indication we wish to break. As long as you
- // write unsigned characters to the interface, this will never be true
- // unless you wish it to be true. Be aware, though, writing a valid
- // value to the interface will bring it out of the break condition.
- reg r_tx_break;
- initial r_tx_break = 1'b0;
- always @(posedge i_clk)
- if (i_reset)
- r_tx_break <= 1'b0;
- else if ((i_wb_stb)&&(i_wb_addr[1:0]== UART_TXREG)&&(i_wb_we)
- &&(i_wb_sel[1]))
- r_tx_break <= i_wb_data[9];
-
- assign tx_break = r_tx_break;
- // }}}
-`else
- // {{{
- assign tx_break = 1'b0;
- // }}}
-`endif
-
- // TX-Reset logic
- // {{{{
- // This is nearly identical to the RX reset logic above. Basically,
- // any time someone writes to bit [12] the transmitter will go through
- // a reset cycle. Keep bit [12] low, and everything will proceed as
- // normal.
- initial tx_uart_reset = 1'b1;
- always @(posedge i_clk)
- if((i_reset)||((i_wb_stb)&&(i_wb_addr == UART_SETUP)&&(i_wb_we)))
- tx_uart_reset <= 1'b1;
- else if ((i_wb_stb)&&(i_wb_addr[1:0]== UART_TXREG)&&(i_wb_we) && i_wb_sel[1])
- tx_uart_reset <= i_wb_data[12];
- else
- tx_uart_reset <= 1'b0;
- // }}}
-
- // The actuall transmitter itself
-`ifdef USE_LITE_UART
- // {{{
- txuartlite #(.CLOCKS_PER_BAUD(INITIAL_SETUP[23:0])) tx(i_clk, txf_wb_write, txf_wb_data,
- o_uart_tx, tx_busy);
- // }}}
-`else
- // cts_n
- // {{{
- wire cts_n;
- assign cts_n = (HARDWARE_FLOW_CONTROL_PRESENT)&&(i_cts_n);
- // }}}
-
- // The *full* transmitter impleemntation
- // {{{
- // Finally, the UART transmitter module itself. Note that we haven't
- // connected the reset wire. Transmitting is as simple as setting
- // the stb value (here set to tx_empty_n) and the data. When these
- // are both set on the same clock that tx_busy is low, the transmitter
- // will move on to the next data byte. Really, the only thing magical
- // here is that tx_empty_n wire--thus, if there's anything in the FIFO,
- // we read it here. (You might notice above, we register a read any
- // time (tx_empty_n) and (!tx_busy) are both true---the condition for
- // starting to transmit a new byte.)
- txuart #(.INITIAL_SETUP(INITIAL_SETUP)) tx(i_clk, 1'b0, uart_setup,
- r_tx_break, (tx_empty_n), tx_data,
- cts_n, o_uart_tx, tx_busy);
- // }}}
-`endif
-
- // wb_tx_data
- // {{{
- // Now that we are done with the chain, pick some wires for the user
- // to read on any read of the transmit port.
- //
- // This port is different from reading from the receive port, since
- // there are no side effects. (Reading from the receive port advances
- // the receive FIFO, here only writing to the transmit port advances the
- // transmit FIFO--hence the read values are free for ... whatever.)
- // We choose here to provide information about the transmit FIFO
- // (txf_err, txf_half_full, txf_full_n), information about the current
- // voltage on the line (o_uart_tx)--and even the voltage on the receive
- // line (ck_uart), as well as our current setting of the break and
- // whether or not we are actively transmitting.
- // assign wb_tx_data = { 16'h00,
- // i_cts_n, txf_status[1:0], txf_err,
- // ck_uart, o_uart_tx, tx_break, (tx_busy|txf_status[0]),
- // (tx_busy|txf_status[0])?txf_wb_data:8'b00};
-
- assign wb_tx_data = {24'd0, txf_wb_data};
- // }}}
- // }}}
- ////////////////////////////////////////////////////////////////////////
- //
- // Bus / register handling
- // {{{
- ////////////////////////////////////////////////////////////////////////
- //
- //
-
-
- // wb_fifo_data
- // {{{
- // Each of the FIFO's returns a 16 bit status value. This value tells
- // us both how big the FIFO is, as well as how much of the FIFO is in
- // use. Let's merge those two status words together into a word we
- // can use when reading about the FIFO.
- //assign wb_fifo_data = { txf_status, rxf_status };
- assign wb_fifo_data = { 16'd0, rxf_status };
- // }}}
-
- // r_wb_addr
- // {{{
- // You may recall from above that reads take two clocks. Hence, we
- // need to delay the address decoding for a clock until the data is
- // ready. We do that here.
- always @(posedge i_clk)
- r_wb_addr <= i_wb_addr;
- // }}}
-
- // r_wb_ack
- // {{{
- initial r_wb_ack = 1'b0;
- always @(posedge i_clk) // We'll ACK in two clocks
- r_wb_ack <= i_wb_stb;
- // }}}
-
- // o_wb_ack
- // {{{
- initial o_wb_ack = 1'b0;
- always @(posedge i_clk) // Okay, time to set the ACK
- o_wb_ack <= i_wb_cyc && r_wb_ack;
- // }}}
-
- // o_wb_data
- // {{{
- // Finally, set the return data. This data must be valid on the same
- // clock o_wb_ack is high. On all other clocks, it is irrelelant--since
- // no one cares, no one is reading it, it gets lost in the mux in the
- // interconnect, etc. For this reason, we can just simplify our logic.
- always @(posedge i_clk)
- casez(r_wb_addr)
- UART_SETUP: o_wb_data <= { 1'b0, uart_setup };
- UART_FIFO: o_wb_data <= wb_fifo_data;
- UART_RXREG: o_wb_data <= wb_rx_data;
- UART_TXREG: o_wb_data <= wb_tx_data;
- endcase
- // }}}
-
- // o_wb_stall
- // {{{
- // This device never stalls. Sure, it takes two clocks, but they are
- // pipelined, and nothing stalls that pipeline. (Creates FIFO errors,
- // perhaps, but doesn't stall the pipeline.) Hence, we can just
- // set this value to zero.
- assign o_wb_stall = 1'b0;
- // }}}
- // }}}
-
- // Make verilator happy
- // {{{
- // verilator lint_off UNUSED
- wire unused;
- assign unused = &{ 1'b0, i_wb_data[31] };
- // verilator lint_on UNUSED
- // }}}
-endmodule
diff --git a/verilog/dv/wb_sram/wb_sram.c b/verilog/dv/wb_sram/wb_sram.c
index 5f9c1c3..49a012d 100644
--- a/verilog/dv/wb_sram/wb_sram.c
+++ b/verilog/dv/wb_sram/wb_sram.c
@@ -90,10 +90,10 @@
volatile unsigned dummy;
bool error = false;
//writing to master key
- *(reg_SRAM) = 0xDEADBEEF;
*(reg_SRAM) = 0xCAFEBEEF;
- *(reg_SRAM) = 0x01234567;
- *(reg_SRAM) = 0x89abcdef;
+ // *(reg_SRAM) = 0xCAFEBEEF;
+ // *(reg_SRAM) = 0x01234567;
+ // *(reg_SRAM) = 0x89abcdef;
@@ -102,15 +102,19 @@
*(reg_SRAM+(2*4)) = 0xDEADBEEF;
//wait for wr_busy
- while(*(reg_SRAM +2) != 0);
+ //while(*(reg_SRAM +2) != 0);
- dummy = *(reg_SRAM + (2 * 4));
+ //dummy = *(reg_SRAM + (2 * 4));
//wait for rd_busy
- while(*(reg_SRAM + 2) != 0);
+ // while(*(reg_SRAM + 2) != 0);
- if(*(reg_SRAM + 1) != 0xDEADBEEF)
+ //if(*(reg_SRAM + 1) != 0xDEADBEEF)
+ // error = true;
+
+ if(*(reg_SRAM+(2*4)) != 0xDEADBEEF)
error = true;
+
// for (int i = 0; i < 32; i++)
// {
// if(*(reg_SRAM+(i*4)) != i * 1024 )
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index d0827e5..37f25a5 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -2,7 +2,8 @@
-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/sram/sram_wb_wrapper.sv
+-v $(USER_PROJECT_VERILOG)/rtl/sram/sram_wb_wrapper_xor.sv
-v $(USER_PROJECT_VERILOG)/rtl/aes/aes.v
-v $(USER_PROJECT_VERILOG)/rtl/security_monitor/lfsr.v
-v $(USER_PROJECT_VERILOG)/rtl/spi/tiny_spi.v
diff --git a/verilog/rtl/sram/sram_wb_wrapper_xor.sv b/verilog/rtl/sram/sram_wb_wrapper_xor.sv
new file mode 100644
index 0000000..c85a374
--- /dev/null
+++ b/verilog/rtl/sram/sram_wb_wrapper_xor.sv
@@ -0,0 +1,146 @@
+//-----------------------------------------------------------------------------
+// @file sram_wb_wrapper.vhd
+//
+// @brief This block is a wishbone wrapper for SRAM signal mapping
+//
+// @details This wrapper gets signal from master if it is selected
+// and convey to the SRAM module and vice versa.
+//
+// @author Sukru Uzun <sukru.uzun@procenne.com>
+// @date 10.03.2022
+//
+// @todo SRAM signalization should be checked
+// @warning SRAM signalization
+//
+// @project https://github.com/Procenne-Digital-Design/secure-memory.git
+//
+// @revision :
+// 0.1 - 10 March 2022, Sukru Uzun
+// initial version
+// 0.2 - 16 March 2022, Sukru Uzun
+// remove SRAM design
+// 0.3 - 20 March 2022, Emre Goncu
+// adding ciphering mechanism
+//-----------------------------------------------------------------------------
+
+module sram_wb_wrapper #(
+ parameter SRAM_ADDR_WD = 8 ,
+ parameter SRAM_DATA_WD = 32
+) (
+`ifdef USE_POWER_PINS
+ input wire vccd1 , // User area 1 1.8V supply
+ input wire vssd1 , // User area 1 digital ground
+`endif
+ input wire rst ,
+ // Wishbone Interface
+ input wire wb_clk_i , // System clock
+ input wire wb_cyc_i , // strobe/request
+ input wire wb_stb_i , // strobe/request
+ input wire [ SRAM_ADDR_WD-1:0] wb_adr_i , // address
+ input wire wb_we_i , // write
+ input wire [ SRAM_DATA_WD-1:0] wb_dat_i , // data output
+ input wire [SRAM_DATA_WD/8-1:0] wb_sel_i , // byte enable
+ output wire [ SRAM_DATA_WD-1:0] wb_dat_o , // data input
+ output reg wb_ack_o , // acknowlegement
+ // SRAM Interface
+ // Port A
+ output wire sram_csb_a ,
+ output wire [ SRAM_ADDR_WD-1:0] sram_addr_a ,
+ input wire [ SRAM_DATA_WD-1:0] sram_dout_a ,
+ // Port B
+ output wire sram_csb_b ,
+ output wire sram_web_b ,
+ output wire [SRAM_DATA_WD/8-1:0] sram_mask_b ,
+ output wire [ SRAM_ADDR_WD-1:0] sram_addr_b ,
+ output wire [ SRAM_DATA_WD-1:0] sram_din_b ,
+ output reg master_key_ready,
+ input wire [ 31:0] trng_i ,
+ input wire alarm ,
+ output reg alarm_set
+);
+
+
+ wire master_key_en ;
+ reg [31:0] master_key ;
+ reg [ 1:0] counter ;
+ reg [ 4:0] trng_count ;
+
+ reg [8:0] wb_adr_reg;
+
+
+ assign master_key_en = rst ? 1'b0 :
+ ((alarm)|| ((wb_adr_i == 32'd0) && wb_cyc_i && wb_stb_i && wb_we_i && !wb_ack_o)) ? 1'b1 : 1'b0;
+
+ always @(posedge wb_clk_i ) begin
+ if(rst)
+ begin
+ alarm_set <= 1'b0;
+ end
+ else
+ if((wb_adr_i == 32'd3) && wb_cyc_i && wb_stb_i && wb_we_i && !wb_ack_o)
+ begin
+ alarm_set <= ~alarm_set;
+ end
+ end
+
+ always @(posedge wb_clk_i) begin
+ if(rst)
+ begin
+ master_key <= 32'd0;
+ trng_count <= 5'd0;
+ master_key_ready <= 1'b0;
+ end
+ else
+ begin
+ master_key_ready <= 1'b0;
+ if(master_key_en)
+ begin
+ if(wb_dat_i)
+ begin
+ master_key <= wb_dat_i;
+ master_key_ready <= 1'b1;
+ end
+ else
+ begin
+ master_key <= trng_i;
+ end
+ end
+ end
+ end
+
+
+ assign sram_csb_b = !wb_stb_i;
+ assign sram_web_b = !wb_we_i;
+ assign sram_mask_b = wb_sel_i;
+ assign sram_addr_b = wb_adr_i;
+ assign sram_din_b = wb_dat_i ^ master_key;
+
+
+ assign sram_csb_a = (wb_stb_i == 1'b1 && wb_we_i == 1'b0 && wb_cyc_i == 1'b1) ? 1'b0 : 1'b1;
+ assign sram_addr_a = wb_adr_i;
+
+ assign wb_dat_o = (wb_adr_reg == 9'd1 && wb_ack_o == 1'b1) ? {31'd0,alarm} :
+ (wb_ack_o == 1'b1) ? sram_dout_a ^ master_key : 32'd0;
+
+
+// Generate once cycle delayed ACK to get the data from SRAM
+ always @(posedge wb_clk_i)
+ begin
+ if ( rst == 1'b1 )
+ begin
+ wb_ack_o <= 1'b0;
+ wb_adr_reg <= 9'd0;
+ end
+ else
+ begin
+ if((wb_stb_i == 1'b1) && (wb_cyc_i == 1'b1))
+ begin
+ wb_ack_o <= 1'b1 ;
+ wb_adr_reg <= wb_adr_i;
+ end
+ else
+ wb_ack_o <= 1'b0 ;
+ end
+ end
+
+endmodule
diff --git a/verilog/rtl/user_proj_example.v b/verilog/rtl/user_proj_example.v
index b2e6506..de6ff88 100644
--- a/verilog/rtl/user_proj_example.v
+++ b/verilog/rtl/user_proj_example.v
@@ -238,7 +238,7 @@
.sram_mask_b(sram_mask_b),
.sram_addr_b(sram_addr_b),
.sram_din_b (sram_din_b ),
- .trng_i(trng_i),
+ .trng_i(trng_buffer_i),
.alarm(alarm),
.master_key_ready(master_key_ready),
.alarm_set(alarm_set)
@@ -280,8 +280,8 @@
.i_Clk (wb_clk_i ),
.i_Enable (1'b1 ),
.i_alarm_set (alarm_set),
- .i_Seed_DV (wb_rst_i ),
- .i_Seed_Data (trng_i ),
+ .i_Seed_DV (trng_wb_cyc_o),
+ .i_Seed_Data (trng_buffer_i ),
.o_LFSR_Data (o_LFSR_Data ),
.o_LFSR_Done (),
.i_LFSR ( io_in[17]),