uart integrated into SOC
diff --git a/openlane/uart/base.sdc b/openlane/uart/base.sdc
new file mode 100644
index 0000000..1eab2c3
--- /dev/null
+++ b/openlane/uart/base.sdc
@@ -0,0 +1,34 @@
+set_units -time ns
+set ::env(CORE_CLOCK_PERIOD) "10"
+set ::env(CORE_CLOCK_PORT) "app_clk"
+
+######################################
+# WB Clock domain input output
+######################################
+create_clock [get_ports $::env(CORE_CLOCK_PORT)] -name $::env(CORE_CLOCK_PORT) -period $::env(CORE_CLOCK_PERIOD)
+set core_input_delay_value [expr $::env(CORE_CLOCK_PERIOD) * 0.6]
+set core_output_delay_value [expr $::env(CORE_CLOCK_PERIOD) * 0.6]
+puts "\[INFO\]: Setting wb output delay to:$core_output_delay_value"
+puts "\[INFO\]: Setting wb input delay to: $core_input_delay_value"
+
+
+set_input_delay 2.0 -clock [get_clocks $::env(CORE_CLOCK_PORT)] {arst_n}
+
+set_input_delay $core_input_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_cs*]
+set_input_delay $core_input_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_addr*]
+set_input_delay $core_input_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_wr*]
+set_input_delay $core_input_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_be*]
+set_input_delay $core_input_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_wdata*]
+
+
+set_output_delay $core_output_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_rdata*]
+set_output_delay $core_output_delay_value -clock [get_clocks $::env(CORE_CLOCK_PORT)] [get_port reg_ack*]
+
+
+
+# TODO set this as parameter
+set_driving_cell -lib_cell $::env(SYNTH_DRIVING_CELL) -pin $::env(SYNTH_DRIVING_CELL_PIN) [all_inputs]
+set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0]
+puts "\[INFO\]: Setting load to: $cap_load"
+set_load $cap_load [all_outputs]
+
diff --git a/openlane/uart/config.tcl b/openlane/uart/config.tcl
new file mode 100644
index 0000000..f0aea1f
--- /dev/null
+++ b/openlane/uart/config.tcl
@@ -0,0 +1,64 @@
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+set ::env(DESIGN_NAME) uart_core
+
+
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "app_clk"
+
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+ $script_dir/../../verilog/rtl/uart/src/uart_core.sv \
+ $script_dir/../../verilog/rtl/uart/src/uart_cfg.sv \
+ $script_dir/../../verilog/rtl/uart/src/uart_rxfsm.sv \
+ $script_dir/../../verilog/rtl/uart/src/uart_txfsm.sv \
+ $script_dir/../../verilog/rtl/lib/async_fifo_th.sv \
+ $script_dir/../../verilog/rtl/lib/reset_sync.sv \
+ "
+
+#set ::env(VERILOG_INCLUDE_DIRS) [glob $script_dir/../../verilog/rtl/sdram_ctrl/src/defs ]
+
+set ::env(SDC_FILE) "$script_dir/base.sdc"
+set ::env(BASE_SDC_FILE) "$script_dir/base.sdc"
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+set ::env(FP_SIZING) "absolute"
+set ::env(DIE_AREA) [list 0.0 0.0 100.0 100.0]
+
+
+
+
+set ::env(FP_PDN_VPITCH) 50
+set ::env(PDN_CFG) $script_dir/pdn.tcl
+
+set ::env(FP_VERTICAL_HALO) 6
+set ::env(PL_TARGET_DENSITY) 0.52
+set ::env(PL_TARGET_DENSITY_CELLS) 0.38
+set ::env(PL_OPENPHYSYN_OPTIMIZATIONS) 1
+set ::env(CELL_PAD) 4
+
+set ::env(GLB_RT_ADJUSTMENT) 0
+set ::env(GLB_RT_L2_ADJUSTMENT) 0.2
+set ::env(GLB_RT_L3_ADJUSTMENT) 0.25
+set ::env(GLB_RT_L4_ADJUSTMENT) 0.2
+set ::env(GLB_RT_L5_ADJUSTMENT) 0.1
+set ::env(GLB_RT_L6_ADJUSTMENT) 0.1
+set ::env(GLB_RT_TILES) 14
+set ::env(GLB_RT_MAXLAYER) 5
+
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
diff --git a/openlane/uart/pdn.tcl b/openlane/uart/pdn.tcl
new file mode 100644
index 0000000..1fe689b
--- /dev/null
+++ b/openlane/uart/pdn.tcl
@@ -0,0 +1,49 @@
+# 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
+
+# Power nets
+set ::power_nets $::env(VDD_PIN)
+set ::ground_nets $::env(GND_PIN)
+
+set ::macro_blockage_layer_list "li1 met1 met2 met3 met4 met5"
+
+pdngen::specify_grid stdcell {
+ name grid
+ rails {
+ met1 {width 0.48 pitch $::env(PLACE_SITE_HEIGHT) offset 0}
+ }
+ straps {
+ met4 {width 1.6 pitch $::env(FP_PDN_VPITCH) offset $::env(FP_PDN_VOFFSET)}
+ met5 {width 1.6 pitch $::env(FP_PDN_HPITCH) offset $::env(FP_PDN_HOFFSET)}
+ }
+ connect {{met1 met4} {met4 met5}}
+}
+
+pdngen::specify_grid macro {
+ power_pins "VPWR"
+ ground_pins "VGND"
+ blockages "li1 met1 met2 met3 met4"
+ straps {
+ }
+ connect {{met4_PIN_ver met5}}
+}
+
+set ::halo 5
+
+# POWER or GROUND #Std. cell rails starting with power or ground rails at the bottom of the core area
+set ::rails_start_with "POWER" ;
+
+# POWER or GROUND #Upper metal stripes starting with power or ground rails at the left/bottom of the core area
+set ::stripes_start_with "POWER" ;
diff --git a/openlane/uart/pin_order.cfg b/openlane/uart/pin_order.cfg
new file mode 100644
index 0000000..f7b568d
--- /dev/null
+++ b/openlane/uart/pin_order.cfg
@@ -0,0 +1,16 @@
+#BUS_SORT
+
+#N
+app_clk
+arst_n
+si
+so
+
+#S
+reg_cs
+reg_wr
+reg_addr.*
+reg_be
+reg_wdata.*
+reg_rdata.*
+reg_ack
diff --git a/verilog/dv/agents/uart_agent.v b/verilog/dv/agents/uart_agent.v
new file mode 100644
index 0000000..4c9d05d
--- /dev/null
+++ b/verilog/dv/agents/uart_agent.v
@@ -0,0 +1,321 @@
+
+module uart_agent (
+ mclk,
+ txd,
+ rxd
+ );
+
+input mclk;
+output txd;
+
+input rxd;
+
+event uart_read_done, uart_write_done;
+event error_detected,uart_parity_error, uart_stop_error1, uart_stop_error2;
+event uart_timeout_error;
+event abort;
+
+reg [15:0] rx_count;
+reg [15:0] tx_count;
+reg [15:0] par_err_count;
+reg [15:0] stop_err1_cnt;
+reg [15:0] stop_err2_cnt;
+reg [15:0] timeout_err_cnt;
+reg [15:0] err_cnt;
+
+reg txd, read, write;
+wire uart_rx_clk;
+reg uart_clk;
+reg stop_err_check;
+
+integer timeout_count;
+integer data_bit_number;
+reg [15:0] clk_count;
+
+reg error_ind; // 1 indicate error
+
+initial
+begin
+ txd = 1'b1;
+ uart_clk = 0;
+ clk_count = 0;
+ stop_err_check = 0;
+ error_ind = 0;
+end
+
+always @(posedge mclk)
+begin
+ if (clk_count == 'h0) begin
+ uart_clk = ~uart_clk;
+ clk_count = control_setup.divisor;
+ end else begin
+ clk_count = clk_count - 1;
+ end
+end
+assign uart_rx_clk = ~uart_clk;
+
+always @(posedge mclk)
+begin
+ timeout_count = timeout_count + 1;
+ if (timeout_count == (control_setup.maxtime * 16))
+ -> abort;
+end
+
+always @uart_read_done
+ rx_count = rx_count + 1;
+
+always @uart_write_done
+ tx_count = tx_count + 1;
+
+always @uart_parity_error begin
+ error_ind = 1;
+ par_err_count = par_err_count + 1;
+end
+
+always @uart_stop_error1 begin
+ error_ind = 1;
+ stop_err1_cnt = stop_err1_cnt + 1;
+end
+
+always @uart_stop_error2 begin
+ error_ind = 1;
+ stop_err2_cnt = stop_err2_cnt + 1;
+end
+
+always @uart_timeout_error begin
+ error_ind = 1;
+ timeout_err_cnt = timeout_err_cnt + 1;
+end
+
+
+always @error_detected begin
+ error_ind = 1;
+ err_cnt = err_cnt + 1;
+end
+
+
+////////////////////////////////////////////////////////////////////////////////
+task uart_init;
+begin
+ read = 0;
+ write = 0;
+ tx_count = 0;
+ rx_count = 0;
+ stop_err_check = 0;
+ par_err_count = 0;
+ stop_err1_cnt = 0;
+ stop_err2_cnt = 0;
+ timeout_err_cnt = 0;
+ err_cnt = 0;
+
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task read_char_chk;
+input expected_data;
+
+integer i;
+reg [7:0] expected_data;
+reg [7:0] data;
+reg parity;
+
+begin
+ data <= 8'h0;
+ parity <= 1;
+ timeout_count = 0;
+
+fork
+ begin : loop_1
+ @(abort)
+ $display ("%m: >>>>> Exceed time limit, uart no responce.\n");
+ ->uart_timeout_error;
+ disable loop_2;
+ end
+
+ begin : loop_2
+
+// start cycle
+ @(negedge rxd)
+ disable loop_1;
+ 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
+
+
+// wait another half cycle for tx_done signal
+ @(negedge uart_rx_clk);
+ read <= 0;
+ -> uart_read_done;
+
+ if (expected_data != data)
+ begin
+ $display ("%m: Error! Data return is %h, expecting %h", data, expected_data);
+ -> error_detected;
+ end
+ else
+ $display ("%m: Data match %h", expected_data);
+
+ $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1);
+ end
+join
+
+end
+
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task write_char;
+input [7:0] data;
+
+integer i;
+reg parity; // 0: odd parity, 1: even parity
+
+begin
+ parity <= #1 1;
+
+// start cycle
+ @(posedge uart_clk)
+ begin
+ txd <= #1 0;
+ write <= #1 1;
+ end
+
+// data cycle
+ begin
+ for (i = 0; i < data_bit_number; i = i + 1)
+ begin
+ @(posedge uart_clk)
+ txd <= #1 data[i];
+ parity <= parity ^ data[i];
+ end
+ end
+
+// parity cycle
+ if (control_setup.parity_en)
+ begin
+ @(posedge uart_clk)
+ txd <= #1
+// control_setup.stick_parity ? ~control_setup.even_odd_parity :
+ control_setup.even_odd_parity ? !parity : parity;
+ end
+
+// stop cycle 1
+ @(posedge uart_clk)
+ txd <= #1 stop_err_check ? 0 : 1;
+
+// stop cycle 2
+ @(posedge uart_clk);
+ txd <= #1 1;
+ if (data_bit_number == 5)
+ @(negedge uart_clk);
+ else if (control_setup.stop_bit_number)
+ @(posedge uart_clk);
+
+ write <= #1 0;
+ $display ("%m:... Write data %h to UART done cnt : %d ...\n", data,tx_count+1);
+ -> uart_write_done;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task control_setup;
+input [1:0] data_bit_set;
+input stop_bit_number;
+input parity_en;
+input even_odd_parity;
+input stick_parity;
+input [15:0] maxtime;
+input [15:0] divisor;
+
+begin
+ clk_count = divisor;
+ data_bit_number = data_bit_set + 5;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+task report_status;
+output [15:0] rx_nu;
+output [15:0] tx_nu;
+begin
+ $display ("-------------------- UART Reporting Configuration --------------------");
+ $display (" Data bit number setting is : %0d", data_bit_number);
+ $display (" Stop bit number setting is : %0d", control_setup.stop_bit_number + 1);
+ $display (" Divisor of Uart clock is : %0d", control_setup.divisor);
+ if (control_setup.parity_en)
+ $display (" Parity is enable");
+ else
+ $display (" Parity is disable");
+
+ if (control_setup.even_odd_parity)
+ $display (" Even parity setting");
+ else
+ $display (" Odd parity setting");
+
+
+ $display ("-----------------------------------------------------------------");
+
+ $display ("-------------------- Reporting Status --------------------\n");
+ $display (" Number of character received is : %d", rx_count);
+ $display (" Number of character sent is : %d", tx_count);
+ $display (" Number of parity error rxd is : %d", par_err_count);
+ $display (" Number of stop1 error rxd is : %d", stop_err1_cnt);
+ $display (" Number of stop2 error rxd is : %d", stop_err2_cnt);
+ $display (" Number of timeout error is : %d", timeout_err_cnt);
+ $display (" Number of error is : %d", err_cnt);
+ $display ("-----------------------------------------------------------------");
+
+ rx_nu = rx_count;
+ tx_nu = tx_count;
+end
+endtask
+
+
+////////////////////////////////////////////////////////////////////////////////
+endmodule
diff --git a/verilog/dv/user_uart/.user_uart.c.un~ b/verilog/dv/user_uart/.user_uart.c.un~
new file mode 100644
index 0000000..5835313
--- /dev/null
+++ b/verilog/dv/user_uart/.user_uart.c.un~
Binary files differ
diff --git a/verilog/dv/user_uart/Makefile b/verilog/dv/user_uart/Makefile
new file mode 100644
index 0000000..1ec201f
--- /dev/null
+++ b/verilog/dv/user_uart/Makefile
@@ -0,0 +1,83 @@
+# 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
+
+## Caravel Pointers
+CARAVEL_ROOT ?= ../../../caravel
+CARAVEL_PATH ?= $(CARAVEL_ROOT)
+CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel
+CARAVEL_VERILOG_PATH = $(CARAVEL_PATH)/verilog
+CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl
+CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel
+
+## User Project Pointers
+UPRJ_VERILOG_PATH ?= ../../../verilog
+UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl
+UPRJ_BEHAVIOURAL_MODELS = ../model
+UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes
+UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs
+
+## RISCV GCC
+GCC_PATH?=/ef/apps/bin
+GCC_PREFIX?=riscv64-unknown-elf
+PDK_PATH?=/ef/tech/SW/sky130A
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+
+.SUFFIXES:
+
+PATTERN = user_uart
+
+all: ${PATTERN:=.vcd}
+
+hex: ${PATTERN:=.hex}
+
+vvp: ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v %.hex
+ifeq ($(SIM),RTL)
+ iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) \
+ -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) \
+ $< -o $@
+else
+ iverilog -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \
+ -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \
+ -I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \
+ $< -o $@
+endif
+
+%.vcd: %.vvp
+ vvp $<
+
+%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s
+ ${GCC_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $<
+
+%.hex: %.elf
+ ${GCC_PREFIX}-objcopy -O verilog $< $@
+ # to fix flash base address
+ sed -i 's/@10000000/@00000000/g' $@
+
+%.bin: %.elf
+ ${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@
+
+# ---- Clean ----
+
+clean:
+ rm -f *.elf *.hex *.bin *.vvp *.vcd *.log
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_uart/run_iverilog b/verilog/dv/user_uart/run_iverilog
new file mode 100644
index 0000000..6f95c23
--- /dev/null
+++ b/verilog/dv/user_uart/run_iverilog
@@ -0,0 +1,20 @@
+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 -I $PDK_PATH -I ../ -I ../../../verilog/rtl -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $$CARAVEL_ROOT/verilog/dv/caravel -I ../model ../agents user_uart_tb.v -o user_uart_tb.vvp
+
+iverilog -g2005-sv -I $PDK_PATH -I ../ -I ../../../verilog/rtl -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_uart/uprj_netlists.v b/verilog/dv/user_uart/uprj_netlists.v
new file mode 100644
index 0000000..0aa46db
--- /dev/null
+++ b/verilog/dv/user_uart/uprj_netlists.v
@@ -0,0 +1,82 @@
+// 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 caravel global defines for the number of the user project IO pads
+`define USE_POWER_PINS
+
+ `include "spi_master/src/spim_top.sv"
+ `include "spi_master/src/spim_regs.sv"
+ `include "spi_master/src/spim_clkgen.sv"
+ `include "spi_master/src/spim_ctrl.sv"
+ `include "spi_master/src/spim_rx.sv"
+ `include "spi_master/src/spim_tx.sv"
+
+ `include "uart/src/uart_core.sv"
+ `include "uart/src/uart_cfg.sv"
+ `include "uart/src/uart_rxfsm.sv"
+ `include "uart/src/uart_txfsm.sv"
+ `include "lib/async_fifo_th.sv"
+ `include "lib/reset_sync.sv"
+
+ `include "sdram_ctrl/src/top/sdrc_top.v"
+ `include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
+ `include "lib/async_fifo.sv"
+ `include "sdram_ctrl/src/core/sdrc_core.v"
+ `include "sdram_ctrl/src/core/sdrc_bank_ctl.v"
+ `include "sdram_ctrl/src/core/sdrc_bank_fsm.v"
+ `include "sdram_ctrl/src/core/sdrc_bs_convert.v"
+ `include "sdram_ctrl/src/core/sdrc_req_gen.v"
+ `include "sdram_ctrl/src/core/sdrc_xfr_ctl.v"
+
+ `include "lib/registers.v"
+ `include "lib/clk_ctl.v"
+ `include "digital_core/src/glbl_cfg.sv"
+ `include "digital_core/src/digital_core.sv"
+
+ `include "lib/wb_stagging.sv"
+ `include "wb_interconnect/src/wb_arb.sv"
+ `include "wb_interconnect/src/wb_interconnect.sv"
+
+
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_hdu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_tdu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_ipic.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_csr.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_exu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ialu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_idu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_ifu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_lsu.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_mprf.sv"
+ `include "syntacore/scr1/src/core/pipeline/scr1_pipe_top.sv"
+ `include "syntacore/scr1/src/core/primitives/scr1_reset_cells.sv"
+ `include "syntacore/scr1/src/core/primitives/scr1_cg.sv"
+ `include "syntacore/scr1/src/core/scr1_clk_ctrl.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc_shift_reg.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc.sv"
+ `include "syntacore/scr1/src/core/scr1_tapc_synchronizer.sv"
+ `include "syntacore/scr1/src/core/scr1_core_top.sv"
+ `include "syntacore/scr1/src/core/scr1_dm.sv"
+ `include "syntacore/scr1/src/core/scr1_dmi.sv"
+ `include "syntacore/scr1/src/core/scr1_scu.sv"
+
+ `include "syntacore/scr1/src/top/scr1_dmem_router.sv"
+ `include "syntacore/scr1/src/top/scr1_dp_memory.sv"
+ `include "syntacore/scr1/src/top/scr1_tcm.sv"
+ `include "syntacore/scr1/src/top/scr1_timer.sv"
+ `include "syntacore/scr1/src/top/scr1_dmem_wb.sv"
+ `include "syntacore/scr1/src/top/scr1_imem_wb.sv"
+ `include "syntacore/scr1/src/top/scr1_top_wb.sv"
+ `include "lib/sync_fifo.sv"
diff --git a/verilog/dv/user_uart/user_uart.c b/verilog/dv/user_uart/user_uart.c
new file mode 100644
index 0000000..cb8c107
--- /dev/null
+++ b/verilog/dv/user_uart/user_uart.c
@@ -0,0 +1,43 @@
+
+#define SC_SIM_OUTPORT (0xf0000000)
+#define uint32_t long
+
+#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x30000000)
+#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x30000004)
+#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x30000008)
+#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x3000000C)
+#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x30000010)
+#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x30000014)
+#define reg_mprj_globl_reg6 (*(volatile uint32_t*)0x30000018)
+#define reg_mprj_globl_reg7 (*(volatile uint32_t*)0x3000001C)
+#define reg_mprj_globl_reg8 (*(volatile uint32_t*)0x30000020)
+#define reg_mprj_globl_reg9 (*(volatile uint32_t*)0x30000024)
+#define reg_mprj_globl_reg10 (*(volatile uint32_t*)0x30000028)
+#define reg_mprj_globl_reg11 (*(volatile uint32_t*)0x3000002C)
+#define reg_mprj_globl_reg12 (*(volatile uint32_t*)0x30000030)
+#define reg_mprj_globl_reg13 (*(volatile uint32_t*)0x30000034)
+#define reg_mprj_globl_reg14 (*(volatile uint32_t*)0x30000038)
+#define reg_mprj_globl_reg15 (*(volatile uint32_t*)0x3000003C)
+
+#define reg_mprj_uart_reg0 (*(volatile uint32_t*)0x30010000)
+#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x30010004)
+#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x30010008)
+#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x3001000C)
+#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x30010010)
+#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x30010014)
+#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x30010018)
+#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x3001001C)
+#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x30010020)
+
+int main()
+{
+
+ while(1) {
+ // Check UART RX fifo has data, if available loop back the data
+ if(reg_mprj_uart_reg8 != 0) {
+ reg_mprj_uart_reg5 = reg_mprj_uart_reg6;
+ }
+ }
+
+ return 0;
+}
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
new file mode 100644
index 0000000..84938f5
--- /dev/null
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -0,0 +1,423 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Standalone User validation Test bench ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// This is a standalone test bench to validate the ////
+//// Digital core. ////
+//// 1. User Risc core is booted using compiled code of ////
+//// user_risc_boot.c ////
+//// 2. User Risc core uses Serial Flash and SDRAM to boot ////
+//// 3. After successful boot, Risc core will check the UART ////
+//// RX Data, If it's available then it loop back the same ////
+//// data in uart tx ////
+//// 4. Test bench send random 40 character towards User uart ////
+//// and expect same data to return back ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, 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 none
+
+`timescale 1 ns / 1 ps
+
+`include "uprj_netlists.v"
+`include "spiflash.v"
+`include "mt48lc8m8a2.v"
+`include "uart_agent.v"
+
+
+`define ADDR_SPACE_UART = 32'h3001_0000;
+
+
+task user_uart_tb;
+
+reg clock ;
+reg RSTB ;
+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 ;
+//----------------------------------
+// Uart Configuration
+// ---------------------------------
+reg [1:0] uart_data_bit ;
+reg uart_stop_bits ; // 0: 1 stop bit; 1: 2 stop bit;
+reg uart_stick_parity ; // 1: force even parity
+reg uart_parity_en ; // parity enable
+reg uart_even_odd_parity ; // 0: odd parity; 1: even parity
+
+reg [7:0] uart_data ;
+reg [15:0] uart_divisor ; // divided by n * 16
+reg [15:0] uart_timeout ;// wait time limit
+
+reg [15:0] uart_rx_nu ;
+reg [15:0] uart_tx_nu ;
+reg [7:0] uart_write_data [0:39];
+reg uart_fifo_enable ; // fifo mode disable
+
+integer i,j;
+
+
+
+initial
+begin
+ uart_data_bit = 2'b11;
+ uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
+ uart_stick_parity = 0; // 1: force even parity
+ uart_parity_en = 0; // parity enable
+ uart_even_odd_parity = 1; // 0: odd parity; 1: even parity
+ uart_divisor = 15;// divided by n * 16
+ uart_timeout = 500;// wait time limit
+ uart_fifo_enable = 0; // fifo mode disable
+
+ #200; // Wait for reset removal
+ repeat (10) @(posedge clock);
+ $display("Monitor: Standalone User Risc Boot Test Started");
+
+ #1;
+ //------------ SDRAM Config - 2
+ wb_user_core_write('h3000_0014,'h100_019E);
+
+ repeat (2) @(posedge clock);
+ #1;
+ //------------ SDRAM Config - 1
+ wb_user_core_write('h3000_0010,'h2F17_2242);
+
+ repeat (2) @(posedge clock);
+ #1;
+ // Remove all the reset
+ wb_user_core_write('h3000_0000,'h7);
+
+ repeat (2000) @(posedge app_clk); // wait for Processor Get Ready
+ tb_uart.uart_init;
+ wb_user_core_write(`ADDR_SPACE_UART+8'h0,{3'h0,2'b00,1'b1,1'b1,1'b1});
+
+
+ for (i=0; i<40; i=i+1)
+ uart_write_data[i] = $random;
+
+
+ tb_top.tb_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity,
+ uart_stick_parity, uart_timeout, uart_divisor, uart_fifo_enable);
+
+ fork
+ begin
+ for (i=0; i<40; i=i+1)
+ begin
+ $display ("\n... UART Agent Writing char %x ...", write_data[i]);
+ tb_top.tb_uart.write_char (uart_write_data[i]);
+ end
+ end
+
+ begin
+ for (j=0; j<40; j=j+1)
+ begin
+ tb_top.tb_uart.read_char_chk(uart_write_data[j]);
+ end
+ end
+ join
+
+ #100
+ tb_top.tb_uart.report_status(rx_nu, tx_nu);
+
+ test_fail = 0;
+ wb_user_core_read(32'h30000018,read_data);
+
+ // Check
+ // if all the 40 byte transmitted
+ // if all the 40 byte received
+ // if no error
+ if(tx_nu != 40) test_fail = 1;
+ if(rx_nu != 40) test_fail = 1;
+ if(tb_top.tb_uart.err_cnt != 0) test_fail = 1;
+
+ $display("###################################################");
+ if(test_fail == 0) begin
+ `ifdef GL
+ $display("Monitor: Standalone User UART Test (GL) Passed");
+ `else
+ $display("Monitor: Standalone User UART Test (RTL) Passed");
+ `endif
+ end else begin
+ `ifdef GL
+ $display("Monitor: Standalone User UART Test (GL) Failed");
+ `else
+ $display("Monitor: Standalone User UART Test (RTL) Failed");
+ `endif
+ end
+ $display("###################################################");
+ #100
+ $finish;
+end
+
+
+digital_core u_core(
+`ifdef USE_POWER_PINS
+ .vdda1(), // User area 1 3.3V supply
+ .vdda2(), // User area 2 3.3V supply
+ .vssa1(), // User area 1 analog ground
+ .vssa2(), // User area 2 analog ground
+ .vccd1(), // User area 1 1.8V supply
+ .vccd2(), // User area 2 1.8v supply
+ .vssd1(), // User area 1 digital ground
+ .vssd2(), // User area 2 digital ground
+`endif
+ .wb_clk_i (clock), // System clock
+ .rtc_clk (1'b1), // Real-time clock
+ .wb_rst_i (RSTB), // Regular Reset signal
+
+ .wbd_ext_cyc_i (wbd_ext_cyc_i), // strobe/request
+ .wbd_ext_stb_i (wbd_ext_stb_i), // strobe/request
+ .wbd_ext_adr_i (wbd_ext_adr_i), // address
+ .wbd_ext_we_i (wbd_ext_we_i), // write
+ .wbd_ext_dat_i (wbd_ext_dat_i), // data output
+ .wbd_ext_sel_i (wbd_ext_sel_i), // byte enable
+
+ .wbd_ext_dat_o (wbd_ext_dat_o), // data input
+ .wbd_ext_ack_o (wbd_ext_ack_o), // acknowlegement
+ .wbd_ext_err_o (wbd_ext_err_o), // error
+
+
+ // Logic Analyzer Signals
+ .la_data_in ('0) ,
+ .la_data_out (),
+ .la_oenb ('0),
+
+
+ // IOs
+ .io_in (io_in) ,
+ .io_out (io_out) ,
+ .io_oeb (io_oeb) ,
+
+ .user_irq ()
+
+);
+
+//------------------------------------------------------
+// Integrate the Serial flash with qurd support to
+// user core using the gpio pads
+// ----------------------------------------------------
+
+ wire flash_clk = io_out[30];
+ wire flash_csb = io_out[31];
+ tri flash_io0 = (io_oeb[32]== 1'b0) ? io_out[32] : 1'bz;
+ tri flash_io1 = (io_oeb[33]== 1'b0) ? io_out[33] : 1'bz;
+ tri flash_io2 = (io_oeb[34]== 1'b0) ? io_out[34] : 1'bz;
+ tri flash_io3 = (io_oeb[35]== 1'b0) ? io_out[35] : 1'bz;
+
+ assign io_in[32] = flash_io0;
+ assign io_in[33] = flash_io1;
+ assign io_in[34] = flash_io2;
+ assign io_in[35] = flash_io3;
+
+
+ // Quard flash
+ spiflash #(
+ .FILENAME("user_uart.hex")
+ ) u_user_spiflash (
+ .csb(flash_csb),
+ .clk(flash_clk),
+ .io0(flash_io0),
+ .io1(flash_io1),
+ .io2(flash_io2),
+ .io3(flash_io3)
+ );
+
+
+//------------------------------------------------
+// Integrate the SDRAM 8 BIT Memory
+// -----------------------------------------------
+
+wire [7:0] Dq ; // SDRAM Read/Write Data Bus
+wire [0:0] sdr_dqm ; // SDRAM DATA Mask
+wire [1:0] sdr_ba ; // SDRAM Bank Select
+wire [12:0] sdr_addr ; // SDRAM ADRESS
+wire sdr_cs_n ; // chip select
+wire sdr_cke ; // clock gate
+wire sdr_ras_n ; // ras
+wire sdr_cas_n ; // cas
+wire sdr_we_n ; // write enable
+wire sdram_clk ;
+
+assign Dq[7:0] = (io_oeb[7:0] == 8'h0) ? io_out [7:0] : 8'hZZ;
+assign sdr_addr[12:0] = io_out [20:8] ;
+assign sdr_ba[1:0] = io_out [22:21] ;
+assign sdr_dqm[0] = io_out [23] ;
+assign sdr_we_n = io_out [24] ;
+assign sdr_cas_n = io_out [25] ;
+assign sdr_ras_n = io_out [26] ;
+assign sdr_cs_n = io_out [27] ;
+assign sdr_cke = io_out [28] ;
+assign sdram_clk = io_out [29] ;
+assign io_in[29] = sdram_clk;
+assign #(1) io_in[7:0] = Dq;
+
+// to fix the sdram interface timing issue
+wire #(1) sdram_clk_d = sdram_clk;
+
+ // SDRAM 8bit
+mt48lc8m8a2 #(.data_bits(8)) u_sdram8 (
+ .Dq (Dq ) ,
+ .Addr (sdr_addr[11:0] ),
+ .Ba (sdr_ba ),
+ .Clk (sdram_clk_d ),
+ .Cke (sdr_cke ),
+ .Cs_n (sdr_cs_n ),
+ .Ras_n (sdr_ras_n ),
+ .Cas_n (sdr_cas_n ),
+ .We_n (sdr_we_n ),
+ .Dqm (sdr_dqm )
+ );
+
+
+//---------------------------
+// UART Agent integration
+// --------------------------
+wire uart_txd,uart_rxd;
+
+assign uart_txd = io_out[37];
+assign io_in[36] = uart_rxd ;
+
+uart_agent tb_uart(
+ .mclk (clock ),
+ .txd (uart_rxd ),
+ .rxd (uart_txd )
+ );
+
+
+task wb_user_core_write;
+input [31:0] address;
+input [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h1; // write
+ wbd_ext_dat_i =data; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ repeat (1) @(posedge clock);
+ 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
+ $display("DEBUG WB USER ACCESS WRITE Address : %x, Data : %x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+task wb_user_core_read;
+input [31:0] address;
+output [31:0] data;
+reg [31:0] data;
+begin
+ repeat (1) @(posedge clock);
+ wbd_ext_adr_i =address; // address
+ wbd_ext_we_i ='h0; // write
+ wbd_ext_dat_i ='0; // data output
+ wbd_ext_sel_i ='hF; // byte enable
+ wbd_ext_cyc_i ='h1; // strobe/request
+ wbd_ext_stb_i ='h1; // strobe/request
+ wait(wbd_ext_ack_o == 1);
+ data = wbd_ext_dat_o;
+ repeat (1) @(posedge clock);
+ 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
+ $display("DEBUG WB USER ACCESS READ Address : %x, Data : %x",address,data);
+ repeat (2) @(posedge clock);
+end
+endtask
+
+
+
+
+////-----------------------------------------------------------------------------
+//// RISC IMEM amd DMEM Monitoring TASK
+////-----------------------------------------------------------------------------
+//logic [`SCR1_DMEM_AWIDTH-1:0] core2imem_addr_o_r; // DMEM address
+//logic [`SCR1_DMEM_AWIDTH-1:0] core2dmem_addr_o_r; // DMEM address
+//logic core2dmem_cmd_o_r;
+//
+//`define RISC_CORE user_uart_tb.u_core.u_riscv_top.i_core_top
+//
+//always@(posedge `RISC_CORE.clk) begin
+// if(`RISC_CORE.imem2core_req_ack_i && `RISC_CORE.core2imem_req_o)
+// core2imem_addr_o_r <= `RISC_CORE.core2imem_addr_o;
+//
+// if(`RISC_CORE.dmem2core_req_ack_i && `RISC_CORE.core2dmem_req_o) begin
+// core2dmem_addr_o_r <= `RISC_CORE.core2dmem_addr_o;
+// core2dmem_cmd_o_r <= `RISC_CORE.core2dmem_cmd_o;
+// end
+//
+// if(`RISC_CORE.imem2core_resp_i !=0)
+// $display("RISCV-DEBUG => IMEM ADDRESS: %x Read Data : %x Resonse: %x", core2imem_addr_o_r,`RISC_CORE.imem2core_rdata_i,`RISC_CORE.imem2core_resp_i);
+// if((`RISC_CORE.dmem2core_resp_i !=0) && core2dmem_cmd_o_r)
+// $display("RISCV-DEBUG => DMEM ADDRESS: %x Write Data: %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.core2dmem_wdata_o,`RISC_CORE.dmem2core_resp_i);
+// if((`RISC_CORE.dmem2core_resp_i !=0) && !core2dmem_cmd_o_r)
+// $display("RISCV-DEBUG => DMEM ADDRESS: %x READ Data : %x Resonse: %x", core2dmem_addr_o_r,`RISC_CORE.dmem2core_rdata_i,`RISC_CORE.dmem2core_resp_i);
+//end
+endmodule
+`default_nettype wire
diff --git a/verilog/rtl/digital_core/src/digital_core.sv b/verilog/rtl/digital_core/src/digital_core.sv
index 41fbf83..405df05 100644
--- a/verilog/rtl/digital_core/src/digital_core.sv
+++ b/verilog/rtl/digital_core/src/digital_core.sv
@@ -31,15 +31,18 @@
//// 4. buswidth warning are fixed inside spi_master ////
//// modified rtl files are ////
//// verilog/rtl/digital_core/src/digital_core.sv ////
-/// verilog/rtl/digital_core/src/glbl_cfg.sv ////
-/// verilog/rtl/lib/wb_stagging.sv ////
-/// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
-/// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
-/// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
-/// verilog/rtl/user_project_wrapper.v ////
-/// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
-/// verilog/rtl/spi_master/src/spim_clkgen.sv ////
-/// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// verilog/rtl/digital_core/src/glbl_cfg.sv ////
+//// verilog/rtl/lib/wb_stagging.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_dmem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_imem_wb.sv ////
+//// verilog/rtl/syntacore/scr1/src/top/scr1_top_wb.sv ////
+//// verilog/rtl/user_project_wrapper.v ////
+//// verilog/rtl/wb_interconnect/src/wb_interconnect.sv ////
+//// verilog/rtl/spi_master/src/spim_clkgen.sv ////
+//// verilog/rtl/spi_master/src/spim_ctrl.sv ////
+//// 0.3 - 20th June 2021, Dinesh A ////
+//// 1. uart core is integrated ////
+//// 2. 3rd Slave ported added to wishbone interconnect ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
@@ -188,6 +191,18 @@
logic wbd_glbl_ack_i; // acknowlegement
logic wbd_glbl_err_i; // error
+//---------------------------------------------------------------------
+// Global Register Wishbone Interface
+//---------------------------------------------------------------------
+logic wbd_uart_stb_o; // strobe/request
+logic [7:0] wbd_uart_adr_o; // address
+logic wbd_uart_we_o; // write
+logic [7:0] wbd_uart_dat_o; // data output
+logic wbd_uart_sel_o; // byte enable
+logic wbd_uart_cyc_o ;
+logic 7:0] wbd_uart_dat_i; // data input
+logic wbd_uart_ack_i; // acknowlegement
+logic wbd_uart_err_i; // error
//----------------------------------------------------
// CPU Configuration
@@ -200,6 +215,8 @@
logic [15:0] irq_lines ;
logic soft_irq ;
+ .si ( uart_rx ),
+ .so ( uart_tx )
//------------------------------------------------
// Configuration Parameter
//------------------------------------------------
@@ -296,12 +313,25 @@
assign io_oeb[34] = !spi_en_tx; // spi_dio2
assign io_oeb[35] = !spi_en_tx; // spi_dio3
+/////////////////////////////////////////////////////////
+// uart interface
+///////////////////////////////////////////////////////
+
+logic uart_rx ;
+logic uart_tx ;
// for uart
-assign io_oeb[36] = 1'b1; // Unused
-assign io_oeb[37] = 1'b1; // Unused
+assign io_oeb[36] = 1'b1; // Uart RX
+assign uart_rx = io_in[36];
+
+assign io_oeb[37] = 1'b0; // Uart TX
+assign io_out[37] = uart_tx;
+
+/////////////////////////////////////////////////////////
+// Generating acive low wishbone reset
+// //////////////////////////////////////////////////////
wire wb_rst_n = !wb_rst_i;
@@ -549,6 +579,17 @@
.s2_wbd_we_o (wbd_glbl_we_o ),
.s2_wbd_cyc_o (wbd_glbl_cyc_o ),
.s2_wbd_stb_o (wbd_glbl_stb_o )
+
+ // Slave 3 Interface
+ .s2_wbd_err_i (1'b0 ),
+ .s2_wbd_dat_i (wbd_uart_dat_i ),
+ .s2_wbd_ack_i (wbd_uart_ack_i ),
+ .s2_wbd_dat_o (wbd_uart_dat_o ),
+ .s2_wbd_adr_o (wbd_uart_adr_o ),
+ .s2_wbd_sel_o (wbd_uart_sel_o ),
+ .s2_wbd_we_o (wbd_uart_we_o ),
+ .s2_wbd_cyc_o (wbd_uart_cyc_o ),
+ .s2_wbd_stb_o (wbd_uart_stb_o )
);
glbl_cfg u_glbl_cfg (
@@ -607,6 +648,26 @@
);
+uart_core u_uart_core (
+ arst_n (wb_rst_n ), // async reset
+ app_clk (wb_clk_i ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (wbd_uart_stb_o ),
+ .reg_wr (wbd_uart_we_o ),
+ .reg_addr (wbd_uart_adr_o[5:2] ),
+ .reg_wdata (wbd_uart_dat_o[7:0] ),
+ .reg_be (wbd_uart_sel_o ),
+
+ // Outputs
+ .reg_rdata (wbd_uart_dat_i[7:0] ),
+ .reg_ack (wbd_uart_ack_i ),
+
+ // Line Interface
+ .si ( uart_rx ),
+ .so ( uart_tx )
+
+ );
endmodule : digital_core
diff --git a/verilog/rtl/lib/reset_sync.sv b/verilog/rtl/lib/reset_sync.sv
new file mode 100644
index 0000000..ea99a4a
--- /dev/null
+++ b/verilog/rtl/lib/reset_sync.sv
@@ -0,0 +1,83 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Active low reset synchronization ////
+//// ////
+//// This file is part of the yifive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description: ////
+//// Synchronize the active low reset to destination clock ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// v0: June 17, 2021, Dinesh A ////
+//// Initial version ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module reset_sync (
+ scan_mode ,
+ dclk , // Destination clock domain
+ arst_n , // active low async reset
+ srst_n
+ );
+
+parameter WIDTH = 1;
+
+input scan_mode ; // test mode
+input dclk ; // Destination clock
+input arst_n ; // Async Reset
+input srst_n ; // Sync Reset w.r.t dclk
+
+
+reg in_data_s ; // One Cycle sync
+reg in_data_2s ; // two Cycle sync
+
+assign srst_n = (scan_mode) ? arst_n : in_data_2s;
+
+always @(negedge arst_n or posedge dclk)
+begin
+ if(arst_n == 1'b0)
+ begin
+ in_data_s <= 1'b0;
+ in_data_2s <= 1'b0;
+ end
+ else
+ begin
+ in_data_s <= 1'b1;
+ in_data_2s <= in_data_s;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_cfg.sv b/verilog/rtl/uart/src/uart_cfg.sv
new file mode 100644
index 0000000..a979c77
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_cfg.sv
@@ -0,0 +1,387 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART Configuration ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// 0.2 - 20th June 2021, Dinesh A ////
+//// tx and rx buffer status added into reg7 and reg8 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_cfg (
+
+ mclk,
+ reset_n,
+
+ // Reg Bus Interface Signal
+ reg_cs,
+ reg_wr,
+ reg_addr,
+ reg_wdata,
+ reg_be,
+
+ // Outputs
+ reg_rdata,
+ reg_ack,
+
+ // Uart Tx fifo interface
+ tx_fifo_full,
+ tx_fifo_fspace,
+ tx_fifo_wr_en,
+ tx_fifo_data,
+
+ // Uart Rx fifo interface
+ rx_fifo_empty,
+ rx_fifo_dval ,
+ rx_fifo_rd_en,
+ rx_fifo_data ,
+
+ // configuration
+ cfg_tx_enable,
+ cfg_rx_enable,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+ cfg_baud_16x ,
+
+ frm_error_o,
+ par_error_o,
+ rx_fifo_full_err_o
+
+ );
+
+
+
+input mclk;
+input reset_n;
+
+//--------------------------------
+// Uart Tx fifo interface
+//--------------------------------
+input tx_fifo_full;
+input [4:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+output tx_fifo_wr_en;
+output [7:0] tx_fifo_data;
+
+//--------------------------------
+// Uart Rx fifo interface
+//--------------------------------
+input rx_fifo_empty;
+wire [4:0] rx_fifo_dval ; // Total Rx fifo Data Available
+output rx_fifo_rd_en;
+input [7:0] rx_fifo_data;
+
+//----------------------------------
+// configuration
+//----------------------------------
+output cfg_tx_enable ; // Tx Enable
+output cfg_rx_enable ; // Rx Enable
+output cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+output [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+output [11:0] cfg_baud_16x ; // 16x Baud clock config
+
+input frm_error_o ; // framing error
+input par_error_o ; // par error
+input rx_fifo_full_err_o ; // rx fifo full error
+
+//---------------------------------
+// Reg Bus Interface Signal
+//---------------------------------
+input reg_cs ;
+input reg_wr ;
+input [3:0] reg_addr ;
+input [7:0] reg_wdata ;
+input reg_be ;
+
+// Outputs
+output [7:0] reg_rdata ;
+output reg_ack ;
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+wire sw_rd_en;
+wire sw_wr_en;
+wire [3:0] sw_addr ; // addressing 16 registers
+wire wr_be ;
+
+reg [7:0] reg_rdata ;
+reg reg_ack ;
+
+wire [7:0] reg_0; // Software_Reg_0
+wire [7:0] reg_1; // Software-Reg_1
+wire [7:0] reg_2; // Software-Reg_2
+wire [7:0] reg_3; // Software-Reg_3
+wire [7:0] reg_4; // Software-Reg_4
+wire [7:0] reg_5; // Software-Reg_5
+wire [7:0] reg_6; // Software-Reg_6
+wire [7:0] reg_7; // Software-Reg_7
+wire [7:0] reg_8; // Software-Reg_8
+wire [7:0] reg_9; // Software-Reg_9
+wire [7:0] reg_10; // Software-Reg_10
+wire [7:0] reg_11; // Software-Reg_11
+wire [7:0] reg_12; // Software-Reg_12
+wire [7:0] reg_13; // Software-Reg_13
+wire [7:0] reg_14; // Software-Reg_14
+wire [7:0] reg_15; // Software-Reg_15
+reg [7:0] reg_out;
+
+//-----------------------------------------------------------------------
+// Main code starts here
+//-----------------------------------------------------------------------
+
+//-----------------------------------------------------------------------
+// Internal Logic Starts here
+//-----------------------------------------------------------------------
+ assign sw_addr = reg_addr [3:0];
+ assign sw_rd_en = reg_cs & !reg_wr;
+ assign sw_wr_en = reg_cs & reg_wr;
+ assign wr_be = reg_be;
+
+
+//-----------------------------------------------------------------------
+// Read path mux
+//-----------------------------------------------------------------------
+
+always @ (posedge mclk or negedge reset_n)
+begin : preg_out_Seq
+ if (reset_n == 1'b0)
+ begin
+ reg_rdata [7:0] <= 8'h00;
+ reg_ack <= 1'b0;
+ end
+ else if (sw_rd_en && !reg_ack)
+ begin
+ reg_rdata [7:0] <= reg_out [7:0];
+ reg_ack <= 1'b1;
+ end
+ else if (sw_wr_en && !reg_ack)
+ reg_ack <= 1'b1;
+ else
+ begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+wire sw_wr_en_12 = sw_wr_en & (sw_addr == 4'hC);
+wire sw_rd_en_12 = sw_rd_en & (sw_addr == 4'hC);
+wire sw_wr_en_13 = sw_wr_en & (sw_addr == 4'hD);
+wire sw_rd_en_13 = sw_rd_en & (sw_addr == 4'hD);
+wire sw_wr_en_14 = sw_wr_en & (sw_addr == 4'hE);
+wire sw_rd_en_14 = sw_rd_en & (sw_addr == 4'hE);
+wire sw_wr_en_15 = sw_wr_en & (sw_addr == 4'hF);
+wire sw_rd_en_15 = sw_rd_en & (sw_addr == 4'hF);
+
+
+always @( *)
+begin : preg_sel_Com
+
+ reg_out [7:0] = 8'd0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [7:0] = reg_0 [7:0];
+ 4'b0001 : reg_out [7:0] = reg_1 [7:0];
+ 4'b0010 : reg_out [7:0] = reg_2 [7:0];
+ 4'b0011 : reg_out [7:0] = reg_3 [7:0];
+ 4'b0100 : reg_out [7:0] = reg_4 [7:0];
+ 4'b0101 : reg_out [7:0] = reg_5 [7:0];
+ 4'b0110 : reg_out [7:0] = reg_6 [7:0];
+ 4'b0111 : reg_out [7:0] = reg_7 [7:0];
+ 4'b1000 : reg_out [7:0] = reg_8 [7:0];
+ 4'b1001 : reg_out [7:0] = reg_9 [7:0];
+ 4'b1010 : reg_out [7:0] = reg_10 [7:0];
+ 4'b1011 : reg_out [7:0] = reg_11 [7:0];
+ 4'b1100 : reg_out [7:0] = reg_12 [7:0];
+ 4'b1101 : reg_out [7:0] = reg_13 [7:0];
+ 4'b1110 : reg_out [7:0] = reg_14 [7:0];
+ 4'b1111 : reg_out [7:0] = reg_15 [7:0];
+ endcase
+end
+
+
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+// Logic for Register 0 : uart Control Register
+//-----------------------------------------------------------------------
+wire [1:0] cfg_pri_mod = reg_0[4:3]; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+wire cfg_stop_bit = reg_0[2]; // 0 -> 1 Stop, 1 -> 2 Stop
+wire cfg_rx_enable = reg_0[1]; // Rx Enable
+wire cfg_tx_enable = reg_0[0]; // Tx Enable
+
+generic_register #(5,0 ) u_uart_ctrl_be0 (
+ .we ({5{sw_wr_en_0 &
+ wr_be }} ),
+ .data_in (reg_wdata[4:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_0[4:0] )
+ );
+
+
+assign reg_0[7:5] = 3'h0;
+
+//-----------------------------------------------------------------------
+// Logic for Register 1 : uart interrupt status
+//-----------------------------------------------------------------------
+stat_register u_intr_bit0 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[0] ),
+ . hware_req (frm_error_o ),
+
+ //outputs
+ . data_out (reg_1[0] )
+ );
+
+stat_register u_intr_bit1 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[1] ),
+ . hware_req (par_error_o ),
+
+ //outputs
+ . data_out (reg_1[1] )
+ );
+
+stat_register u_intr_bit2 (
+ //inputs
+ . clk (mclk ),
+ . reset_n (reset_n ),
+ . cpu_we (sw_wr_en_1 &
+ wr_be ),
+ . cpu_ack (reg_wdata[2] ),
+ . hware_req (rx_fifo_full_err_o ),
+
+ //outputs
+ . data_out (reg_1[2] )
+ );
+
+assign reg_1[7:3] = 5'h0;
+
+
+//-----------------------------------------------------------------------
+// Logic for Register 2 : Baud Rate Control
+//-----------------------------------------------------------------------
+wire [11:0] cfg_baud_16x = {reg_3[3:0],reg_2[7:0]};
+
+generic_register #(8,0 ) u_uart_ctrl_reg2 (
+ .we ({8{sw_wr_en_2 &
+ wr_be }} ),
+ .data_in (reg_wdata[7:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_2[7:0] )
+ );
+
+generic_register #(4,0 ) u_uart_ctrl_reg3 (
+ .we ({4{sw_wr_en_3 &
+ wr_be }} ),
+ .data_in (reg_wdata[3:0] ),
+ .reset_n (reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_3[3:0] )
+ );
+
+assign reg_3[7:4] = 4'h0;
+
+
+// reg-4 status
+//
+assign reg_4[7:0] = {6'h0,rx_fifo_empty,tx_fifo_full};
+
+// reg_5 is tx_fifo wr
+assign tx_fifo_wr_en = sw_wr_en_5 & reg_ack & !tx_fifo_full;
+assign tx_fifo_data = reg_wdata[7:0];
+
+// reg_6 is rx_fifo read
+// rx_fifo read data
+assign reg_6[7:0] = {rx_fifo_data};
+assign rx_fifo_rd_en = sw_rd_en_6 & reg_ack & !rx_fifo_empty;
+
+assign reg_7[7:0] = {3'h0,tx_fifo_fspace}; // tx fifo free space
+assign reg_8[7:0] = {3'h0,rx_fifo_dval}; // rx fifo data available
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv
new file mode 100644
index 0000000..d318e3f
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_core.sv
@@ -0,0 +1,320 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART CORE with TX/RX 16 Byte Buffer ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_core
+
+ (
+
+ arst_n , // async reset
+ app_clk ,
+
+ // Reg Bus Interface Signal
+ reg_cs,
+ reg_wr,
+ reg_addr,
+ reg_wdata,
+ reg_be,
+
+ // Outputs
+ reg_rdata,
+ reg_ack,
+
+ // Line Interface
+ si,
+ so
+
+ );
+
+
+
+
+parameter W = 8'd8;
+parameter DP = 8'd16;
+parameter AW = (DP == 2) ? 1 :
+ (DP == 4) ? 2 :
+ (DP == 8) ? 3 :
+ (DP == 16) ? 4 :
+ (DP == 32) ? 5 :
+ (DP == 64) ? 6 :
+ (DP == 128) ? 7 :
+ (DP == 256) ? 8 : 0;
+
+
+
+input arst_n ; // async reset
+input app_clk ; // application clock
+
+//---------------------------------
+// Reg Bus Interface Signal
+//---------------------------------
+input reg_cs ;
+input reg_wr ;
+input [3:0] reg_addr ;
+input [7:0] reg_wdata ;
+input reg_be ;
+
+// Outputs
+output [7:0] reg_rdata ;
+output reg_ack ;
+
+// Line Interface
+input si ; // uart si
+output so ; // uart so
+
+// Wire Declaration
+wire app_reset_n ;
+wire line_reset_n ;
+
+wire [W-1: 0] tx_fifo_rd_data;
+wire [W-1: 0] rx_fifo_wr_data;
+wire [W-1: 0] app_rxfifo_data;
+wire [W-1: 0] app_txfifo_data;
+wire [1 : 0] error_ind;
+
+// Wire
+wire cfg_tx_enable ; // Tx Enable
+wire cfg_rx_enable ; // Rx Enable
+wire cfg_stop_bit ; // 0 -> 1 Stop, 1 -> 2 Stop
+wire [1:0] cfg_pri_mod ; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
+
+wire frm_error_o ; // framing error
+wire par_error_o ; // par error
+wire rx_fifo_full_err_o ; // rx fifo full error
+
+wire [11:0] cfg_baud_16x ; // 16x Baud clock generation
+wire rx_fifo_wr_full ;
+wire app_rxfifo_empty ;
+
+wire [AW:0] tx_fifo_fspace ; // Total Tx fifo Free Space
+wire [AW:0] rx_fifo_dval ; // Total Rx fifo Data Available
+
+uart_cfg u_cfg (
+
+ . mclk (app_clk),
+ . reset_n (app_reset_n),
+
+ // Reg Bus Interface Signal
+ . reg_cs (reg_cs),
+ . reg_wr (reg_wr),
+ . reg_addr (reg_addr),
+ . reg_wdata (reg_wdata),
+ . reg_be (reg_be),
+
+ // Outputs
+ . reg_rdata (reg_rdata),
+ . reg_ack (reg_ack),
+
+
+ // configuration
+ . cfg_tx_enable (cfg_tx_enable),
+ . cfg_rx_enable (cfg_rx_enable),
+ . cfg_stop_bit (cfg_stop_bit),
+ . cfg_pri_mod (cfg_pri_mod),
+
+ . cfg_baud_16x (cfg_baud_16x),
+
+ . tx_fifo_full (app_tx_fifo_full),
+ .tx_fifo_fspace (tx_fifo_fspace ),
+ . tx_fifo_wr_en (tx_fifo_wr_en),
+ . tx_fifo_data (app_txfifo_data),
+
+ . rx_fifo_empty (app_rxfifo_empty),
+ .rd_fifo_dval (rx_fifo_dval ),
+ . rx_fifo_rd_en (app_rxfifo_rd_en),
+ . rx_fifo_data (app_rxfifo_data) ,
+
+ . frm_error_o (frm_error_o),
+ . par_error_o (par_error_o),
+ . rx_fifo_full_err_o (rx_fifo_full_err_o)
+
+ );
+
+
+//##############################################################
+// 16x Baud clock generation
+// Example: to generate 19200 Baud clock from 50Mhz Link clock
+// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = 0xA0 (160)
+//###############################################################
+
+wire line_clk_16x;
+
+clk_ctl #(11) u_clk_ctl (
+ // Outputs
+ .clk_o (line_clk_16x),
+
+ // Inputs
+ .mclk (app_clk),
+ .reset_n (app_reset_n),
+ .clk_div_ratio (cfg_baud_16x)
+ );
+
+//###################################
+// Application Reset Synchronization
+//###################################
+reset_sync u_app_rst (
+ .scan_mode (1'b0 ),
+ .dclk (app_clk ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (app_reset_n )
+ );
+
+//###################################
+// Line Reset Synchronization
+//###################################
+reset_sync u_line_rst (
+ .scan_mode (1'b0 ),
+ .dclk (line_clk_16x ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (line_reset_n )
+ );
+
+
+uart_txfsm u_txfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ),
+
+ .cfg_tx_enable ( cfg_tx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ // FIFO control signal
+ .fifo_empty ( tx_fifo_rd_empty ),
+ .fifo_rd ( tx_fifo_rd ),
+ .fifo_data ( tx_fifo_rd_data ),
+
+ // Line Interface
+ .so ( so )
+ );
+
+
+uart_rxfsm u_rxfsm (
+ .reset_n ( line_reset_n ),
+ .baud_clk_16x ( line_clk_16x ) ,
+
+ .cfg_rx_enable ( cfg_rx_enable ),
+ .cfg_stop_bit ( cfg_stop_bit ),
+ .cfg_pri_mod ( cfg_pri_mod ),
+
+ .error_ind ( error_ind ),
+
+ // FIFO control signal
+ .fifo_aval ( !rx_fifo_wr_full ),
+ .fifo_wr ( rx_fifo_wr ),
+ .fifo_data ( rx_fifo_wr_data ),
+
+ // Line Interface
+ .si (si_ss )
+ );
+
+async_fifo_th #(W,DP,0,0) u_rxfifo (
+ .wr_clk (line_clk_16x ),
+ .wr_reset_n (line_reset_n ),
+ .wr_en (rx_fifo_wr ),
+ .wr_data (rx_fifo_wr_data ),
+ .full (rx_fifo_wr_full ), // sync'ed to wr_clk
+ .wr_total_free_space( ),
+
+ .rd_clk (app_clk ),
+ .rd_reset_n (app_reset_n ),
+ .rd_en (app_rxfifo_rd_en ),
+ .empty (app_rxfifo_empty ), // sync'ed to rd_clk
+ .rd_total_aval (rx_fifo_dval ),
+ .rd_data (app_rxfifo_data )
+ );
+
+async_fifo_th #(W,DP,0,0) u_txfifo (
+ .wr_clk (app_clk ),
+ .wr_reset_n (app_reset_n ),
+ .wr_en (tx_fifo_wr_en ),
+ .wr_data (app_txfifo_data ),
+ .full (app_tx_fifo_full ), // sync'ed to wr_clk
+ .wr_total_free_space(tx_fifo_fspace ),
+
+ .rd_clk (line_clk_16x ),
+ .rd_reset_n (line_reset_n ),
+ .rd_en (tx_fifo_rd ),
+ .empty (tx_fifo_rd_empty ), // sync'ed to rd_clk
+ .rd_total_aval ( ),
+ .rd_data (tx_fifo_rd_data )
+ );
+
+
+double_sync_low u_si_sync (
+ .in_data ( si ),
+ .out_clk (line_clk_16x ),
+ .out_rst_n (line_reset_n ),
+ .out_data (si_ss )
+ );
+
+wire frm_error = (error_ind == 2'b01);
+wire par_error = (error_ind == 2'b10);
+wire rx_fifo_full_err = (error_ind == 2'b11);
+
+double_sync_low u_frm_err (
+ .in_data ( frm_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( frm_error_o )
+ );
+
+double_sync_low u_par_err (
+ .in_data ( par_error ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( par_error_o )
+ );
+
+double_sync_low u_rxfifo_err (
+ .in_data ( rx_fifo_full_err ),
+ .out_clk ( app_clk ),
+ .out_rst_n ( app_reset_n ),
+ .out_data ( rx_fifo_full_err_o )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_rxfsm.sv b/verilog/rtl/uart/src/uart_rxfsm.sv
new file mode 100644
index 0000000..e7dea59
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_rxfsm.sv
@@ -0,0 +1,203 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART RX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+module uart_rxfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_rx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ error_ind ,
+
+ // FIFO control signal
+ fifo_aval ,
+ fifo_wr ,
+ fifo_data ,
+
+ // Line Interface
+ si
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_rx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+output [1:0] error_ind ; // 2'b00 --> Normal
+ // 2'b01 --> framing error
+ // 2'b10 --> parity error
+ // 2'b11 --> fifo full
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_aval ; // fifo empty
+output fifo_wr ; // fifo write, assumed no back to back write
+output [7:0] fifo_data ; // fifo write data
+
+// Line Interface
+input si ; // rxd pin
+
+
+
+reg [7:0] fifo_data ; // fifo write data
+reg fifo_wr ; // fifo write
+reg [1:0] error_ind ;
+reg [2:0] cnt ;
+reg [3:0] offset ; // free-running counter from 0 - 15
+reg [3:0] rxpos ; // stable rx position
+reg [2:0] rxstate ;
+
+parameter idle_st = 3'b000;
+parameter xfr_start = 3'b001;
+parameter xfr_data_st = 3'b010;
+parameter xfr_pri_st = 3'b011;
+parameter xfr_stop_st1 = 3'b100;
+parameter xfr_stop_st2 = 3'b101;
+
+
+always @(negedge reset_n or posedge baud_clk_16x) begin
+ if(reset_n == 0) begin
+ rxstate <= 3'b0;
+ offset <= 4'b0;
+ rxpos <= 4'b0;
+ cnt <= 3'b0;
+ error_ind <= 2'b0;
+ fifo_wr <= 1'b0;
+ fifo_data <= 8'h0;
+ end
+ else begin
+ offset <= offset + 1;
+ case(rxstate)
+ idle_st : begin
+ if(!si) begin // Start indication
+ if(fifo_aval && cfg_rx_enable) begin
+ rxstate <= xfr_start;
+ cnt <= 0;
+ rxpos <= offset + 8; // Assign center rxoffset
+ error_ind <= 2'b00;
+ end
+ else begin
+ error_ind <= 2'b11; // fifo full error indication
+ end
+ end else begin
+ error_ind <= 2'b00; // Reset Error
+ end
+ end
+ xfr_start : begin
+ // Make Sure that minimum 8 cycle low is detected
+ if(cnt < 7 && si) begin // Start indication
+ rxstate <= idle_st;
+ end
+ else if(cnt == 7 && !si) begin // Start indication
+ rxstate <= xfr_data_st;
+ cnt <= 0;
+ end else begin
+ cnt <= cnt +1;
+ end
+ end
+ xfr_data_st : begin
+ if(rxpos == offset) begin
+ fifo_data[cnt] <= si;
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ fifo_wr <= 1;
+ if(cfg_pri_mod == 2'b00) // No Priority
+ rxstate <= xfr_stop_st1;
+ else rxstate <= xfr_pri_st;
+ end
+ end
+ end
+ xfr_pri_st : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ if( si != ^fifo_data) error_ind <= 2'b10;
+ else // Odd Priority
+ if( si != ~(^fifo_data)) error_ind <= 2'b10;
+ rxstate <= xfr_stop_st1;
+ end
+ end
+ xfr_stop_st1 : begin
+ fifo_wr <= 0;
+ if(rxpos == offset) begin
+ if(si) begin
+ if(cfg_stop_bit) // Two Stop bit
+ rxstate <= xfr_stop_st2;
+ else
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ xfr_stop_st2 : begin
+ if(rxpos == offset) begin
+ if(si) begin
+ rxstate <= idle_st;
+ end else begin // Framing error
+ error_ind <= 2'b01;
+ rxstate <= idle_st;
+ end
+ end
+ end
+ default: rxstate <= idle_st;
+ endcase
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uart/src/uart_txfsm.sv b/verilog/rtl/uart/src/uart_txfsm.sv
new file mode 100644
index 0000000..fd8f947
--- /dev/null
+++ b/verilog/rtl/uart/src/uart_txfsm.sv
@@ -0,0 +1,172 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// UART TX FSM ////
+//// ////
+//// This file is part of the YIFive cores project ////
+//// http://www.opencores.org/cores/yifive/ ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 20th June 2021, Dinesh A ////
+//// 1. initial version picked from ////
+//// http://www.opencores.org/cores/oms8051mini ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+
+
+module uart_txfsm (
+ reset_n ,
+ baud_clk_16x ,
+
+ cfg_tx_enable ,
+ cfg_stop_bit ,
+ cfg_pri_mod ,
+
+ // FIFO control signal
+ fifo_empty ,
+ fifo_rd ,
+ fifo_data ,
+
+ // Line Interface
+ so
+ );
+
+
+input reset_n ; // active low reset signal
+input baud_clk_16x ; // baud clock-16x
+
+input cfg_tx_enable ; // transmit interface enable
+input cfg_stop_bit ; // stop bit
+ // 0 --> 1 stop, 1 --> 2 Stop
+input [1:0] cfg_pri_mod ;// Priority Mode
+ // 2'b00 --> None
+ // 2'b10 --> Even priority
+ // 2'b11 --> Odd priority
+
+//--------------------------------------
+// FIFO control signal
+//--------------------------------------
+input fifo_empty ; // fifo empty
+output fifo_rd ; // fifo read, assumed no back to back read
+input [7:0] fifo_data ; // fifo read data
+
+// Line Interface
+output so ; // txd pin
+
+
+reg [2:0] txstate ; // tx state
+reg so ; // txd pin
+reg [7:0] txdata ; // local txdata
+reg fifo_rd ; // Fifo read enable
+reg [2:0] cnt ; // local data cont
+reg [3:0] divcnt ; // clock div count
+
+parameter idle_st = 3'b000;
+parameter xfr_data_st = 3'b001;
+parameter xfr_pri_st = 3'b010;
+parameter xfr_stop_st1 = 3'b011;
+parameter xfr_stop_st2 = 3'b100;
+
+
+always @(negedge reset_n or posedge baud_clk_16x)
+begin
+ if(reset_n == 1'b0) begin
+ txstate <= idle_st;
+ so <= 1'b1;
+ cnt <= 3'b0;
+ txdata <= 8'h0;
+ fifo_rd <= 1'b0;
+ divcnt <= 4'b0;
+ end
+ else begin
+ divcnt <= divcnt+1;
+ if(divcnt == 4'b0000) begin // Do at once in 16 clock
+ case(txstate)
+ idle_st : begin
+ if(!fifo_empty && cfg_tx_enable) begin
+ so <= 1'b0 ; // Start bit
+ cnt <= 3'b0;
+ fifo_rd <= 1'b1;
+ txdata <= fifo_data;
+ txstate <= xfr_data_st;
+ end
+ end
+
+ xfr_data_st : begin
+ fifo_rd <= 1'b0;
+ so <= txdata[cnt];
+ cnt <= cnt+1;
+ if(cnt == 7) begin
+ if(cfg_pri_mod == 2'b00) begin // No Priority
+ txstate <= xfr_stop_st1;
+ end
+ else begin
+ txstate <= xfr_pri_st;
+ end
+ end
+ end
+
+ xfr_pri_st : begin
+ if(cfg_pri_mod == 2'b10) // even priority
+ so <= ^txdata;
+ else begin // Odd Priority
+ so <= ~(^txdata);
+ end
+ txstate <= xfr_stop_st1;
+ end
+
+ xfr_stop_st1 : begin // First Stop Bit
+ so <= 1;
+ if(cfg_stop_bit == 0) // 1 Stop Bit
+ txstate <= idle_st;
+ else // 2 Stop Bit
+ txstate <= xfr_stop_st2;
+ end
+
+ xfr_stop_st2 : begin // Second Stop Bit
+ so <= 1;
+ txstate <= idle_st;
+ end
+ default: txstate <= idle_st;
+ endcase
+ end
+ else begin
+ fifo_rd <= 1'b0;
+ end
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v
index 689eca3..33f2c1f 100644
--- a/verilog/rtl/uprj_netlists.v
+++ b/verilog/rtl/uprj_netlists.v
@@ -31,6 +31,13 @@
`include "spi_master/src/spim_rx.sv"
`include "spi_master/src/spim_tx.sv"
+ `include "uart/src/uart_core.sv"
+ `include "uart/src/uart_cfg.sv"
+ `include "uart/src/uart_rxfsm.sv"
+ `include "uart/src/uart_txfsm.sv"
+ `include "lib/async_fifo_th.sv"
+ `include "lib/reset_sync.sv"
+
`include "sdram_ctrl/src/top/sdrc_top.v"
`include "sdram_ctrl/src/wb2sdrc/wb2sdrc.v"
`include "lib/async_fifo.sv"
@@ -80,4 +87,5 @@
`include "syntacore/scr1/src/top/scr1_imem_wb.sv"
`include "syntacore/scr1/src/top/scr1_top_wb.sv"
`include "lib/sync_fifo.sv"
+
`endif
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
index 3eb688e..61f7f64 100644
--- a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
+++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -20,6 +20,8 @@
//// 0.2 - 17th June 2021, Dinesh A ////
//// Stagging FF added at Slave Interface to break ////
//// path ////
+//// 0.3 - 21th June 2021, Dinesh A ////
+//// slave port 3 added for uart ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
@@ -120,6 +122,18 @@
output logic s2_wbd_we_o,
output logic s2_wbd_cyc_o,
output logic s2_wbd_stb_o
+
+ // Slave 3 Interface
+ // Uart is 8bit interface
+ input logic [7:0] s3_wbd_dat_i,
+ input logic s3_wbd_ack_i,
+ input logic s3_wbd_err_i,
+ output logic [7:0] s3_wbd_dat_o,
+ output logic [7:0] s3_wbd_adr_o,
+ output logic s3_wbd_sel_o,
+ output logic s3_wbd_we_o,
+ output logic s3_wbd_cyc_o,
+ output logic s3_wbd_stb_o
);
////////////////////////////////////////////////////////////////////
@@ -161,11 +175,13 @@
type_wb_wr_intf s0_wb_wr;
type_wb_wr_intf s1_wb_wr;
type_wb_wr_intf s2_wb_wr;
+type_wb_wr_intf s3_wb_wr;
// Slave Read Interface
type_wb_rd_intf s0_wb_rd;
type_wb_rd_intf s1_wb_rd;
type_wb_rd_intf s2_wb_rd;
+type_wb_rd_intf s3_wb_rd;
type_wb_wr_intf m_bus_wr; // Multiplexed Master I/F
@@ -179,22 +195,26 @@
// 0x1000_0000 to 0x1000_00FF - SPI REGISTER
// 0x2000_0000 to 0x2FFF_FFFF - SDRAM
// 0x3000_0000 to 0x3000_00FF - GLOBAL REGISTER
+// 0x3000_0000 to 0x3001_00FF - UART Register
//-----------------------------
//
-wire [3:0] m0_wbd_tid_i = (m0_wbd_adr_i[31:28] == 4'b0000 ) ? 4'b0000 :
- (m0_wbd_adr_i[31:28] == 4'b0001 ) ? 4'b0000 :
- (m0_wbd_adr_i[31:28] == 4'b0010 ) ? 4'b0001 :
- (m0_wbd_adr_i[31:28] == 4'b0011 ) ? 4'b0010 : 4'b0000;
+wire [3:0] m0_wbd_tid_i = (m0_wbd_adr_i[31:28] == 4'b0000 ) ? 4'b0000 :
+ (m0_wbd_adr_i[31:28] == 4'b0001 ) ? 4'b0000 :
+ (m0_wbd_adr_i[31:28] == 4'b0010 ) ? 4'b0001 :
+ (m0_wbd_adr_i[31:16] == 16'h3000 ) ? 4'b0010 :
+ (m0_wbd_adr_i[31:16] == 16'h3001 ) ? 4'b0011 : 4'b0000;
-wire [3:0] m1_wbd_tid_i = (m1_wbd_adr_i[31:28] == 4'b0000 ) ? 4'b0000 :
- (m1_wbd_adr_i[31:28] == 4'b0001 ) ? 4'b0000 :
- (m1_wbd_adr_i[31:28] == 4'b0010 ) ? 4'b0001 :
- (m1_wbd_adr_i[31:28] == 4'b0011 ) ? 4'b0010 : 4'b0000;
+wire [3:0] m1_wbd_tid_i = (m1_wbd_adr_i[31:28] == 4'b0000 ) ? 4'b0000 :
+ (m1_wbd_adr_i[31:28] == 4'b0001 ) ? 4'b0000 :
+ (m1_wbd_adr_i[31:28] == 4'b0010 ) ? 4'b0001 :
+ (m1_wbd_adr_i[31:16] == 16'h3000 ) ? 4'b0010 :
+ (m1_wbd_adr_i[31:16] == 16'h3001 ) ? 4'b0011 : 4'b0000;
//-------------------------------------------------------------------
// EXTERNAL MEMORY MAP
// 0x3000_0000 to 0x3000_00FF - GLOBAL REGISTER
+// 0x3000_0000 to 0x3001_00FF - UART Register
// 0x4000_0000 to 0x4FFF_FFFF - SPI FLASH MEMORY
// 0x5000_0000 to 0x5000_00FF - SPI REGISTER
// 0x6000_0000 to 0x6FFF_FFFF - SDRAM
@@ -202,7 +222,8 @@
wire [3:0] m2_wbd_tid_i = (m2_wbd_adr_i[31:28] == 4'b0100 ) ? 4'b0000 :
(m2_wbd_adr_i[31:28] == 4'b0101 ) ? 4'b0000 :
(m2_wbd_adr_i[31:28] == 4'b0110 ) ? 4'b0001 :
- (m2_wbd_adr_i[31:28] == 4'b0011 ) ? 4'b0010 : 4'b0000;
+ (m2_wbd_adr_i[31:16] == 16'h3000 ) ? 4'b0010 :
+ (m2_wbd_adr_i[31:16] == 16'h3001 ) ? 4'b0011 : 4'b0000;
//----------------------------------------
// Master Mapping
@@ -267,6 +288,13 @@
assign s2_wbd_we_o = s2_wb_wr.wbd_we ;
assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ;
assign s2_wbd_stb_o = s2_wb_wr.wbd_stb ;
+
+ assign s3_wbd_dat_o = s3_wb_wr.wbd_dat[7:0] ;
+ assign s3_wbd_adr_o = s3_wb_wr.wbd_adr[7:0] ; // Global Reg Need 8 bit
+ assign s3_wbd_sel_o = s3_wb_wr.wbd_sel[0] ;
+ assign s3_wbd_we_o = s3_wb_wr.wbd_we ;
+ assign s3_wbd_cyc_o = s3_wb_wr.wbd_cyc ;
+ assign s3_wbd_stb_o = s3_wb_wr.wbd_stb ;
assign s0_wb_rd.wbd_dat = s0_wbd_dat_i ;
assign s0_wb_rd.wbd_ack = s0_wbd_ack_i ;
@@ -280,6 +308,9 @@
assign s2_wb_rd.wbd_ack = s2_wbd_ack_i ;
assign s2_wb_rd.wbd_err = s2_wbd_err_i ;
+ assign s3_wb_rd.wbd_dat = {24'h0,s3_wbd_dat_i} ;
+ assign s3_wb_rd.wbd_ack = s3_wbd_ack_i ;
+ assign s3_wb_rd.wbd_err = s3_wbd_err_i ;
//
// arbitor
@@ -314,6 +345,7 @@
3'h0: s_bus_rd = s0_wb_rd;
3'h1: s_bus_rd = s1_wb_rd;
3'h2: s_bus_rd = s2_wb_rd;
+ 3'h3: s_bus_rd = s3_wb_rd;
default: s_bus_rd = s0_wb_rd;
endcase
end
@@ -323,6 +355,7 @@
assign s0_wb_wr = (s_wbd_tid == 2'b00) ? s_bus_wr : 'h0;
assign s1_wb_wr = (s_wbd_tid == 2'b01) ? s_bus_wr : 'h0;
assign s2_wb_wr = (s_wbd_tid == 2'b10) ? s_bus_wr : 'h0;
+assign s3_wb_wr = (s_wbd_tid == 2'b11) ? s_bus_wr : 'h0;
// Connect Slave to Master
assign m0_wb_rd = (gnt == 2'b00) ? m_bus_rd : 'h0;