Made a handful of corrections to the array connectivity; the array now passes tests 2 and 3.
diff --git a/verilog/dv/README.local b/verilog/dv/README.local index cb6c608..20c407b 100644 --- a/verilog/dv/README.local +++ b/verilog/dv/README.local
@@ -12,7 +12,7 @@ make setup -Simulation environment setup: +Simulation environment setup (also requires PDK_ROOT and PDK from above): setenv CORE_VERILOG_PATH /home/tim/gits/chaos_automaton_final/mgmt_core_wrapper/verilog setenv DESIGNS /home/tim/gits/chaos_automaton_final
diff --git a/verilog/dv/chaos_test1/chaos_test1_tb.v b/verilog/dv/chaos_test1/chaos_test1_tb.v index cacb564..fd26ef6 100644 --- a/verilog/dv/chaos_test1/chaos_test1_tb.v +++ b/verilog/dv/chaos_test1/chaos_test1_tb.v
@@ -53,11 +53,11 @@ assign mprj_io[3] = (CSB == 1'b1) ? 1'b1 : 1'bz; initial begin - // $dumpfile("chaos_test1.vcd"); - // $dumpvars(0, chaos_test1_tb); + $dumpfile("chaos_test1.vcd"); + $dumpvars(0, chaos_test1_tb); // Repeat cycles of 1000 clock edges as needed to complete testbench - repeat (200) begin + repeat (100) begin repeat (1000) @(posedge clock); // $display("+1000 cycles"); end
diff --git a/verilog/dv/chaos_test3/chaos_test3.c b/verilog/dv/chaos_test3/chaos_test3.c index a80b495..f4445c3 100644 --- a/verilog/dv/chaos_test3/chaos_test3.c +++ b/verilog/dv/chaos_test3/chaos_test3.c
@@ -115,6 +115,9 @@ // Apply input values first, so that the bits are valid // when the load process toggles "hold" on all cells. + // Apply a reset to all cells (auto-clearing bit) + reg_user_transfer = 4; + // Apply zero bits to all inputs reg_user_data0 = 0; reg_user_data1 = 0;
diff --git a/verilog/dv/local-install.md b/verilog/dv/local-install.md new file mode 100644 index 0000000..7cd54c1 --- /dev/null +++ b/verilog/dv/local-install.md
@@ -0,0 +1,65 @@ +# Local Installation (Linux) + +Instructions to install the dv setup locally (dockerless install). + +## You will need to fullfil these dependecies: + +* Icarus Verilog (10.2+) +* RV32I Toolchain + +Using apt, you can install Icarus Verilog: + +```bash +sudo apt-get install iverilog +``` + +Next, you will need to build the RV32I toolchain. Firstly, export the installation path for the RV32I toolchain, + +```bash +export GCC_PATH=<gcc-installation-path> +``` + +Then, run the following: + +```bash +# packages needed: +sudo apt-get install autoconf automake autotools-dev curl libmpc-dev \ + libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo \ + gperf libtool patchutils bc zlib1g-dev git libexpat1-dev + +sudo mkdir $GCC_PATH +sudo chown $USER $GCC_PATH + +git clone https://github.com/riscv/riscv-gnu-toolchain riscv-gnu-toolchain-rv32i +cd riscv-gnu-toolchain-rv32i +git checkout 411d134 +git submodule update --init --recursive + +mkdir build; cd build +../configure --with-arch=rv32i --prefix=$GCC_PATH +make -j$(nproc) +``` + +# Running Simulation + +You will need to export these environment variables: + +```bash +export GCC_PATH=<gcc-installation-path> +export PDK_PATH=<pdk-location/sky130A> +``` + +To run any simulation, you need to be on the top level or caravel_user_project. + +To run RTL simulation for one of the DV tests, + +```bash +SIM=RTL make verify-<dv-test> +``` + +To run gate level simulation for one of the DV tests, + +```bash +SIM=GL make verify-<dv-test> +``` +
diff --git a/verilog/rtl/chaos_subarray.v b/verilog/rtl/chaos_subarray.v index b9bf395..252007c 100755 --- a/verilog/rtl/chaos_subarray.v +++ b/verilog/rtl/chaos_subarray.v
@@ -234,16 +234,16 @@ /* Connect the endpoints of the array to the inputs and outputs of the module */ - for (j = 0; j < YSIZE; j=j+1) begin: connx - assign rconn[XSIZE][j] = ieast[j]; - assign lconn[0][j] = iwest[j]; + for (j = 0; j < YSIZE; j=j+1) begin: conny + assign rconn[0][j] = iwest[j]; + assign lconn[XSIZE][j] = ieast[j]; assign oeast[j] = rconn[XSIZE][j]; assign owest[j] = lconn[0][j]; end - for (i = 0; i < XSIZE; i=i+1) begin: conny - assign uconn[YSIZE][i] = inorth[i]; - assign dconn[0][i] = isouth[i]; + for (i = 0; i < XSIZE; i=i+1) begin: connx + assign uconn[0][i] = isouth[i]; + assign dconn[YSIZE][i] = inorth[i]; assign onorth[i] = uconn[YSIZE][i]; assign osouth[i] = dconn[0][i]; end
diff --git a/verilog/rtl/user_defines.v b/verilog/rtl/user_defines.v new file mode 100644 index 0000000..43ed500 --- /dev/null +++ b/verilog/rtl/user_defines.v
@@ -0,0 +1,87 @@ +// 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 + +`ifndef __USER_DEFINES_H +// User GPIO initial configuration parameters +`define __USER_DEFINES_H + +// Useful GPIO mode values. These match the names used in defs.h. +`define GPIO_MODE_MGMT_STD_INPUT_NOPULL 13'h0403 +`define GPIO_MODE_MGMT_STD_INPUT_PULLDOWN 13'h0803 +`define GPIO_MODE_MGMT_STD_INPUT_PULLUP 13'h0c03 +`define GPIO_MODE_MGMT_STD_OUTPUT 13'h1809 +`define GPIO_MODE_MGMT_STD_BIDIRECTIONAL 13'h1801 +`define GPIO_MODE_MGMT_STD_ANALOG 13'h000b + +`define GPIO_MODE_USER_STD_INPUT_NOPULL 13'h0402 +`define GPIO_MODE_USER_STD_INPUT_PULLDOWN 13'h0802 +`define GPIO_MODE_USER_STD_INPUT_PULLUP 13'h0c02 +`define GPIO_MODE_USER_STD_OUTPUT 13'h1808 +`define GPIO_MODE_USER_STD_BIDIRECTIONAL 13'h1800 +`define GPIO_MODE_USER_STD_OUT_MONITORED 13'h1802 +`define GPIO_MODE_USER_STD_ANALOG 13'h000a + +// The power-on configuration for GPIO 0 to 4 is fixed and cannot be +// modified (allowing the SPI and debug to always be accessible unless +// overridden by a flash program). + +// The values below can be any of the standard types defined above, +// or they can be any 13-bit value if the user wants a non-standard +// startup state for the GPIO. By default, every GPIO from 5 to 37 +// is set to power up as an input controlled by the management SoC. +// Users may want to redefine these so that the user project powers +// up in a state that can be used immediately without depending on +// the management SoC to run a startup program to configure the GPIOs. + +`define USER_CONFIG_GPIO_5_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_6_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_7_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_8_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_9_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_10_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_11_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_12_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_13_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_14_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL + +// Configurations of GPIO 15 to 25 are used on caravel but not caravan. +`define USER_CONFIG_GPIO_15_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_16_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_17_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_18_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_19_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_20_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_21_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_22_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_23_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_24_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_25_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL + +`define USER_CONFIG_GPIO_26_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_27_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_28_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_29_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_30_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_31_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_32_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_33_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_34_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_35_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_36_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL +`define USER_CONFIG_GPIO_37_INIT `GPIO_MODE_USER_STD_BIDIRECTIONAL + +`endif // __USER_DEFINES_H
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index c5e0dd8..09691b6 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v
@@ -191,6 +191,7 @@ reg [2:0] xfer_state; /* state of the data transfer */ reg [1:0] xfer_ctrl; /* Configuration transfer trigger bits */ reg [63:0] config_data; /* 64 bits to read or write configuration */ + reg local_reset; /* Reset applied from a register */ reg [ASIZE - 1:0] cell_addr; /* Core cell to address */ reg [ASIZE - 1:0] cell_offset; /* Current offset of shift register */ @@ -223,6 +224,7 @@ reg [31:0] wbs_dat_o; reg [63:0] wdata; reg write; + wire all_cell_reset; // Direction for each GPIO (32 used) reg [31:0] gpio_oeb; @@ -276,7 +278,7 @@ // GPIOs can be clustered on either end or in the center of the array // side, or distributed along the side (1 GPIO per 5 array cells) reg [1:0] gpio_output_slice; - reg [1:0] gpio_input_slice; + reg [2:0] gpio_input_slice; // Registered GPIO directions go directly to io_oeb[37:6]. Leave the // lower 6 GPIO to the management processor. @@ -301,6 +303,8 @@ assign wbs_ack_o = ready; assign iomem_we = wbs_sel_i & {4{wbs_we_i}}; + assign all_cell_reset = wb_rst_i | local_reset; + // IRQ assign user_irq = 3'b000; // Unused @@ -318,7 +322,7 @@ .vssd1(vssd1), `endif .clk(clk), - .reset(wb_rst_i), + .reset(all_cell_reset), .hold(hold), .rdata(rdata), .wdata(wdata), @@ -395,39 +399,42 @@ // the arrays (high to low index is top to bottom, or right to left). assign gpio_east = // I/O 15 to 6 - (gpio_input_slice == 0) ? // Distributed + (gpio_input_slice == 0) ? 50'b0 : // No pad input + (gpio_input_slice == 1) ? // Distributed {2'b0, io_in[15], 4'b0, io_in[14], 4'b0, io_in[13], 4'b0, io_in[12], 4'b0, io_in[11], 4'b0, io_in[10], 4'b0, io_in[9], 4'b0, io_in[8], 4'b0, io_in[7], 4'b0, io_in[6], 2'b0} : - (gpio_input_slice == 1) ? {40'b0, io_in[15:6]} : // Bottom shifted - (gpio_input_slice == 2) ? {20'b0, io_in[15:6], 20'b0} : // Centered + (gpio_input_slice == 2) ? {40'b0, io_in[15:6]} : // Bottom shifted + (gpio_input_slice == 3) ? {20'b0, io_in[15:6], 20'b0} : // Centered {io_in[15:6], 40'b0}; // Top shifted assign gpio_north = // I/O 21 to 16 - (gpio_input_slice == 0) ? // Distributed + (gpio_input_slice == 0) ? 30'b0 : // No pad input + (gpio_input_slice == 1) ? // Distributed {2'b0, io_in[16], 4'b0, io_in[17], 4'b0, io_in[18], 4'b0, io_in[19], 4'b0, io_in[20], 4'b0, io_in[21], 2'b0} : - (gpio_input_slice == 1) ? // Right shifted + (gpio_input_slice == 2) ? // Right shifted {14'b0, io_in[16], io_in[17], io_in[18], io_in[19], io_in[20], io_in[21]} : - (gpio_input_slice == 2) ? // Centered + (gpio_input_slice == 3) ? // Centered {7'b0, io_in[16], io_in[17], io_in[18], io_in[19], io_in[20], io_in[21], 7'b0} : {io_in[16], io_in[17], io_in[18], io_in[19], io_in[20], io_in[21], 4'b0}; // Left shifted assign gpio_west = // I/O 22 to 31 - (gpio_input_slice == 0) ? // Distributed + (gpio_input_slice == 0) ? 50'b0 : // No pad input + (gpio_input_slice == 1) ? // Distributed {2'b0, io_in[22], 4'b0, io_in[23], 4'b0, io_in[24], 4'b0, io_in[25], 4'b0, io_in[26], 4'b0, io_in[27], 4'b0, io_in[28], 4'b0, io_in[29], 4'b0, io_in[30], 4'b0, io_in[31], 2'b0} : - (gpio_input_slice == 1) ? // Bottom shifted + (gpio_input_slice == 2) ? // Bottom shifted {40'b0, io_in[22], io_in[23], io_in[24], io_in[25], io_in[26], io_in[27], io_in[28], io_in[29], io_in[31], io_in[31]} : - (gpio_input_slice == 2) ? // Centered + (gpio_input_slice == 3) ? // Centered {20'b0, io_in[22], io_in[23], io_in[24], io_in[25], io_in[26], io_in[27], io_in[28], io_in[29], io_in[31], io_in[31], 20'b0} : @@ -436,11 +443,12 @@ 40'b0}; // Top shifted assign gpio_south = // I/O 32 to 37 - (gpio_input_slice == 0) ? // Distributed + (gpio_input_slice == 0) ? 30'b0 : // No pad input + (gpio_input_slice == 1) ? // Distributed {2'b0, io_in[37], 4'b0, io_in[36], 4'b0, io_in[35], 4'b0, io_in[34], 4'b0, io_in[33], 4'b0, io_in[32], 2'b0} : - (gpio_input_slice == 1) ? {14'b0, io_in[37:32]} : // Right shifted - (gpio_input_slice == 2) ? {7'b0, io_in[37:32], 7'b0} : // Centered + (gpio_input_slice == 2) ? {14'b0, io_in[37:32]} : // Right shifted + (gpio_input_slice == 3) ? {7'b0, io_in[37:32], 7'b0} : // Centered {io_in[37:32], 14'b0}; // Left shifted // East side @@ -633,7 +641,7 @@ end else if (direct_sel) begin rdata_pre = gpio_oeb; end else if (source_sel) begin - rdata_pre = {10'b0, gpio_output_slice, 2'b0, gpio_input_slice, + rdata_pre = {9'b0, gpio_output_slice, 1'b0, gpio_input_slice, 1'b0, north_loopback, 1'b0, east_loopback, 1'b0, south_loopback, 1'b0, west_loopback}; end else if (data_sel[0]) begin @@ -672,13 +680,12 @@ assign latched_in_south = latched_in[YSIZE+XSIZE-1:YSIZE]; assign latched_in_west = latched_in[YSIZE-1:0]; - /* Write data */ - always @(posedge wb_clk_i or posedge wb_rst_i) begin if (wb_rst_i) begin cell_addr <= 0; gpio_oeb <= 0; xfer_ctrl <= 0; + local_reset <= 0; west_loopback <= 0; east_loopback <= 0; north_loopback <= 0; @@ -692,7 +699,10 @@ write <= 1'b0; if (valid && !ready && wbs_adr_i[31:8] == BASE_ADR[31:8]) begin if (xfer_sel) begin - if (iomem_we[0]) xfer_ctrl <= wbs_dat_i[1:0]; + if (iomem_we[0]) begin + xfer_ctrl <= wbs_dat_i[1:0]; + local_reset <= wbs_dat_i[2]; + end end else if (config_sel[0]) begin if (iomem_we[0]) wdata[7:0] <= wbs_dat_i[7:0]; if (iomem_we[1]) wdata[15:8] <= wbs_dat_i[15:8]; @@ -724,8 +734,8 @@ north_loopback <= wbs_dat_i[6:4]; end if (iomem_we[2]) begin - gpio_input_slice <= wbs_dat_i[1:0]; - gpio_output_slice <= wbs_dat_i[5:4]; + gpio_input_slice <= wbs_dat_i[2:0]; + gpio_output_slice <= wbs_dat_i[6:4]; end end else if (data_sel[0]) begin if (iomem_we[0]) latched_in[7:0] <= wbs_dat_i[7:0]; @@ -755,6 +765,7 @@ end end else begin xfer_ctrl <= 0; // Immediately self-resetting + local_reset <= 0; // Immediately self-resetting end end end @@ -855,10 +866,10 @@ output [XSIZE-1:0] data_out_north, output [XSIZE-1:0] data_out_south ); - wire [XSIZE - 1: 0] uconn [YTOP: 0]; - wire [XSIZE - 1: 0] dconn [YTOP: 0]; - wire [YSIZE - 1: 0] rconn [XTOP: 0]; - wire [YSIZE - 1: 0] lconn [XTOP: 0]; + wire [XSIZE - 1: 0] uconn [YTOP: 0]; // Upward moving data + wire [XSIZE - 1: 0] dconn [YTOP: 0]; // Downward moving data + wire [YSIZE - 1: 0] rconn [XTOP: 0]; // Rightward moving data + wire [YSIZE - 1: 0] lconn [XTOP: 0]; // Leftward moving data wire [YTOP - 1: 0] shiftreg [XTOP: 0]; wire [YTOP - 1: 0] clkarray [XTOP: 0]; @@ -874,18 +885,18 @@ // |^|^ |^|^ |^|^ // v|v| v|v| v|v| // +------+ +------+ +------+ - // l->| |->| |->| |->l - // r<-| |<-| |<-| |<-r - // l->| |->| |->| |->l - // r<-| |<-| |<-| |<-r + // r->| |->| |->| |->r + // l<-| |<-| |<-| |<-l + // r->| |->| |->| |->r + // l<-| |<-| |<-| |<-l // +------+ +------+ +------+ // |^|^ |^|^ |^|^ // v|v| v|v| v|v| // +------+ +------+ +------+ - // l->| |->| |->| |->l - // r<-| |<-| |<-| |<-r - // l->| |->| |->| |->l - // r<-| |<-| |<-| |<-r + // r->| |->| |->| |->r + // l<-| |<-| |<-| |<-l + // r->| |->| |->| |->r + // l<-| |<-| |<-| |<-l // +------+ +------+ +------+ // |^|^ |^|^ |^|^ // v|v| v|v| v|v| @@ -918,10 +929,10 @@ assign data_out_east = rconn[XTOP][YSIZE - 1:0]; assign data_out_west = lconn[0][YSIZE - 1:0]; - assign dconn[YTOP][XSIZE - 1:0] = data_in_south; - assign uconn[0][XSIZE - 1:0] = data_in_north; - assign rconn[0][YSIZE - 1:0] = data_in_east; - assign lconn[XTOP][YSIZE - 1:0] = data_in_west; + assign dconn[YTOP][XSIZE - 1:0] = data_in_north; + assign uconn[0][XSIZE - 1:0] = data_in_south; + assign rconn[0][YSIZE - 1:0] = data_in_west; + assign lconn[XTOP][YSIZE - 1:0] = data_in_east; genvar i, j;