Rtl changes for uart Auto detect + PWM changes
diff --git a/openlane/Makefile b/openlane/Makefile index 14d5aac..c21989a 100644 --- a/openlane/Makefile +++ b/openlane/Makefile
@@ -43,7 +43,7 @@ @sleep 1 @if [ -f ./$*/interactive.tcl ]; then\ - docker run --rm \ + docker run --rm -v $(OPENLANE_ROOT):/openlane \ -v $(PDK_ROOT):$(PDK_ROOT) \ -v $(PWD)/..:$(PWD)/.. \ -v $(MCW_ROOT):$(MCW_ROOT) \ @@ -57,7 +57,7 @@ -u $(shell id -u $(USER)):$(shell id -g $(USER)) \ $(OPENLANE_IMAGE_NAME) sh -c $(OPENLANE_INTERACTIVE_COMMAND);\ else\ - docker run --rm \ + docker run --rm -v $(OPENLANE_ROOT):/openlane \ -v $(PDK_ROOT):$(PDK_ROOT) \ -v $(PWD)/..:$(PWD)/.. \ -v $(CARAVEL_ROOT):$(CARAVEL_ROOT) \
diff --git a/openlane/pinmux_top/base.sdc b/openlane/pinmux_top/base.sdc index 2aa686d..9c22d9c 100644 --- a/openlane/pinmux_top/base.sdc +++ b/openlane/pinmux_top/base.sdc
@@ -61,6 +61,10 @@ set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0] puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] + +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] ############################################################################### # Design Rules ###############################################################################
diff --git a/openlane/pinmux_top/config.tcl b/openlane/pinmux_top/config.tcl index 243f5e5..9326c1a 100755 --- a/openlane/pinmux_top/config.tcl +++ b/openlane/pinmux_top/config.tcl
@@ -45,19 +45,23 @@ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pinmux_top.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pinmux.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/glbl_reg.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/gpio_top.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/gpio_reg.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/gpio_intr.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pwm_top.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pwm_reg.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pwm.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/timer_top.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/timer_reg.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/timer.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_top.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_reg.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_intr.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_dglicth.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm_top.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm_core.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm_glbl_reg.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm_blk_reg.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm_cfg_dglitch.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/pwm/src/pwm.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/timer/src/timer_top.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/timer/src/timer_reg.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/timer/src/timer.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/semaphore_reg.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/ws281x_top.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/ws281x_driver.sv \ - $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/ws281x_reg.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/ws281x/src/ws281x_top.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/ws281x/src/ws281x_driver.sv \ + $::env(DESIGN_DIR)/../../verilog/rtl/ws281x/src/ws281x_reg.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/strap_ctrl.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/glbl_rst_reg.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/lib/pulse_gen_type1.sv \ @@ -88,7 +92,7 @@ set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg set ::env(FP_SIZING) absolute -set ::env(DIE_AREA) "0 0 500 750" +set ::env(DIE_AREA) "0 0 500 850" # If you're going to use multiple power domains, then keep this disabled. @@ -98,7 +102,7 @@ set ::env(PL_TIME_DRIVEN) 1 -set ::env(PL_TARGET_DENSITY) "0.36" +set ::env(PL_TARGET_DENSITY) "0.37" set ::env(CELL_PAD) "8" #set ::env(GRT_ADJUSTMENT) {0.2} @@ -135,6 +139,14 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1"
diff --git a/openlane/pinmux_top/pin_order.cfg b/openlane/pinmux_top/pin_order.cfg index e99154e..116c747 100644 --- a/openlane/pinmux_top/pin_order.cfg +++ b/openlane/pinmux_top/pin_order.cfg
@@ -72,6 +72,7 @@ e_reset_n p_reset_n s_reset_n +rtc_clk usb_clk strap_uartm\[1\] strap_uartm\[0\] @@ -304,8 +305,7 @@ #N -rtc_clk 000 0 4 -digital_io_oen\[37\] +digital_io_oen\[37\] 000 0 4 digital_io_out\[37\] digital_io_in\[37\] digital_io_oen\[36\]
diff --git a/openlane/qspim_top/base.sdc b/openlane/qspim_top/base.sdc index c0e8993..9322474 100644 --- a/openlane/qspim_top/base.sdc +++ b/openlane/qspim_top/base.sdc
@@ -283,6 +283,10 @@ set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0] puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] + +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] ############################################################################### # Design Rules ###############################################################################
diff --git a/openlane/qspim_top/config.tcl b/openlane/qspim_top/config.tcl index 4cdf315..c376278 100755 --- a/openlane/qspim_top/config.tcl +++ b/openlane/qspim_top/config.tcl
@@ -102,6 +102,14 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1"
diff --git a/openlane/uart_i2cm_usb_spi_top/base.sdc b/openlane/uart_i2cm_usb_spi_top/base.sdc index 3218d29..ae14897 100644 --- a/openlane/uart_i2cm_usb_spi_top/base.sdc +++ b/openlane/uart_i2cm_usb_spi_top/base.sdc
@@ -77,6 +77,12 @@ puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] + +############################################################################### + set ::env(SYNTH_TIMING_DERATE) 0.05 puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %" set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
diff --git a/openlane/uart_i2cm_usb_spi_top/config.tcl b/openlane/uart_i2cm_usb_spi_top/config.tcl index 86a397e..9870805 100644 --- a/openlane/uart_i2cm_usb_spi_top/config.tcl +++ b/openlane/uart_i2cm_usb_spi_top/config.tcl
@@ -128,6 +128,15 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} + set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" set ::env(QUIT_ON_LVS_ERROR) "1"
diff --git a/openlane/wb_host/base.sdc b/openlane/wb_host/base.sdc index 3c8cdc9..599dff4 100644 --- a/openlane/wb_host/base.sdc +++ b/openlane/wb_host/base.sdc
@@ -102,6 +102,11 @@ set cap_load [expr $::env(SYNTH_CAP_LOAD) / 1000.0] puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] + +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] + ############################################################################### # Design Rules ###############################################################################
diff --git a/openlane/wb_host/config.tcl b/openlane/wb_host/config.tcl index 08d18dd..f2b9028 100755 --- a/openlane/wb_host/config.tcl +++ b/openlane/wb_host/config.tcl
@@ -27,6 +27,8 @@ # Timing configuration set ::env(CLOCK_PERIOD) "10" set ::env(CLOCK_PORT) "wbm_clk_i wbs_clk_i u_uart2wb.u_core.u_uart_clk.genblk1.u_mux/X" +set ::env(CLOCK_NET) "wbm_clk_i wbs_clk_i u_uart2wb.u_core.u_uart_clk.genblk1.u_mux/X" +#set ::env(CLOCK_NET) "wbm_clk_i wbs_clk_i u_uart2wb.u_core.u_uart_clk.genblk1.u_mux/X u_uart2wb.u_arst_sync.u_buf.genblk1.u_mux/X" set ::env(SYNTH_MAX_FANOUT) 4 @@ -59,6 +61,7 @@ $::env(DESIGN_DIR)/../../verilog/rtl/uart2wb/src/uart2wb.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/uart2wb/src/uart2_core.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/uart2wb/src/uart_msg_handler.v \ + $::env(DESIGN_DIR)/../../verilog/rtl/uart2wb/src/uart_auto_det.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/sspis/src/sspis_top.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/sspis/src/sspis_if.sv \ $::env(DESIGN_DIR)/../../verilog/rtl/sspis/src/spi2wb.sv \ @@ -86,7 +89,7 @@ # If you're going to use multiple power domains, then keep this disabled. -set ::env(RUN_CVC) 1 +set ::env(RUN_CVC) 0 #set ::env(PDN_CFG) $script_dir/pdn.tcl @@ -114,6 +117,18 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} + + + + set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) "0" set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) "1" set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "1"
diff --git a/openlane/wb_interconnect/base.sdc b/openlane/wb_interconnect/base.sdc index d4e6271..9c402a4 100644 --- a/openlane/wb_interconnect/base.sdc +++ b/openlane/wb_interconnect/base.sdc
@@ -133,6 +133,11 @@ puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] + +############################################################################### set ::env(SYNTH_TIMING_DERATE) 0.05 puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %" set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}]
diff --git a/openlane/wb_interconnect/config.tcl b/openlane/wb_interconnect/config.tcl index 51f3ba1..58b9acb 100755 --- a/openlane/wb_interconnect/config.tcl +++ b/openlane/wb_interconnect/config.tcl
@@ -27,6 +27,7 @@ # Timing configuration set ::env(CLOCK_PERIOD) "10" set ::env(CLOCK_PORT) "clk_i" +set ::env(CLOCK_NET) "clk_i" set ::env(SYNTH_MAX_FANOUT) 4 @@ -98,7 +99,7 @@ ## Placement set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) 1 -set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 0 +set ::env(PL_RESIZER_TIMING_OPTIMIZATIONS) 1 set ::env(PL_RESIZER_MAX_SLEW_MARGIN) 2 set ::env(PL_RESIZER_MAX_CAP_MARGIN) 2 @@ -107,6 +108,14 @@ set ::env(GRT_ADJUSTMENT) 0.1 set ::env(DPL_CELL_PADDING) 1 +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} @@ -127,9 +136,6 @@ set ::env(PL_RESIZER_MAX_SLEW_MARGIN) "2.0" set ::env(PL_RESIZER_MAX_CAP_MARGIN) "5" -## FANOUT Reduced to take care of long routes -set ::env(SYNTH_MAX_FANOUT) "2" - set ::env(FP_PDN_VPITCH) 100 set ::env(FP_PDN_HPITCH) 100 set ::env(FP_PDN_VWIDTH) 6.2
diff --git a/openlane/ycr4_iconnect/base.sdc b/openlane/ycr4_iconnect/base.sdc index dd5e554..c1af415 100644 --- a/openlane/ycr4_iconnect/base.sdc +++ b/openlane/ycr4_iconnect/base.sdc
@@ -7,7 +7,7 @@ set_clock_transition 0.1500 [all_clocks] set_clock_uncertainty -setup 0.5000 [all_clocks] -set_clock_uncertainty -hold 0.2500 [all_clocks] +set_clock_uncertainty -hold 0.3000 [all_clocks] set ::env(SYNTH_TIMING_DERATE) 0.05 puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %" @@ -172,7 +172,7 @@ #Towards ycr_intf - dmem -set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req_ack}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req_ack}] set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_rdata[*]}] set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_resp[*]}] @@ -273,6 +273,10 @@ puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] + ############################################################################### # Design Rules ###############################################################################
diff --git a/openlane/ycr4_iconnect/config.tcl b/openlane/ycr4_iconnect/config.tcl index b687076..d7fb61d 100644 --- a/openlane/ycr4_iconnect/config.tcl +++ b/openlane/ycr4_iconnect/config.tcl
@@ -80,17 +80,25 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} -set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) "0" -set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) "1" -set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "1" -set ::env(PL_RESIZER_DESIGN_OPTIMIZATIONS) "1" +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} + set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" set ::env(QUIT_ON_LVS_ERROR) "1" set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" - set ::env(FP_PDN_VPITCH) 100 set ::env(FP_PDN_HPITCH) 100 set ::env(FP_PDN_VWIDTH) 6.2 set ::env(FP_PDN_HWIDTH) 6.2 + +#As tool has issue in fixing hold violation, temp enabled this +#set ::env(GLB_RESIZER_ALLOW_SETUP_VIOS) {1} +#set ::env(ECO_ENABLE) {0}
diff --git a/openlane/ycr_core_top/base.sdc b/openlane/ycr_core_top/base.sdc index f804cf0..874dabb 100644 --- a/openlane/ycr_core_top/base.sdc +++ b/openlane/ycr_core_top/base.sdc
@@ -34,7 +34,7 @@ #DMEM Constraints set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_cmd_o}] set_output_delay -max 8.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_req_o}] -set_output_delay -max 2.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_addr_o[*]}] +set_output_delay -max 7.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_addr_o[*]}] set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_wdata_o[*]}] set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2dmem_width_o[*]}] @@ -60,6 +60,9 @@ puts "\[INFO\]: Setting load to: $cap_load" set_load $cap_load [all_outputs] +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] ############################################################################### # Design Rules ###############################################################################
diff --git a/openlane/ycr_core_top/config.tcl b/openlane/ycr_core_top/config.tcl index a884490..cb42943 100644 --- a/openlane/ycr_core_top/config.tcl +++ b/openlane/ycr_core_top/config.tcl
@@ -92,6 +92,14 @@ #LVS Issue - DEF Base looks to having issue set ::env(MAGIC_EXT_USE_GDS) {1} +set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5} +set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5} + +set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25} +set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25} + +set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500} +set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500} set ::env(QUIT_ON_TIMING_VIOLATIONS) "0" set ::env(QUIT_ON_MAGIC_DRC) "1" @@ -99,7 +107,7 @@ set ::env(QUIT_ON_SLEW_VIOLATIONS) "0" #Need to cross-check why global timing opimization creating setup vio with hugh hold fix -set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "0" +set ::env(GLB_RESIZER_TIMING_OPTIMIZATIONS) "1" #PDN set ::env(FP_PDN_VPITCH) 100
diff --git a/signoff/digital_pll/OPENLANE_VERSION b/signoff/digital_pll/OPENLANE_VERSION new file mode 100644 index 0000000..b5bf449 --- /dev/null +++ b/signoff/digital_pll/OPENLANE_VERSION
@@ -0,0 +1 @@ +openlane b6bacc9d1ab469917fda7ceea61ea3a18984b818
diff --git a/signoff/digital_pll/PDK_SOURCES b/signoff/digital_pll/PDK_SOURCES new file mode 100644 index 0000000..f9d0f46 --- /dev/null +++ b/signoff/digital_pll/PDK_SOURCES
@@ -0,0 +1 @@ +open_pdks 44a43c23c81b45b8e774ae7a84899a5a778b6b0b
diff --git a/sta/scripts/ycr4_iconnect.tcl b/sta/scripts/ycr4_iconnect.tcl new file mode 100644 index 0000000..75e17ea --- /dev/null +++ b/sta/scripts/ycr4_iconnect.tcl
@@ -0,0 +1,83 @@ + + set ::env(USER_ROOT) ".." + set ::env(CARAVEL_ROOT) "/home/dinesha/workarea/efabless/MPW-7/caravel" + set ::env(CARAVEL_PDK_ROOT) "/opt/pdk_mpw7/sky130B" + + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_sram_macros/lib/sky130_sram_2kbyte_1rw1r_32x512_8_TT_1p8V_25C.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_sram_macros/lib/sky130_sram_1kbyte_1rw1r_32x256_8_TT_1p8V_25C.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_sc_hvl/lib/sky130_fd_sc_hvl__tt_025C_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_sc_hvl/lib/sky130_fd_sc_hvl__tt_025C_3v30_lv1v80.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_gpiov2_tt_tt_025C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_hvc_wpad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_lvc_wpad_tt_025C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_ground_lvc_wpad_tt_100C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_power_lvc_wpad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_fd_io__top_xres4v2_tt_tt_025C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__gpiov2_pad_tt_tt_025C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vdda_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssa_hvc_clamped_pad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped3_pad_tt_025C_1v80_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vccd_lvc_clamped3_pad_tt_025C_1v80_3v30_3v30.lib + read_liberty $::env(CARAVEL_PDK_ROOT)/libs.ref/sky130_fd_io/lib/sky130_ef_io__vssd_lvc_clamped_pad_tt_025C_1v80_3v30.lib + + # User project netlist + read_verilog $::env(USER_ROOT)/verilog/gl/ycr4_iconnect.v + + + link_design ycr4_iconnect + + + ## User Project Spef + read_spef $::env(USER_ROOT)/spef/ycr4_iconnect.spef + + + read_sdc -echo ./sdc/ycr4_iconnect.sdc + set_propagated_clock [all_clocks] + + check_setup -verbose > unconstraints.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 50 + report_checks -path_delay max -fields {slew cap input nets fanout} -format full_clock_expanded -group_count 50 + report_worst_slack -max + report_worst_slack -min + report_checks -path_delay min -fields {slew cap input nets fanout} -format full_clock_expanded -slack_max 0.18 -group_count 10 + report_check_types -max_slew -max_capacitance -max_fanout -violators > slew.cap.fanout.vio.rpt + + + #Delay check around imem + echo "imem Interface Min Timing.................." > imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2imem_cmd_o >> imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2imem_req_o >> imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through imem2core_req_ack_i >> imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2imem_addr_o[*] >> imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2imem_bl_o[*] >> imem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through imem2core_rdata_i[*] >> imem.min.rpt + + echo "imem Interface max Timing.................." > imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2imem_cmd_o >> imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2imem_req_o >> imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through imem2core_req_ack_i >> imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2imem_addr_o[*] >> imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2imem_bl_o[*] >> imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through imem2core_rdata_i[*] >> imem.max.rpt + + #Delay check around imem + echo "dmem Interface Min Timing.................." > dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2dmem_cmd_o >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2dmem_req_o >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through dmem2core_req_ack_i >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2dmem_addr_o[*] >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2dmem_wdata_o[*] >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through core2dmem_width_o[*] >> dmem.min.rpt + report_checks -path_delay min -fields {slew cap input nets fanout} -through dmem2core_rdata_i[*] >> dmem.min.rpt + + echo "imem Interface max Timing.................." > imem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2dmem_cmd_o >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2dmem_req_o >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through dmem2core_req_ack_i >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2dmem_addr_o[*] >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2dmem_wdata_o[*] >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through core2dmem_width_o[*] >> dmem.max.rpt + report_checks -path_delay max -fields {slew cap input nets fanout} -through dmem2core_rdata_i[*] >> dmem.max.rpt +
diff --git a/sta/sdc/caravel.sdc b/sta/sdc/caravel.sdc index ab8d910..047d5a6 100644 --- a/sta/sdc/caravel.sdc +++ b/sta/sdc/caravel.sdc
@@ -71,10 +71,10 @@ set_case_analysis 0 [get_pins {mprj/u_wb_host/cfg_cska_wh[1]}] set_case_analysis 1 [get_pins {mprj/u_wb_host/cfg_cska_wh[0]}] -set_case_analysis 1 [get_pins {mprj/u_intercon/cfg_cska_wi[3]}] -set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[2]}] -set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[0]}] -set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[1]}] +set_case_analysis 0 [get_pins {mprj/u_intercon/cfg_cska_wi[3]}] +set_case_analysis 1 [get_pins {mprj/u_intercon/cfg_cska_wi[2]}] +set_case_analysis 1 [get_pins {mprj/u_intercon/cfg_cska_wi[0]}] +set_case_analysis 1 [get_pins {mprj/u_intercon/cfg_cska_wi[1]}] #Keept the SRAM clock driving edge at pos edge set_case_analysis 0 [get_pins {mprj/u_riscv_top.u_intf/cfg_sram_lphase[0]}]
diff --git a/sta/sdc/ycr4_iconnect.sdc b/sta/sdc/ycr4_iconnect.sdc new file mode 100644 index 0000000..07dfb5a --- /dev/null +++ b/sta/sdc/ycr4_iconnect.sdc
@@ -0,0 +1,282 @@ +############################################################################### +# Timing Constraints +############################################################################### +create_clock -name core_clk -period 10.0000 [get_ports {core_clk}] +create_generated_clock -name sram0_clk0 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {sram0 clock-0} [get_ports sram0_clk0] +create_generated_clock -name sram0_clk1 -add -source [get_ports {core_clk}] -master_clock [get_clocks core_clk] -divide_by 1 -comment {sram0 clock-0} [get_ports sram0_clk1] + +set_clock_transition 0.1500 [all_clocks] +set_clock_uncertainty -setup 0.5000 [all_clocks] +set_clock_uncertainty -hold 0.2500 [all_clocks] + +set ::env(SYNTH_TIMING_DERATE) 0.05 +puts "\[INFO\]: Setting timing derate to: [expr {$::env(SYNTH_TIMING_DERATE) * 10}] %" +set_timing_derate -early [expr {1-$::env(SYNTH_TIMING_DERATE)}] +set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}] + + +## Debug bus +set_input_delay -max 4.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_debug[*]}] +set_input_delay -max 4.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_debug[*]}] +set_input_delay -max 4.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_debug[*]}] +set_input_delay -max 4.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_debug[*]}] + +set_input_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_debug[*]}] +set_input_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_debug[*]}] +set_input_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_debug[*]}] +set_input_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_debug[*]}] + +#CORE-0 IMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_bl[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_bl[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_imem_rdata[*]}] + +#CORE-0 DMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_wdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_width[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_wdata[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_width[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core0_dmem_rdata[*]}] + +#CORE-1 IMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_bl[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_bl[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_imem_rdata[*]}] + +#CORE-1 DMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_wdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_width[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_wdata[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_width[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core1_dmem_rdata[*]}] + +#CORE-2 IMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_bl[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_bl[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_imem_rdata[*]}] + +#CORE-2 DMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_wdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_width[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_wdata[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_width[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core2_dmem_rdata[*]}] + +#CORE-3 IMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_bl[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_bl[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_imem_rdata[*]}] + +#CORE-3 DMEM Constraints +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_cmd}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_req}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_addr[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_wdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_width[*]}] + +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_cmd}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_req}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_addr[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_wdata[*]}] +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_width[*]}] + +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_req_ack}] +set_output_delay -max 4.5000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_rdata[*]}] + +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_req_ack}] +set_output_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core3_dmem_rdata[*]}] + + +#Towards ycr_intf - dmem +set_input_delay -min 2.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req_ack}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_rdata[*]}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_resp[*]}] + +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req_ack}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_rdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_resp[*]}] + +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_cmd}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_width[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_addr[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_bl[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_wdata[*]}] + +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_req}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_cmd}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_width[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_addr[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_bl[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dmem_wdata[*]}] + +#Towards ycr_intf - icache +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_req_ack}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_rdata[*]}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_resp[*]}] + +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_req_ack}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_rdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_resp[*]}] + +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_req}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_cmd}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_width[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_addr[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_bl[*]}] + +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_req}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_cmd}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_width[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_addr[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_icache_bl[*]}] + +#Towards ycr_intf - dcache +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_req_ack}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_rdata[*]}] +set_input_delay -min 3.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_resp[*]}] + +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_req_ack}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_rdata[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_resp[*]}] + +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_req}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_cmd}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_width[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_addr[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_bl[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_wdata[*]}] + +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_req}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_cmd}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_width[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_addr[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_bl[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {core_clk}] -add_delay [get_ports {core_dcache_wdata[*]}] + +#SRAM Interface +#SRAM0-CLK0 +set_input_delay -min 2.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_dout0[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_dout0[*]}] + +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_csb0}] +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_web0}] +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_addr0[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_wmask0[*]}] +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_din0[*]}] + +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_csb0}] +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_web0}] +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_addr0[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_wmask0[*]}] +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk0}] -add_delay [get_ports {sram0_din0[*]}] + +#SRAM0-CLK1 +set_input_delay -min 2.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_dout1[*]}] +set_input_delay -max 6.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_dout1[*]}] + +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_csb1}] +set_output_delay -min 1.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_addr1[*]}] + +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_csb1}] +set_output_delay -max 6.0000 -clock [get_clocks {sram0_clk1}] -add_delay [get_ports {sram0_addr1[*]}] + +############################################################################### +# Environment +############################################################################### +set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} [all_inputs] +set cap_load 0.0334 +puts "\[INFO\]: Setting load to: $cap_load" +set_load $cap_load [all_outputs] + +set_max_transition 1.00 [current_design] +set_max_capacitance 0.2 [current_design] +set_max_fanout 10 [current_design] + +############################################################################### +# Design Rules +###############################################################################
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile index 238d50c..dabc09e 100644 --- a/verilog/dv/Makefile +++ b/verilog/dv/Makefile
@@ -19,14 +19,19 @@ .SUFFIXES: .SILENT: clean all -PATTERNS = user_basic user_uart user_uart1 user_risc_boot user_qspi user_sspi user_i2cm user_usb user_gpio user_aes user_spi_isp user_timer user_uart_master user_sram_exec user_cache_bypass user_pwm user_sema risc_boot uart_master wb_port arduino_arrays arduino_digital_port_control arduino_i2c_scaner arduino_risc_boot arduino_timer_intr arduino_ascii_table arduino_gpio_intr arduino_i2c_wr_rd arduino_string arduino_ws281x arduino_character_analysis arduino_hello_world arduino_multi_serial arduino_switchCase2 user_mcore_test1 user_mcore_test2 riscv_regress +PATTERNS = user_basic user_uart user_uart1 user_risc_boot user_qspi user_sspi user_i2cm user_usb user_gpio user_aes user_spi_isp user_timer user_uart_master user_sram_exec user_cache_bypass user_pwm user_sema risc_boot uart_master_test1 uart_master_test2 wb_port arduino_arrays arduino_digital_port_control arduino_i2c_scaner arduino_risc_boot arduino_timer_intr arduino_ascii_table arduino_gpio_intr arduino_i2c_wr_rd arduino_string arduino_ws281x arduino_character_analysis arduino_hello_world arduino_multi_serial arduino_switchCase2 user_mcore_test1 user_mcore_test2 all: ${PATTERNS} - echo "################# Test case Summary #####################" > regression.rpt + echo "################# RTL Test case Summary #####################" > regression.rpt xterm -e /usr/bin/watch -n 25 /bin/cat regression.rpt & for i in ${PATTERNS}; do \ - ( cd $$i && make | tee run.log && grep Monitor run.log | grep $$i >> ../regression.rpt) ; \ + ( cd $$i && make | tee run.rtl.log && grep Monitor run.rtl.log | grep $$i >> ../regression.rpt) ; \ done + #echo "################# GL Test case Summary #####################" >> regression.rpt + #\rm -rf */*.vvp + #for i in ${PATTERNS}; do \ + # ( cd $$i && make SIM=GL | tee run.gl.log && grep Monitor run.gl.log | grep $$i >> ../regression.rpt) ; \ + #done echo "################# End of Test case Summary #####################" >> regression.rpt DV_PATTERNS = $(foreach dv, $(PATTERNS), verify-$(dv))
diff --git a/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v b/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v index 5152893..b618915 100644 --- a/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v +++ b/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v
@@ -121,36 +121,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v b/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v index 275b18b..7f5b1c0 100644 --- a/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v +++ b/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v
@@ -150,35 +150,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - initial begin uart_data_bit = 2'b11;
diff --git a/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v b/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v index 23e360e..30797d1 100644 --- a/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v +++ b/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v
@@ -186,36 +186,6 @@ // Uart pins io_in[2], io_in[1] are excluded } = (u_top.p_reset_n == 0) ? 23'hZZ_ZZZZ: arduino_din; // Tri-state untill Strap pull completed - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - reg[7:0] pinmap[0:22]; //ardiono to gpio pinmaping initial begin
diff --git a/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v b/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v index 44b41db..d1141a8 100644 --- a/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v +++ b/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v
@@ -122,36 +122,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v b/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v index ace2a5b..72c3fbe 100644 --- a/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v +++ b/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v
@@ -127,36 +127,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v b/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v index 3c94c7d..40f9df8 100644 --- a/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v +++ b/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v
@@ -127,36 +127,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v b/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v index fc55f4c..45fe601 100644 --- a/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v +++ b/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v
@@ -121,36 +121,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v b/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v index c4b21ff..46e8d54 100644 --- a/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v +++ b/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v
@@ -157,7 +157,7 @@ end // SSPI Slave I/F -assign io_in[0] = 1'b1; // RESET +assign io_in[5] = 1'b1; // RESET assign io_in[16] = 1'b0 ; // SPIS SCK `ifndef GL // Drive Power for Hold Fix Buf
diff --git a/verilog/dv/arduino_string/arduino_string_tb.v b/verilog/dv/arduino_string/arduino_string_tb.v index a02727a..567a67c 100644 --- a/verilog/dv/arduino_string/arduino_string_tb.v +++ b/verilog/dv/arduino_string/arduino_string_tb.v
@@ -125,36 +125,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v b/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v index 3432fca..8493415 100644 --- a/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v +++ b/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v
@@ -150,36 +150,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - /************* Port-D Mapping ********************************** * Arduino-No * Pin-2 0 PD0/RXD[0] digital_io[6]
diff --git a/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v b/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v index ace0ce7..31ac5a0 100644 --- a/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v +++ b/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v
@@ -124,39 +124,6 @@ `endif - wire [15:0] irq_lines = u_top.u_pinmux.u_glbl_reg.irq_lines; - - - - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - initial begin
diff --git a/verilog/dv/common/agents/caravel_task.sv b/verilog/dv/common/agents/caravel_task.sv index 83a9c70..70ff764 100644 --- a/verilog/dv/common/agents/caravel_task.sv +++ b/verilog/dv/common/agents/caravel_task.sv
@@ -170,3 +170,33 @@ endgenerate + /************************************************************************* + * This is Baud Rate to clock divider conversion for Test Bench + * Note: DUT uses 16x baud clock, where are test bench uses directly + * baud clock, Due to 16x Baud clock requirement at RTL, there will be + * some resolution loss, we expect at lower baud rate this resolution + * loss will be less. For Quick simulation perpose higher baud rate used + * *************************************************************************/ + task tb_set_uart_baud; + input [31:0] ref_clk; + input [31:0] baud_rate; + output [31:0] baud_div; + reg [31:0] baud_div; + begin +// for 230400 Baud = (50Mhz/230400) = 216.7 +baud_div = ref_clk/baud_rate; // Get the Bit Baud rate +// Baud 16x = 216/16 = 13 + baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench +// Test bench baud clock , 16x of above value +// 13 * 16 = 208, +// (Note if you see original value was 216, now it's 208 ) + baud_div = baud_div * 16; +// Test bench half cycle counter to toggle it +// 208/2 = 104 + baud_div = baud_div/2; +//As counter run's from 0 , substract from 1 + baud_div = baud_div-1; + end + endtask + +
diff --git a/verilog/dv/common/agents/uart_master_tasks.sv b/verilog/dv/common/agents/uart_master_tasks.sv index cd0af94..e18eff4 100644 --- a/verilog/dv/common/agents/uart_master_tasks.sv +++ b/verilog/dv/common/agents/uart_master_tasks.sv
@@ -73,7 +73,7 @@ 8'd17 : data[3:0] = char2hex(read_data); endcase i = i+1; - $display("received Data: %x",data); + $display("received Data: 0x%x",data); end end @@ -119,9 +119,9 @@ i = i+1; end if(rxd_data == exp_data) begin - // $display("STATUS: ADDRESS: %x RXD: %x", addr,rxd_data); + $display("STATUS: ADDRESS: 0x%x RXD: 0x%x", addr,rxd_data); end else begin - $display("ERROR: ADDRESS: %x EXP: %x RXD: %x", addr,exp_data,rxd_data); + $display("ERROR: ADDRESS: 0x%x EXP: %x RXD: 0x%x", addr,exp_data,rxd_data); test_fail = 1; end
diff --git a/verilog/dv/common/agents/user_tasks.sv b/verilog/dv/common/agents/user_tasks.sv index 8365b6b..0ea83c8 100644 --- a/verilog/dv/common/agents/user_tasks.sv +++ b/verilog/dv/common/agents/user_tasks.sv
@@ -90,7 +90,7 @@ begin // Run in Fast Sim Mode `ifdef GL - force u_top.u_wb_host.u_reg._8654_.Q= 1'b1; + force u_top.u_wb_host._09718_.Q= 1'b1; `else force u_top.u_wb_host.u_reg.u_fastsim_buf.X = 1'b1; `endif @@ -421,6 +421,34 @@ end endtask + /************************************************************************* + * This is Baud Rate to clock divider conversion for Test Bench + * Note: DUT uses 16x baud clock, where are test bench uses directly + * baud clock, Due to 16x Baud clock requirement at RTL, there will be + * some resolution loss, we expect at lower baud rate this resolution + * loss will be less. For Quick simulation perpose higher baud rate used + * *************************************************************************/ + task tb_set_uart_baud; + input [31:0] ref_clk; + input [31:0] baud_rate; + output [31:0] baud_div; + reg [31:0] baud_div; + begin +// for 230400 Baud = (50Mhz/230400) = 216.7 +baud_div = ref_clk/baud_rate; // Get the Bit Baud rate +// Baud 16x = 216/16 = 13 + baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench +// Test bench baud clock , 16x of above value +// 13 * 16 = 208, +// (Note if you see original value was 216, now it's 208 ) + baud_div = baud_div * 16; +// Test bench half cycle counter to toggle it +// 208/2 = 104 + baud_div = baud_div/2; +//As counter run's from 0 , substract from 1 + baud_div = baud_div-1; + end + endtask /** `ifdef GL
diff --git a/verilog/dv/uart_master/Makefile b/verilog/dv/uart_master/Makefile deleted file mode 100644 index 12331ba..0000000 --- a/verilog/dv/uart_master/Makefile +++ /dev/null
@@ -1,232 +0,0 @@ -# SPDX-FileCopyrightText: 2020 Efabless Corporation -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# -# SPDX-License-Identifier: Apache-2.0 - - - -PWDD := $(shell pwd) -BLOCKS := $(shell basename $(PWDD)) - -# ---- Include Partitioned Makefiles ---- - -DESIGNS?=../../.. -CONFIG = caravel_user_project -TOOLS?=/opt/riscv32i/ - -######################################################## -#include $(MCW_ROOT)/verilog/dv/make/env.makefile -######################################################## -####################################################################### -## Global Environment Variables for local repo -####################################################################### - -export PDK_PATH = $(PDK_ROOT)/sky130A -export VIP_PATH = $(CORE_VERILOG_PATH)/dv/vip -export FIRMWARE_PATH = $(CORE_VERILOG_PATH)/dv/firmware - -####################################################################### -## Caravel Verilog for Integration Tests -####################################################################### - -export CARAVEL_VERILOG_PATH ?= $(CARAVEL_ROOT)/verilog -export CORE_VERILOG_PATH ?= $(CARAVEL_ROOT)/mgmt_core_wrapper/verilog -export USER_PROJECT_VERILOG ?= $(DESIGNS)/verilog - -export CARAVEL_PATH = $(CARAVEL_VERILOG_PATH) -export VERILOG_PATH = $(CORE_VERILOG_PATH) - -####################################################################### -## Compiler Information -####################################################################### - -export TOOLS ?= /opt/riscv32i -export GCC_PATH ?= $(TOOLS)/bin -GCC_PREFIX?=riscv32-unknown-elf - - - - - - - - -######################################################## -#include $(MCW_ROOT)/verilog/dv/make/var.makefile -######################################################## - -CPU=vexriscv -CPUFAMILY=riscv -CPUFLAGS=-march=rv32i -mabi=ilp32 -D__vexriscv__ -CPUENDIANNESS=little -CLANG=0 - - -###################################################### -# include $(MCW_ROOT)/verilog/dv/make/cpu.makefile -###################################################### - -ifeq ($(CPU),picorv32) - LINKER_SCRIPT=$(FIRMWARE_PATH)/sections.lds - SOURCE_FILES=$(FIRMWARE_PATH)/start.s - VERILOG_FILES= -endif - -ifeq ($(CPU),ibex) - LINKER_SCRIPT=$(FIRMWARE_PATH)/link_ibex.ld - SOURCE_FILES=$(FIRMWARE_PATH)/crt0_ibex.S $(FIRMWARE_PATH)/simple_system_common.c -# VERILOG_FILES=../ibex/* - VERILOG_FILES= -endif - -ifeq ($(CPU),vexriscv) -# LINKER_SCRIPT=$(FIRMWARE_PATH)/sections_vexriscv.lds -# SOURCE_FILES=$(FIRMWARE_PATH)/start_caravel_vexriscv.s - LINKER_SCRIPT=$(FIRMWARE_PATH)/sections.lds - SOURCE_FILES=$(FIRMWARE_PATH)/crt0_vex.S $(FIRMWARE_PATH)/isr.c - VERILOG_FILES= -endif - - - -##################################################### -#include $(MCW_ROOT)/verilog/dv/make/sim.makefile -###################################################### - -export IVERILOG_DUMPER = fst - -# RTL/GL/GL_SDF -SIM?=RTL -DUMP?=OFF - - -.SUFFIXES: - - -all: ${BLOCKS:=.vcd} ${BLOCKS:=.lst} - -hex: ${BLOCKS:=.hex} - -#.SUFFIXES: - -############################################################################## -# Comiple firmeware -############################################################################## -%.elf: %.c $(LINKER_SCRIPT) $(SOURCE_FILES) - ${GCC_PREFIX}-gcc -g \ - -I$(FIRMWARE_PATH) \ - -I$(VERILOG_PATH)/dv/generated \ - -I$(VERILOG_PATH)/dv/ \ - -I$(VERILOG_PATH)/common \ - $(CPUFLAGS) \ - -Wl,-Bstatic,-T,$(LINKER_SCRIPT),--strip-debug \ - -ffreestanding -nostdlib -o $@ $(SOURCE_FILES) $< - -%.lst: %.elf - ${GCC_PREFIX}-objdump -d -S $< > $@ - -%.hex: %.elf - ${GCC_PREFIX}-objcopy -O verilog $< $@ - # to fix flash base address - sed -ie 's/@10/@00/g' $@ - -%.bin: %.elf - ${GCC_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ - - -############################################################################## -# Runing the simulations -############################################################################## - -%.vvp: %_tb.v %.hex - -## RTL -ifeq ($(SIM),RTL) - ifeq ($(DUMP),OFF) - iverilog -g2005-sv -Ttyp -DFUNCTIONAL -DSIM -DUSE_POWER_PINS -DUNIT_DELAY=#0.1 \ - -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \ - -f$(VERILOG_PATH)/includes/includes.rtl.caravel \ - -o $@ $< - else - iverilog -g2005-sv -DWFDUMP -Ttyp -DFUNCTIONAL -DSIM -DUSE_POWER_PINS -DUNIT_DELAY=#0.1 \ - -f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \ - -f$(VERILOG_PATH)/includes/includes.rtl.caravel \ - -o $@ $< - endif -endif - -##GL -ifeq ($(SIM),GL) - ifeq ($(DUMP),OFF) - iverilog -Ttyp -DFUNCTIONAL -DGL -DUSE_POWER_PINS -DUNIT_DELAY=#0.1 \ - -f$(VERILOG_PATH)/includes/includes.gl.caravel \ - -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) -o $@ $< - else - iverilog -Ttyp -DWFDUMP -DFUNCTIONAL -DGL -DUSE_POWER_PINS -DUNIT_DELAY=#0.1 \ - -f$(VERILOG_PATH)/includes/includes.gl.caravel \ - -f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) -o $@ $< - endif -endif - -## GL+SDF -ifeq ($(SIM),GL_SDF) - ifeq ($(CONFIG),caravel_user_project) - cvc64 +interp \ - +define+SIM +define+FUNCTIONAL +define+GL +define+USE_POWER_PINS +define+UNIT_DELAY +define+ENABLE_SDF \ - +change_port_type +dump2fst +fst+parallel2=on +nointeractive +notimingchecks +mipdopt \ - -f $(VERILOG_PATH)/includes/includes.gl+sdf.caravel \ - -f $(USER_PROJECT_VERILOG)/includes/includes.gl+sdf.$(CONFIG) $< - else - cvc64 +interp \ - +define+SIM +define+FUNCTIONAL +define+GL +define+USE_POWER_PINS +define+UNIT_DELAY +define+ENABLE_SDF \ - +change_port_type +dump2fst +fst+parallel2=on +nointeractive +notimingchecks +mipdopt \ - -f $(VERILOG_PATH)/includes/includes.gl+sdf.$(CONFIG) \ - -f $CARAVEL_PATH/gl/__user_project_wrapper.v $< - endif -endif - -%.vcd: %.vvp - vvp $< - -# twinwave: RTL-%.vcd GL-%.vcd -# twinwave RTL-$@ * + GL-$@ * - -check-env: -ifndef PDK_ROOT - $(error PDK_ROOT is undefined, please export it before running make) -endif -ifeq (,$(wildcard $(PDK_ROOT)/sky130A)) - $(error $(PDK_ROOT)/sky130A not found, please install pdk before running make) -endif -ifeq (,$(wildcard $(GCC_PREFIX)-gcc )) - $(error $(GCC_PREFIX)-gcc is not found, please export GCC_PATH and GCC_PREFIX before running make) -endif -# check for efabless style installation -ifeq (,$(wildcard $(PDK_ROOT)/sky130A/libs.ref/*/verilog)) -SIM_DEFINES := ${SIM_DEFINES} -DEF_STYLE -endif - - -# ---- Clean ---- - -clean: - \rm -f *.elf *.hex *.bin *.vvp *.log *.vcd *.lst *.hexe - -.PHONY: clean hex all - - - - - -
diff --git a/verilog/dv/uart_master/run_verilog b/verilog/dv/uart_master/run_verilog deleted file mode 100644 index 5ffed3c..0000000 --- a/verilog/dv/uart_master/run_verilog +++ /dev/null
@@ -1,20 +0,0 @@ -# ////////////////////////////////////////////////////////////////////////////// -# // SPDX-FileCopyrightText: 2021, Dinesh Annayya -# // -# // 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 -# // SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> -# // ////////////////////////////////////////////////////////////////////////// - -#iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl -I ../../../verilog wb_port_tb.v -o wb_port.vvp -iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -DGL -I /home/dinesha/workarea/pdk/sky130A -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/dv/caravel -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog/rtl -I /home/dinesha/workarea/opencore/git/yifive_r0/caravel/verilog -I ../ -I../../../verilog/rtl -I../../../verilog/gl -I ../../../verilog wb_port_tb.v -o wb_port.vvp
diff --git a/verilog/dv/uart_master/uart_master.c b/verilog/dv/uart_master/uart_master.c deleted file mode 100644 index 991bdc5..0000000 --- a/verilog/dv/uart_master/uart_master.c +++ /dev/null
@@ -1,162 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2020 Efabless Corporation - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * SPDX-License-Identifier: Apache-2.0 - */ - -// This include is relative to $CARAVEL_PATH (see Makefile) -#include <defs.h> -#include <stub.c> - -// User Project Slaves (0x3000_0000) - - -#define GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP 0x1C00 - -#define SC_SIM_OUTPORT (0xf0000000) - -/* - RiscV Hello World test. - - Wake up the Risc V - - Boot from SPI Flash - - Riscv Write Hello World to SDRAM, - - External Wishbone read back validation the data -*/ -int i = 0; -int clk = 0; -int uart_cfg = 0; -void main() -{ - - //int bFail = 0; - /* - IO Control Registers - | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | - | 3-bits | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | 1-bit | - Output: 0000_0110_0000_1110 (0x1808) = GPIO_MODE_USER_STD_OUTPUT - | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | - | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | - - - Input: 0000_0001_0000_1111 (0x0402) = GPIO_MODE_USER_STD_INPUT_NOPULL - | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | - | 001 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | - - Input: 0000_0001_0000_1111 (0x1800) = GPIO_MODE_USER_STD_BIDIRECTIONAL - | DM | VTRIP | SLOW | AN_POL | AN_SEL | AN_EN | MOD_SEL | INP_DIS | HOLDH | OEB_N | MGMT_EN | - | 110 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | - */ - - /* Set up the housekeeping SPI to be connected internally so */ - /* that external pin changes don't affect it. */ - - //reg_spi_enable = 1; - //reg_wb_enable = 1; - // reg_spimaster_config = 0xa002; // Enable, prescaler = 2, - // connect to housekeeping SPI - - // Connect the housekeeping SPI to the SPI master - // so that the CSB line is not left floating. This allows - // all of the GPIO pins to be used for user functions. - - //reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; - //reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; - - // /* Apply configuration */ - //reg_mprj_xfer = 1; - //while (reg_mprj_xfer == 1); - - reg_la0_oenb = reg_la0_iena = 0xFFFFFFFF; // [31:0] - - // Flag start of the test - reg_mprj_datal = 0xAB600000; - - //----------------------------------------------------- - // Start of User Functionality and take over the GPIO Pins - // -------------------------------------------------------------------- - // User block decide on the GPIO function - // io[6] to 37 are set to default bio-direction using user_define.h file - //--------------------------------------------------------------------- - - //reg_mprj_io_37 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_36 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_35 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_34 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_33 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_32 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_31 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_30 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_29 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_28 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_27 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_26 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_25 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_24 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_23 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_22 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_21 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_20 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_19 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_18 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_17 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_16 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_15 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_14 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_13 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_12 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_11 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_10 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_9 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_8 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_7 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_6 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_5 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_4 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_3 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_2 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_1 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - //reg_mprj_io_0 = GPIO_MODE_USER_STD_BIDIRECTIONAL_PULLUP; - - // /* Apply configuration */ - //reg_mprj_xfer = 1; - //while (reg_mprj_xfer == 1); - - reg_la0_data = 0x000; - //reg_la0_data = 0x000; - //reg_la0_data |= 0x1; // bit[0] - Remove Software Reset - //reg_la0_data |= 0x1; // bit[1] - Enable Transmit Path - //reg_la0_data |= 0x2; // bit[2] - Enable Receive Path - //reg_la0_data |= 0x4; // bit[3] - Set 2 Stop Bit - //reg_la0_data |= 0x0; // bit[15:4] - 16x Baud Clock - //reg_la0_data |= 0x0; // bit[17:16] - Priority mode = 0 - reg_la0_data = 0x001; - reg_la0_data = 0x00F; - - - -}
diff --git a/verilog/dv/uart_master/uart_master_tb.v b/verilog/dv/uart_master/uart_master_tb.v deleted file mode 100644 index 2a99ff7..0000000 --- a/verilog/dv/uart_master/uart_master_tb.v +++ /dev/null
@@ -1,287 +0,0 @@ -// SPDX-FileCopyrightText: 2020 Efabless Corporation -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// SPDX-License-Identifier: Apache-2.0 - -`default_nettype none - -`timescale 1 ns / 1 ps -`include "uart_agent.v" - -`define TB_HEX "uart_master.hex" -`define TB_TOP uart_master_tb -module `TB_TOP; - reg clock; - reg RSTB; - reg CSB; - reg power1, power2; - reg power3, power4; - - wire gpio; - wire [37:0] mprj_io; - wire [7:0] mprj_io_0; - wire [15:0] checkbits; - -//---------------------------------- -// 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 - -reg [31:0] read_data ; -reg flag; -reg test_fail ; -reg [15:0] strap_in; - - - assign checkbits = mprj_io[31:16]; - - assign mprj_io[3] = (CSB == 1'b1) ? 1'b1 : 1'bz; - - // External clock is used by default. Make this artificially fast for the - // simulation. Normally this would be a slow clock and the digital PLL - // would be the fast clock. - - always #12.5 clock <= (clock === 1'b0); - - initial begin - clock = 0; - end - - `ifdef WFDUMP - initial begin - $dumpfile("simx.vcd"); - $dumpvars(2, `TB_TOP); - $dumpvars(0, `TB_TOP.tb_master_uart); - $dumpvars(0, `TB_TOP.u_top.mprj.u_wb_host.u_uart2wb); - $dumpvars(1, `TB_TOP.tb_master_uart); - $dumpvars(0, `TB_TOP.u_top.mprj.u_pinmux); - end - `endif - - initial begin - - // Repeat cycles of 1000 clock edges as needed to complete testbench - repeat (400) begin - repeat (10000) @(posedge clock); - // $display("+1000 cycles"); - end - $display("%c[1;31m",27); - $display ("##########################################################"); - `ifdef GL - $display ("Monitor: Timeout, %m (GL) Failed"); - `else - $display ("Monitor: Timeout, %m (RTL) Failed"); - `endif - $display ("##########################################################"); - $display("%c[0m",27); - $finish; - end - - initial begin - - strap_in = 0; - strap_in[`PSTRAP_UARTM_CFG] = 0; // uart master config control - load from LA - apply_strap(strap_in); - - 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 = 200;// wait time limit - uart_fifo_enable = 0; // fifo mode disable - tb_master_uart.debug_mode = 0; // disable debug display - - #200; // Wait for reset removal - - // wait(checkbits == 16'h AB60); - // $display("Monitor: UART Master Test Started"); - - repeat (10000) @(posedge clock); - tb_master_uart.uart_init; - tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, - uart_stick_parity, uart_timeout, uart_divisor); - //$write ("\n(%t)Response:\n",$time); - // Wait for Initial Command Format from the uart master - flag = 0; - while(flag == 0) - begin - tb_master_uart.read_char(read_data,flag); - $write ("%c",read_data); - end - - - - // Remove Wb Reset - uartm_reg_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1); - - repeat (2) @(posedge clock); - #1; - - $display("Monitor: Writing expected value"); - - test_fail = 0; - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,32'h11223344); - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_1,32'h22334455); - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_2,32'h33445566); - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_3,32'h44556677); - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_4,32'h55667788); - uartm_reg_write(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_5,32'h66778899); - - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,32'h11223344); - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_1,32'h22334455); - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_2,32'h33445566); - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_3,32'h44556677); - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_4,32'h55667788); - uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_5,32'h66778899); - - $display("###################################################"); - if(test_fail == 0) begin - `ifdef GL - $display("Monitor: %m (GL) Passed"); - `else - $display("Monitor: %m (RTL) Passed"); - `endif - end else begin - `ifdef GL - $display("Monitor: %m (GL) Failed"); - `else - $display("Monitor: %m (RTL) Failed"); - `endif - end - $display("###################################################"); - #100 - - $finish; - end - - initial begin - RSTB <= 1'b0; - //CSB <= 1'b1; // Force CSB high - #2000; - RSTB <= 1'b1; // Release reset - #170000; - //CSB = 1'b0; // CSB can be released - end - - initial begin // Power-up sequence - power1 <= 1'b0; - power2 <= 1'b0; - power3 <= 1'b0; - power4 <= 1'b0; - #100; - power1 <= 1'b1; - #100; - power2 <= 1'b1; - #100; - power3 <= 1'b1; - #100; - power4 <= 1'b1; - end - - //always @(mprj_io) begin - // #1 $display("MPRJ-IO state = %b ", mprj_io[7:0]); - //end - - wire flash_csb; - wire flash_clk; - wire flash_io0; - wire flash_io1; - - wire VDD3V3 = power1; - wire VDD1V8 = power2; - wire USER_VDD3V3 = power3; - wire USER_VDD1V8 = power4; - wire VSS = 1'b0; - - caravel u_top ( - .vddio (VDD3V3), - .vssio (VSS), - .vdda (VDD3V3), - .vssa (VSS), - .vccd (VDD1V8), - .vssd (VSS), - .vdda1 (USER_VDD3V3), - .vdda2 (USER_VDD3V3), - .vssa1 (VSS), - .vssa2 (VSS), - .vccd1 (USER_VDD1V8), - .vccd2 (USER_VDD1V8), - .vssd1 (VSS), - .vssd2 (VSS), - .clock (clock), - .gpio (gpio), - .mprj_io (mprj_io), - .flash_csb(flash_csb), - .flash_clk(flash_clk), - .flash_io0(flash_io0), - .flash_io1(flash_io1), - .resetb (RSTB) - ); - - spiflash #( - .FILENAME("uart_master.hex") - ) spiflash ( - .csb(flash_csb), - .clk(flash_clk), - .io0(flash_io0), - .io1(flash_io1), - .io2(), // not used - .io3() // not used - ); - - - - -`ifndef GL // Drive Power for Hold Fix Buf - // All standard cell need power hook-up for functionality work - initial begin - end -`endif - - -//--------------------------- -// UART Agent integration -// -------------------------- -wire uart_txd,uart_rxd; - -assign uart_txd = mprj_io[7]; -assign mprj_io[6] = uart_rxd ; - -uart_agent tb_master_uart( - .mclk (clock ), - .txd (uart_rxd ), - .rxd (uart_txd ) - ); - - -`include "caravel_task.sv" -`include "uart_master_tasks.sv" - -endmodule - -`default_nettype wire
diff --git a/verilog/dv/user_basic/user_basic_tb.v b/verilog/dv/user_basic/user_basic_tb.v index 2a1858d..feab774 100644 --- a/verilog/dv/user_basic/user_basic_tb.v +++ b/verilog/dv/user_basic/user_basic_tb.v
@@ -74,6 +74,7 @@ `timescale 1 ns/1 ps `include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v" +`include "uart_agent.v" `include "user_params.svh" `define TB_TOP user_basic_tb @@ -100,7 +101,6 @@ 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 wire clock_mon; @@ -109,8 +109,10 @@ wire [31:0] strap_sticky; reg [7:0] test_id; reg [25:0] bcount; +wire uart_txd,uart_rxd; +reg flag; -assign io_in = {26'h0,xtal_clk,11'h0}; +assign io_in = {26'h0,xtal_clk,4'h0,uart_rxd,6'h0}; wire [14:0] pstrap_select; @@ -317,7 +319,9 @@ $display("Step-5, Checking the uart Master baud-16x clock is 9600* 16"); test_id = 5; - apply_strap(16'h10); // [4] - // uart master config control - constant value based on system clock selection + strap_in = 0; + strap_in[`PSTRAP_UARTM_CFG] = 2'b01; // constant value based on system clock-50Mhz + apply_strap(strap_in); repeat (10) @(posedge clock); uartm_clock_monitor(6510); // 1/(9600*16) = 6510 ns, Assumption is user_clock1 = 40Mhz @@ -329,13 +333,97 @@ end $display("##########################################################"); + $display("##########################################################"); + $display("Step-6, Checking the uart Master Auto Detect Mode"); + test_id = 6; + strap_in = 0; + strap_in[`PSTRAP_UARTM_CFG] = 2'b00; // Auto Detect Mode + apply_strap(strap_in); + + tb_master_uart.uart_init; + uart_data_bit = 2'b11; + uart_stop_bits = 1; // 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 = 600;// wait time limit + uart_fifo_enable = 0; // fifo mode disable + tb_master_uart.debug_mode = 0; // disable debug display + tb_set_uart_baud(50000000,288000,uart_divisor);// 50Mhz Ref clock, Baud Rate: 288000 + tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, uart_stick_parity, uart_timeout, uart_divisor); + + repeat (10) @(posedge clock); + tb_master_uart.write_char(8'hA); // New line for auto detect + + repeat (10) @(posedge clock); + uartm_clock_monitor(200); // 1/(28800*16) = 217 ns - Adjusting 20ns (50Mhz) boundary => 200 + + // Wait for Initial command from uart master + flag = 0; + while(flag == 0) + begin + tb_master_uart.read_char(read_data,flag); + $write ("%c",read_data); + end + uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,CHIP_SIGNATURE); + + if(test_fail == 1) begin + $display("ERROR: Step-6, Checking the uart Master Auto Detect baud-28800 - FAILED"); + end else begin + $display("STATUS: Step-6, Checking the uart Master Auto Detect baud-28800 - PASSED"); + end + $display("##########################################################"); + + $display("##########################################################"); + $display("Step-7, Checking the uart Master Auto Detect Mode"); + test_id = 7; + + strap_in = 0; + strap_in[`PSTRAP_UARTM_CFG] = 2'b00; // Auto Detect Mode + apply_strap(strap_in); + + tb_master_uart.uart_init; + uart_data_bit = 2'b11; + uart_stop_bits = 1; // 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 = 600;// wait time limit + uart_fifo_enable = 0; // fifo mode disable + tb_master_uart.debug_mode = 0; // disable debug display + tb_set_uart_baud(50000000,38400,uart_divisor);// 50Mhz Ref clock, Baud Rate: 38400 + tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, uart_stick_parity, uart_timeout, uart_divisor); + + repeat (10) @(posedge clock); + tb_master_uart.write_char(8'hA); // New line for auto detect + + repeat (10) @(posedge clock); + uartm_clock_monitor(1620); // 1/(38400*16) = 1627.6 ns, Adjusting to 20ns boundary => 1620 + + // Wait for Initial command from uart master + flag = 0; + while(flag == 0) + begin + tb_master_uart.read_char(read_data,flag); + $write ("%c",read_data); + end + uartm_reg_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,CHIP_SIGNATURE); + + if(test_fail == 1) begin + $display("ERROR: Step-7, Checking the uart Master Auto Detect baud-38400 - FAILED"); + end else begin + $display("STATUS: Step-7, Checking the uart Master Auto Detect baud-38400 - PASSED"); + end + $display("##########################################################"); `ifndef GL $display("###################################################"); - $display("Step-5,Monitor: Checking the PLL:"); + $display("Step-8,Monitor: Checking the PLL:"); $display("###################################################"); - test_id = 5; + test_id = 8; // Set PLL enable, no DCO mode ; Set PLL output divider to 0x03 // Checking the expression // Internal PLL delay = 1.168 + 0.012 * $itor(bcount) @@ -361,18 +449,18 @@ pll_clock_monitor(5); */ if(test_fail == 1) begin - $display("ERROR: Step-5, Checking the PLL - FAILED"); + $display("ERROR: Step-8, Checking the PLL - FAILED"); end else begin - $display("STATUS: Step-5, Checking the PLL - PASSED"); + $display("STATUS: Step-8, Checking the PLL - PASSED"); end $display("##########################################################"); $display("###################################################"); - $display("Step-6,Monitor: PLL Monitor Clock output:"); + $display("Step-9,Monitor: PLL Monitor Clock output:"); $display("###################################################"); $display("Monitor: CPU: CLOCK2/(2+3), USB: CLOCK2/(2+9), RTC: CLOCK2/(2+255), WBS:CLOCK2/(2+4)"); - test_id = 6; + test_id = 9; test_step = 13; init(); repeat (10) @(posedge clock); @@ -384,34 +472,34 @@ dbg_clk_monitor(); if(test_fail == 1) begin - $display("ERROR: Step-6, PLL Monitor Clock output - FAILED"); + $display("ERROR: Step-9, PLL Monitor Clock output - FAILED"); end else begin - $display("STATUS: Step-6, PLL Monitor Clock output - PASSED"); + $display("STATUS: Step-9, PLL Monitor Clock output - PASSED"); end `endif $display("##########################################################"); - $display("Step-7,Monitor: Checking the chip signature :"); + $display("Step-10,Monitor: Checking the chip signature :"); $display("###################################################"); - test_id = 7; + test_id = 10; test_step = 14; // Remove Wb/PinMux Reset wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1); - wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,read_data,32'h8273_8343); - wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_1,read_data,32'h0709_2022); - wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_2,read_data,32'h0005_4000); + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_0,read_data,CHIP_SIGNATURE); + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_1,read_data,CHIP_RELEASE_DATE); + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_SOFT_REG_2,read_data,CHIP_REVISION); if(test_fail == 1) begin - $display("ERROR: Step-7,Monitor: Checking the chip signature - FAILED"); + $display("ERROR: Step-10,Monitor: Checking the chip signature - FAILED"); end else begin - $display("STATUS: Step-7,Monitor: Checking the chip signature - PASSED"); + $display("STATUS: Step-10,Monitor: Checking the chip signature - PASSED"); $display("##########################################################"); end end begin - repeat (30000) @(posedge clock); + repeat (500000) @(posedge clock); // $display("+1000 cycles"); test_fail = 1; end @@ -438,6 +526,19 @@ $finish; end +//--------------------------- +// UART Agent integration +// -------------------------- + +assign uart_txd = io_out[7]; +//assign io_in[6] = uart_rxd ; // Assigned at top-level + +uart_agent tb_master_uart( + .mclk (clock ), + .txd (uart_rxd ), + .rxd (uart_txd ) + ); + task clock_monitor2; @@ -521,7 +622,7 @@ begin //force clock_mon = u_top.u_wb_host.pll_clk_out[0]; `ifdef GL - force clock_mon = u_top.u_wb_host.pll_clk_out[0]; + force clock_mon = u_top.u_wb_host.int_pll_clock; `else force clock_mon = u_top.u_wb_host.int_pll_clock; @@ -534,7 +635,11 @@ task uartm_clock_monitor; input real exp_period; begin + `ifdef GL + force clock_mon = u_top.u_wb_host._09314_.Q; + `else force clock_mon = u_top.u_wb_host.u_uart2wb.u_core.line_clk_16x; + `endif check_clock_period("UART CLock",exp_period); release clock_mon; end @@ -615,5 +720,6 @@ +`include "uart_master_tasks.sv" endmodule `default_nettype wire
diff --git a/verilog/dv/user_gpio/user_gpio_tb.v b/verilog/dv/user_gpio/user_gpio_tb.v index 0efe8fe..1e313c4 100644 --- a/verilog/dv/user_gpio/user_gpio_tb.v +++ b/verilog/dv/user_gpio/user_gpio_tb.v
@@ -245,6 +245,9 @@ // Disable Multi func wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_MUTI_FUNC,'h000); + // config 1us based on system clock - 1000/25ns = 40 + wb_user_core_write(`ADDR_SPACE_TIMER+`TIMER_CFG_GLBL,39); + /************* GPIO As Output ******************/ $display("#####################################"); $display("Step-1: Testing GPIO As Output "); @@ -255,15 +258,15 @@ cmp_gpio_output(8'h55,8'h55,8'h55,8'h55); // Set the GPIO Output data: 0xAAAAAAAA - wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'hAAAAAAAA); + wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'hAAAAAAAA); cmp_gpio_output(8'hAA,8'hAA,8'hAA,8'hAA); // Set the GPIO Output data: 0x5A5A5A5A5A5A - wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'h5A5A5A5A); + wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'h5A5A5A5A); cmp_gpio_output(8'h5A,8'h5A,8'h5A,8'h5A); // Set the GPIO Output data: 0xA5A5A5A5A5A5 - wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'hA5A5A5A5); + wb_user_core_write(`ADDR_SPACE_GPIO+`GPIO_CFG_ODATA,'hA5A5A5A5); cmp_gpio_output(8'hA5,8'hA5,8'hA5,8'hA5); /************* GPIO As Input ******************/ @@ -324,9 +327,10 @@ // Drive GPIO with 0xA5 cmp_gpio_neg_intr(8'hA5,8'hA5,8'hA5,8'hA5); - repeat (200) @(posedge clock); + repeat (200) @(posedge clock); + check_fast_dglitch(); - + check_slow_dglitch(); repeat (100) @(posedge clock); // $display("+1000 cycles"); @@ -420,6 +424,7 @@ port_c_out = port_c; port_d_out = port_d; + repeat (200) @(posedge clock); // for de-glitch period wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); end endtask @@ -543,6 +548,143 @@ end endtask +// Check for slow De-Glitch (1us based sampling) +task check_slow_dglitch; +reg [7:0] port_a; +reg [7:0] port_b; +reg [7:0] port_c; +reg [7:0] port_d; +begin + $display("STATUS: Testing Slow De-Glitch Mode"); + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_CFG1,32'h0); + port_a = 8'hAA; + port_b = 8'hAA; + port_c = 8'hAA; + port_d = 8'hAA; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + + repeat (200) @(posedge clock); // for de-glitch period + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a_out = $random(); + port_b_out = $random(); + port_c_out = $random(); + port_d_out = $random(); + repeat (10) @(posedge clock); + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (10) @(posedge clock); + port_a_out = $random(); + port_b_out = $random(); + port_c_out = $random(); + port_d_out = $random(); + repeat (10) @(posedge clock); + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (10) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a = 8'h11; + port_b = 8'h22; + port_c = 8'h33; + port_d = 8'h44; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (200) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a = 8'h55; + port_b = 8'h66; + port_c = 8'h77; + port_d = 8'h88; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (200) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); +end +endtask + + +// Check for slow De-Glitch (system clock based sampling) +task check_fast_dglitch; +reg [7:0] port_a; +reg [7:0] port_b; +reg [7:0] port_c; +reg [7:0] port_d; +begin + $display("STATUS: Testing Fast De-Glitch Mode"); + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_CFG1,32'h100); + port_a = 8'h55; + port_b = 8'h55; + port_c = 8'h55; + port_d = 8'h55; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + + repeat (10) @(posedge clock); // for de-glitch period + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a_out = $random(); + port_b_out = $random(); + port_c_out = $random(); + port_d_out = $random(); + + repeat (2) @(posedge clock); + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (2) @(posedge clock); + + port_a_out = $random(); + port_b_out = $random(); + port_c_out = $random(); + port_d_out = $random(); + repeat (2) @(posedge clock); + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (2) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a = 8'h11; + port_b = 8'h22; + port_c = 8'h33; + port_d = 8'h44; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (10) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + + port_a = 8'h55; + port_b = 8'h66; + port_c = 8'h77; + port_d = 8'h88; + port_a_out = port_a; + port_b_out = port_b; + port_c_out = port_c; + port_d_out = port_d; + repeat (10) @(posedge clock); + wb_user_core_read_check(`ADDR_SPACE_GPIO+`GPIO_CFG_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,port_a & 8'h1F}); + +end +endtask endmodule `default_nettype wire
diff --git a/verilog/dv/user_mcore_test1/user_mcore_test1.c b/verilog/dv/user_mcore_test1/user_mcore_test1.c index 45136a5..8df1fbb 100644 --- a/verilog/dv/user_mcore_test1/user_mcore_test1.c +++ b/verilog/dv/user_mcore_test1/user_mcore_test1.c
@@ -29,23 +29,23 @@ // Multi-core test, Two Array is filled with below data, destination hold sum // source result remark // src0 src1 dest -// 0x00 0x0000 0x0000 updated by core-0 -// 0x11 0x1100 0x1111 updated by core-0 -// 0x22 0x2200 0x2222 updated by core-0 -// 0x33 0x3300 0x3333 updated by core-0 -// 0x44 0x4400 0x4444 updated by core-0 -// 0x55 0x5500 0x5555 updated by core-0 -// 0x66 0x6600 0x6666 updated by core-0 -// 0x77 0x7700 0x7777 updated by core-0 -// -// 0x88 0x8800 0x8888 updated by core-1 -// 0x99 0x9900 0x9999 updated by core-1 -// 0xAA 0xAA00 0xAAAA updated by core-1 -// 0xBB 0xBB00 0xBBBB updated by core-1 -// 0xCC 0xCC00 0xCCCC updated by core-1 -// 0xDD 0xDD00 0xDDDD updated by core-1 -// 0xEE 0xEE00 0xEEEE updated by core-1 -// 0xFF 0xFF00 0xFFFF updated by core-1 +// 0x0000 0x00000000 0x00000000 updated by core-0 +// 0x1111 0x11110000 0x11111111 updated by core-0 +// 0x2222 0x22220000 0x22222222 updated by core-0 +// 0x3333 0x33330000 0x33333333 updated by core-0 +// 0x4444 0x44440000 0x44444444 updated by core-1 +// 0x5555 0x55550000 0x55555555 updated by core-1 +// 0x6666 0x66660000 0x66666666 updated by core-1 +// 0x7777 0x77770000 0x77777777 updated by core-1 +// +// 0x8888 0x88880000 0x88888888 updated by core-2 +// 0x9999 0x99990000 0x99999999 updated by core-2 +// 0xAAAA 0xAAAA0000 0xAAAAAAAA updated by core-2 +// 0xBBBB 0xBBBB0000 0xBBBBBBBB updated by core-2 +// 0xCCCC 0xCCCC0000 0xCCCCCCCC updated by core-3 +// 0xDDDD 0xDDDD0000 0xDDDDDDDD updated by core-3 +// 0xEEEE 0xEEEE0000 0xEEEEEEEE updated by core-3 +// 0xFFFF 0xFFFF0000 0xFFFFFFFF updated by core-3 // // ------------------------------------------------------------------------- @@ -103,8 +103,10 @@ // Create two argument structures that include the array pointers and // what elements each core should process. - arg_t arg0 = { dest, src0, src1, 0, buf_size/2 }; - arg_t arg1 = { dest, src0, src1, buf_size/2, buf_size }; + arg_t arg0 = { dest, src0, src1, 0, buf_size/4 }; + arg_t arg1 = { dest, src0, src1, buf_size/4, buf_size/2 }; + arg_t arg2 = { dest, src0, src1, buf_size/2, (3*buf_size)/4 }; + arg_t arg3 = { dest, src0, src1, (3*buf_size)/4, buf_size }; reg_glbl_soft_reg_0 = 0x11223344; // Sig-0 // Initialize bare threads (bthread). @@ -118,6 +120,8 @@ // Spawn work onto core 1 bthread_spawn( 1, &vvadd_mt, &arg1 ); + bthread_spawn( 2, &vvadd_mt, &arg2 ); + bthread_spawn( 3, &vvadd_mt, &arg3 ); reg_glbl_soft_reg_2 = 0x33445566; // Sig-2 // Have core 0 also do some work. @@ -126,6 +130,8 @@ reg_glbl_soft_reg_3 = 0x44556677; // Sig-3 // Wait for core 1 to finish. bthread_join(1); + bthread_join(2); + bthread_join(3); // Stop counting stats
diff --git a/verilog/dv/user_mcore_test1/user_mcore_test1_tb.v b/verilog/dv/user_mcore_test1/user_mcore_test1_tb.v index d272b22..41db4aa 100644 --- a/verilog/dv/user_mcore_test1/user_mcore_test1_tb.v +++ b/verilog/dv/user_mcore_test1/user_mcore_test1_tb.v
@@ -101,8 +101,8 @@ repeat (2) @(posedge clock); #1; // Remove all the reset - $display("STATUS: Working with Both core Risc core 0 & 1 "); - wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_CFG0,'h31F); + $display("STATUS: Working with Both core Risc core 0/1/2/3 "); + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_CFG0,'hF1F); wait_riscv_boot();
diff --git a/verilog/dv/user_mcore_test2/user_mcore_test2_tb.v b/verilog/dv/user_mcore_test2/user_mcore_test2_tb.v index c6f6181..ba2f54e 100644 --- a/verilog/dv/user_mcore_test2/user_mcore_test2_tb.v +++ b/verilog/dv/user_mcore_test2/user_mcore_test2_tb.v
@@ -117,36 +117,6 @@ end `endif - /************************************************************************* - * This is Baud Rate to clock divider conversion for Test Bench - * Note: DUT uses 16x baud clock, where are test bench uses directly - * baud clock, Due to 16x Baud clock requirement at RTL, there will be - * some resolution loss, we expect at lower baud rate this resolution - * loss will be less. For Quick simulation perpose higher baud rate used - * *************************************************************************/ - task tb_set_uart_baud; - input [31:0] ref_clk; - input [31:0] baud_rate; - output [31:0] baud_div; - reg [31:0] baud_div; - begin - // for 230400 Baud = (50Mhz/230400) = 216.7 - baud_div = ref_clk/baud_rate; // Get the Bit Baud rate - // Baud 16x = 216/16 = 13 - baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench - // Test bench baud clock , 16x of above value - // 13 * 16 = 208, - // (Note if you see original value was 216, now it's 208 ) - baud_div = baud_div * 16; - // Test bench half cycle counter to toggle it - // 208/2 = 104 - baud_div = baud_div/2; - //As counter run's from 0 , substract from 1 - baud_div = baud_div-1; - end - endtask - - initial begin uart_data_bit = 2'b11; uart_stop_bits = 0; // 0: 1 stop bit; 1: 2 stop bit;
diff --git a/verilog/dv/user_pwm/user_pwm_tb.v b/verilog/dv/user_pwm/user_pwm_tb.v index 8d7a20a..b8bce21 100644 --- a/verilog/dv/user_pwm/user_pwm_tb.v +++ b/verilog/dv/user_pwm/user_pwm_tb.v
@@ -72,7 +72,7 @@ module user_pwm_tb; -parameter real CLK1_PERIOD = 25; +parameter real CLK1_PERIOD = 20; // 50Mhz parameter real CLK2_PERIOD = 2.5; parameter real IPLL_PERIOD = 5.008; parameter real XTAL_PERIOD = 6; @@ -81,14 +81,18 @@ - reg [31:0] OneMsPeriod; - integer test_step; + reg [31:0] pwm0_period; + reg [31:0] pwm1_period; + reg [31:0] pwm2_period; + reg [31:0] pwm3_period; + reg [31:0] pwm4_period; + reg [31:0] pwm5_period; + + reg [15:0] check_sum; + integer test_step,i; wire clock_mon; - initial begin - OneMsPeriod = 1000; - end `ifdef WFDUMP initial begin @@ -117,26 +121,627 @@ repeat (2) @(posedge clock); #1; - // Remove the reset - // Remove WB and SPI/UART Reset, Keep CORE under Reset - //wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_CFG0,'h01F); - - // config 1us based on system clock - 1000/25ns = 40 - wb_user_core_write(`ADDR_SPACE_TIMER+`TIMER_CFG_GLBL,39); - test_fail = 0; + check_sum = 0; repeat (200) @(posedge clock); wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_BANK_SEL,'h1000); // Change the Bank Sel 1000 - $display("Step-1, PWM-0: 1ms/2 = 500Hz; PWM-1: 1ms/3; PWM-2: 1ms/4, PWM-3: 1ms/5, PWM-4: 1ms/6, PWM-5: 1ms/7"); + $display("########################################"); + $display("Step-1, PWM Square Waveform"); test_step = 1; - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_0,'h0000_0000); - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_1,'h0000_0001); - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_2,'h0001_0001); - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_3,'h0001_0002); - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_4,'h0002_0002); - wb_user_core_write(`ADDR_SPACE_PWM+`PWM_CFG_PWM_5,'h0002_0003); - pwm_monitor(OneMsPeriod*2,OneMsPeriod*3,OneMsPeriod*4,OneMsPeriod*5,OneMsPeriod*6,OneMsPeriod*7); + pwm0_period = 20*256; + pwm1_period = 20*2*256; + pwm2_period = 20*4*256; + pwm3_period = 20*256; // pwm3 is connected to pwm0 + pwm4_period = 20*2*256; // pwm4 is connected to pwm1 + pwm5_period = 20*4*256; // pwm5 is conneted to pwm2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_8000); // No Scale + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_8001); // Scale 2^1 = 2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_8002); // Scale 2^2 = 4 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h0000_007F); // COMP0 = 0xFF + + // PWm3 to 5 Removed + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK3_CFG0,'h0000_8003); // Scale 2^3 = 8 + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK3_CFG1,'h0000_00FF); // Period 0xFFFF + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK3_CFG2,'h0000_007F); // COMP0 = 0xFF + + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK4_CFG0,'h0000_8004); // Scale 2^4 = 16 + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK4_CFG1,'h0000_00FF); // Period 0xFFFF + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK4_CFG2,'h0000_007F); // COMP0 = 0xFF + + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK5_CFG0,'h0000_8005); // Scale 2^5 = 32 + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK5_CFG1,'h0000_00FF); // Period 0xFFFF + //wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK5_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM + RUN + pwm_monitor(pwm0_period,pwm1_period,pwm2_period,pwm3_period,pwm4_period,pwm5_period); + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-1, PWM Square Waveform - FAILED"); + end else begin + $display("STATUS: Step-1, PWM Square Waveform - PASSED"); + end + $display("########################################"); + $display("Step-2, PWM One Shot"); + test_step = 2; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_8010); // No Scale + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_8011); // Scale 2^1 = 2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_8012); // Scale 2^2 = 4 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM + Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-2, PWM One Shot - FAILED"); + end else begin + $display("STATUS: Step-2, PWM One Shot - PASSED"); + end + + $display("########################################"); + $display("Step-3, PWM One Shot + Hold last data "); + test_step = 3; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_8810); // No Scale + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_8811); // Scale 2^1 = 2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_8812); // Scale 2^2 = 4 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFFFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h0000_007F); // COMP0 = 0xFF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM + Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-3, PWM One Shot + Hold last data - FAILED"); + end else begin + $display("STATUS: Step-3, PWM One Shot + Hold last data - PASSED"); + end + + $display("########################################"); + $display("Step-4, PWM One Shot + mode:1 "); + test_step = 4; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_9010); // No Scale + One Shot + Mode:1 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h0000_0000); // COMP2 = 0x00, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_9011); // Scale 2^1 = 2 + One Shot + Mode:1 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h0000_0000); // COMP2 = 0x00, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_9012); // Scale 2^2 = 4 + One Shot + Mode:1 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h0000_0000); // COMP2 = 0x00, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM + Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-4, PWM One Shot + mode:1 - FAILED"); + end else begin + $display("STATUS: Step-4, PWM One Shot + mode:1 - PASSED"); + end + + $display("########################################"); + $display("Step-5, PWM One Shot + mode:2 "); + test_step = 5; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_A010); // No Scale + One Shot + Mode:2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h0000_00AF); // COMP2 = 0xAF, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_A011); // Scale 2^1 = 2 + One Shot + Mode:2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h0000_00AF); // COMP2 = 0xAF, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_A012); // Scale 2^2 = 4 + One Shot + Mode:2 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h0000_00AF); // COMP2 = 0xAF, COMP3= 0x00 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM + Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-5, PWM One Shot + mode:2 - FAILED"); + end else begin + $display("STATUS: Step-5, PWM One Shot + mode:2 - PASSED"); + end + $display("########################################"); + $display("Step-6, PWM One Shot + mode:3 "); + test_step = 6; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_B010); // No Scale + One Shot + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_B011); // Scale 2^1 = 2 + One Shot + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_B012); // Scale 2^2 = 4 + One Shot + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM+Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-6, PWM One Shot + mode:3 - FAILED"); + end else begin + $display("STATUS: Step-6, PWM One Shot + mode:3 - PASSED"); + end + $display("########################################"); + $display("Step-7, PWM Free Running + mode:3 "); + test_step = 7; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_B000); // No Scale + Free Run + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_B001); // Scale 2^1 = 2 + Free Run + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_B002); // Scale 2^2 = 4 + Free Run + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM+Run + read_data = 8'h0; + fork + begin + while(read_data != 8'h07) begin // Wait for Overflow Interrupt + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-7, PWM Free Run + mode:3 - FAILED"); + end else begin + $display("STATUS: Step-7, PWM Free Run + mode:3 - PASSED"); + end + $display("########################################"); + $display("Step-8, PWM Gpio: 0x3 Pos Edge , One Shot + mode:3 "); + test_step = 8; + // Pin-26 17 PC3/usb_dn/ADC3 digital_io[25]/analog_io[14] + + force u_top.io_in[25] = 1'b0; // force PC3 to 0 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_B350); // No Scale + One Shot + GPIO: 0x3, Posedge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_B351); // Scale 2^1 = 2 + One Shot + GPIO: 0x3, Posedge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_B352); // Scale 2^2 = 4 + One Shot + GPIO: 0x3, Posedge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Interrupt Enable + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0007); // PWM Enable + No Run (Expect GPIO generate Run) + + // Generate 4 GPIO Edge Sequence + for(i=0; i < 4; i=i+1) begin + read_data = 8'h0; + // Generate Pos Egde + force u_top.io_in[25] = 1'b1; // force PC3 to 1 + repeat (10) @(posedge clock); + force u_top.io_in[25] = 1'b0; // force PC3 to 0 + + fork + begin + while(read_data != 8'h07) begin // Wait for Overflow Interrupt + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + if(i < 3) begin + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + end + end + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-8, PWM Gpio: 0x3 Pos Edge , One Shot + mode:3 - FAILED"); + end else begin + $display("STATUS: Step-8, PWM Gpio: 0x3 Pos Edge , One Shot + mode:3 - PASSED"); + end + $display("########################################"); + $display("Step-9, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 "); + test_step = 9; + // Pin-26 17 PC3/usb_dn/ADC3 digital_io[25]/analog_io[14] + + force u_top.io_in[25] = 1'b1; // force PC3 to 1 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_B3D0); // No Scale + One Shot + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_B3D1); // Scale 2^1 = 2 + One Shot + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_B3D2); // Scale 2^2 = 4 + One Shot + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Interrupt Enable + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0007); // PWM Enable + No Run (Expect GPIO generate Run) + + repeat (100) @(posedge clock); // Wait for PWM enable command propagaton + // Generate 4 GPIO Edge Sequence + for(i=0; i < 4; i=i+1) begin + read_data = 8'h0; + // Generate Neg Egde + force u_top.io_in[25] = 1'b0; // force PC3 to 0 + repeat (10) @(posedge clock); + force u_top.io_in[25] = 1'b1; // force PC3 to 1 + + fork + begin + while(read_data != 8'h07) begin // Wait for Overflow Interrupt + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + if(i < 3) begin + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + end + end + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-9, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 - FAILED"); + end else begin + $display("STATUS: Step-9, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 - PASSED"); + end + $display("########################################"); + $display("Step-10, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 + Waveform Invert "); + test_step = 10; + // Pin-26 17 PC3/usb_dn/ADC3 digital_io[25]/analog_io[14] + + force u_top.io_in[25] = 1'b1; // force PC3 to 1 + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h0000_F3D0); // No Scale + One Shot + Clk Inv + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h0000_F3D1); // Scale 2^1 = 2 + One Shot + Clk Inv + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h0000_F3D2); // Scale 2^2 = 4 + One Shot + Clk Inv + GPIO: 0x3, Neg Edge + Mode:3 + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_00FF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Interrupt Enable + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0007); // PWM Enable + No Run (Expect GPIO generate Run) + + repeat (100) @(posedge clock); // Wait for PWM enable command propagaton + // Generate 4 GPIO Edge Sequence + for(i=0; i < 4; i=i+1) begin + read_data = 8'h0; + // Generate Neg Egde + force u_top.io_in[25] = 1'b0; // force PC3 to 0 + repeat (10) @(posedge clock); + force u_top.io_in[25] = 1'b1; // force PC3 to 1 + + fork + begin + while(read_data != 8'h07) begin // Wait for Overflow Interrupt + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + if(i < 3) begin + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data); + end + end + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-9, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 - FAILED"); + end else begin + $display("STATUS: Step-9, PWM Gpio: 0x3 Neg Edge , One Shot + mode:3 - PASSED"); + end + $display("########################################"); + $display("Step-10, PWM One Shot + mode:3 + Comparator Center "); + test_step = 10; + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0007_0000); // Disable Cfg Update + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG0,'h000F_B010); // No Scale + One Shot + Mode:3 + Comparator Center + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG1,'h0000_FFFF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK0_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG0,'h000F_B010); // No Scale + One Shot + Mode:3 + Comparator Center + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG1,'h0000_FFFF); // Period 0xFF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG2,'h008F_006F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK1_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG0,'h000F_B010); // No Scale + One Shot + Mode:3 + Comparator Center + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG1,'h0000_FFFF); // Period 0x80FF + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG2,'h008F_0F6F); // COMP0 = 0x6F, COMP1= 0x8F + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_BLK2_CFG3,'h00CF_00AF); // COMP2 = 0xAF, COMP3= 0xCF + + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_MASK,'h0000_0007); // Enable PWM Interrupt + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Remove config update block + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0707); // Enable PWM+Run + read_data[15:8] = 8'h7; + fork + begin + while(read_data[15:8] != 8'h00) begin // Wait for De-assertion on Run + wb_user_core_read(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,read_data); + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + begin + while(1) begin + check_sum = check_sum + pwm_wfm; + repeat (100) @(posedge clock); + end + end + join_any + + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0007); // Check Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0020); // Check Global Interrupt Status + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_CFG0,'h0000_0000); // Disable PWM + wb_user_core_write(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,'h0000_0007); // Clear Interrupt + wb_user_core_read_check(`ADDR_SPACE_PWM+`PWM_GLBL_INTR_STAT,read_data,'h0000_0000); // Check Interrupt Status + wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,'h0000_0020); // Check Global Interrupt Status + wb_user_core_read_check(`ADDR_SPACE_GLBL+`GLBL_CFG_INTR_STAT,read_data,'h0000_0000); // Check Global Interrupt Status + + if(test_fail == 1) begin + $display("ERROR: Step-10, PWM One Shot + mode:3 + Comparator Center - FAILED"); + end else begin + $display("STATUS: Step-10, PWM One Shot + mode:3 + Comparator Center - PASSED"); + end + $display("Check Sum: %x ",check_sum); + if(check_sum != 16'hc638) test_fail = 1; repeat (100) @(posedge clock); // $display("+1000 cycles"); @@ -158,14 +763,19 @@ $finish; end +wire [5:0] pwm_wfm = {io_out[19], + io_out[18], + io_out[17], + io_out[14], + io_out[13], + io_out[9]}; -wire pwm0 = io_out[9]; -wire pwm1 = io_out[13]; -wire pwm2 = io_out[14]; -wire pwm3 = io_out[17]; -wire pwm4 = io_out[18]; -wire pwm5 = io_out[19]; - +wire pwm0 = pwm_wfm[0]; +wire pwm1 = pwm_wfm[1]; +wire pwm2 = pwm_wfm[2]; +wire pwm3 = pwm_wfm[3]; +wire pwm4 = pwm_wfm[4]; +wire pwm5 = pwm_wfm[5]; task pwm_monitor; input [31:0] pwm0_period; @@ -217,12 +827,12 @@ repeat(2) @(posedge clock_mon); next_t = $realtime; periodd = (next_t-prev_t)/2; - periodd = (periodd)/1e3; + periodd = (periodd); if(clk_period != periodd) begin - $display("STATUS: FAIL => %s Exp Period: %d ms Rxd: %d ms",clk_name,clk_period,periodd); + $display("STATUS: FAIL => %s Exp Period: %d ns Rxd: %d ns",clk_name,clk_period,periodd); test_fail = 1; end else begin - $display("STATUS: PASS => %s Period: %d ms ",clk_name,clk_period); + $display("STATUS: PASS => %s Period: %d ns ",clk_name,clk_period); end end endtask
diff --git a/verilog/dv/user_qspi/user_risc_boot.c b/verilog/dv/user_qspi/user_risc_boot.c deleted file mode 100644 index 83fb41b..0000000 --- a/verilog/dv/user_qspi/user_risc_boot.c +++ /dev/null
@@ -1,53 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -// SPDX-FileCopyrightText: 2021, Dinesh Annayya -// -// 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 -// SPDX-FileContributor: Dinesh Annayya <dinesha@opencores.org> -// ////////////////////////////////////////////////////////////////////////// -#define SC_SIM_OUTPORT (0xf0000000) -#define uint32_t long - -#define reg_mprj_globl_reg0 (*(volatile uint32_t*)0x10020000) // Chip ID -#define reg_mprj_globl_reg1 (*(volatile uint32_t*)0x10020004) // Global Config-0 -#define reg_mprj_globl_reg2 (*(volatile uint32_t*)0x10020008) // Global Config-1 -#define reg_mprj_globl_reg3 (*(volatile uint32_t*)0x1002000C) // Global Interrupt Mask -#define reg_mprj_globl_reg4 (*(volatile uint32_t*)0x10020010) // Global Interrupt -#define reg_mprj_globl_reg5 (*(volatile uint32_t*)0x10020014) // Multi functional sel -#define reg_mprj_globl_soft0 (*(volatile uint32_t*)0x10020018) // Sof Register-0 -#define reg_mprj_globl_soft1 (*(volatile uint32_t*)0x1002001C) // Sof Register-1 -#define reg_mprj_globl_soft2 (*(volatile uint32_t*)0x10020020) // Sof Register-2 -#define reg_mprj_globl_soft3 (*(volatile uint32_t*)0x10020024) // Sof Register-3 -#define reg_mprj_globl_soft4 (*(volatile uint32_t*)0x10020028) // Sof Register-4 -#define reg_mprj_globl_soft5 (*(volatile uint32_t*)0x1002002C) // Sof Register-5 - -int main() -{ - - //volatile long *out_ptr = (volatile long*)SC_SIM_OUTPORT; - //*out_ptr = 0xAABBCCDD; - //*out_ptr = 0xBBCCDDEE; - //*out_ptr = 0xCCDDEEFF; - //*out_ptr = 0xDDEEFF00; - - // Write software Write & Read Register - reg_mprj_globl_soft0 = 0x11223344; - reg_mprj_globl_soft1 = 0x22334455; - reg_mprj_globl_soft2 = 0x33445566; - reg_mprj_globl_soft3 = 0x44556677; - reg_mprj_globl_soft4 = 0x55667788; - reg_mprj_globl_soft5 = 0x66778899; - - while(1) {} - return 0; -}
diff --git a/verilog/dv/user_uart_master/user_uart_master_tb.v b/verilog/dv/user_uart_master/user_uart_master_tb.v index 33277cb..25cbfd3 100644 --- a/verilog/dv/user_uart_master/user_uart_master_tb.v +++ b/verilog/dv/user_uart_master/user_uart_master_tb.v
@@ -116,7 +116,7 @@ initial begin strap_in = 0; - strap_in[`PSTRAP_UARTM_CFG] = 2'b11; // uart master config control - load from LA + strap_in[`PSTRAP_UARTM_CFG] = 2'b00; // uart master config control - load from LA apply_strap(strap_in); uart_data_bit = 2'b11; @@ -144,6 +144,8 @@ tb_master_uart.control_setup (uart_data_bit, uart_stop_bits, uart_parity_en, uart_even_odd_parity, uart_stick_parity, uart_timeout, uart_divisor); + + tb_master_uart.write_char('\n'); // for uart baud auto detect purpose //$write ("\n(%t)Response:\n",$time); flag = 0; while(flag == 0)
diff --git a/verilog/dv/wb_port/wb_port_tb.v b/verilog/dv/wb_port/wb_port_tb.v index 271e092..d91518f 100644 --- a/verilog/dv/wb_port/wb_port_tb.v +++ b/verilog/dv/wb_port/wb_port_tb.v
@@ -49,7 +49,7 @@ initial begin $dumpfile("simx.vcd"); $dumpvars(1, wb_port_tb); - $dumpvars(1, wb_port_tb.u_top); + $dumpvars(2, wb_port_tb.u_top); $dumpvars(1, wb_port_tb.u_top.mgmt_buffers); $dumpvars(1, wb_port_tb.u_top.housekeeping); $dumpvars(1, wb_port_tb.u_top.pll);
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project index 1779d63..55b2bc8 100644 --- a/verilog/includes/includes.rtl.caravel_user_project +++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -10,21 +10,25 @@ -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pinmux_top.sv -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pinmux.sv -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/glbl_reg.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/gpio_top.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/gpio_intr.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/gpio_reg.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pwm_top.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pwm_reg.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pwm.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/timer_top.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/timer_reg.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/timer.sv -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/semaphore_reg.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/ws281x_top.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/ws281x_driver.sv --v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/ws281x_reg.sv -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/strap_ctrl.sv -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/glbl_rst_reg.sv +-v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_top.sv +-v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_dglicth.sv +-v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_intr.sv +-v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_reg.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm_top.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm_glbl_reg.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm_blk_reg.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm_cfg_dglitch.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm_core.sv +-v $(USER_PROJECT_VERILOG)/rtl/pwm/src/pwm.sv +-v $(USER_PROJECT_VERILOG)/rtl/timer/src/timer_top.sv +-v $(USER_PROJECT_VERILOG)/rtl/timer/src/timer_reg.sv +-v $(USER_PROJECT_VERILOG)/rtl/timer/src/timer.sv +-v $(USER_PROJECT_VERILOG)/rtl/ws281x/src/ws281x_top.sv +-v $(USER_PROJECT_VERILOG)/rtl/ws281x/src/ws281x_driver.sv +-v $(USER_PROJECT_VERILOG)/rtl/ws281x/src/ws281x_reg.sv -v $(USER_PROJECT_VERILOG)/rtl/lib/pulse_gen_type1.sv -v $(USER_PROJECT_VERILOG)/rtl/lib/pulse_gen_type2.sv -v $(USER_PROJECT_VERILOG)/rtl/lib/clk_div8.v @@ -130,6 +134,7 @@ -v $(USER_PROJECT_VERILOG)/rtl/uart2wb/src/uart2wb.sv -v $(USER_PROJECT_VERILOG)/rtl/uart2wb/src/uart2_core.sv -v $(USER_PROJECT_VERILOG)/rtl/uart2wb/src/uart_msg_handler.v +-v $(USER_PROJECT_VERILOG)/rtl/uart2wb/src/uart_auto_det.sv -v $(USER_PROJECT_VERILOG)/rtl/lib/async_reg_bus.sv -v $(USER_PROJECT_VERILOG)/rtl/user_project_wrapper.v -v $(USER_PROJECT_VERILOG)/rtl/lib/clk_skew_adjust.gv
diff --git a/verilog/rtl/digital_pll/src/ring_osc2x13.v b/verilog/rtl/digital_pll/src/ring_osc2x13.v index f20110e..ce76830 100644 --- a/verilog/rtl/digital_pll/src/ring_osc2x13.v +++ b/verilog/rtl/digital_pll/src/ring_osc2x13.v
@@ -42,7 +42,7 @@ .Z(d1) ); - sky130_fd_sc_hd__einvn_4 delayenb1 ( + sky130_fd_sc_hd__einvn_2 delayenb1 ( .A(ts), .TE_B(trim[1]), .Z(d1) @@ -86,7 +86,7 @@ .Z(d1) ); - sky130_fd_sc_hd__einvn_4 delayenb1 ( + sky130_fd_sc_hd__einvn_2 delayenb1 ( .A(in), .TE_B(trim[1]), .Z(d1)
diff --git a/verilog/rtl/gpio/src/gpio_dglicth.sv b/verilog/rtl/gpio/src/gpio_dglicth.sv new file mode 100644 index 0000000..e843057 --- /dev/null +++ b/verilog/rtl/gpio/src/gpio_dglicth.sv
@@ -0,0 +1,72 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// GPIO De-Glitch //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesh.annayya@gmail.com //// +//// //// +//// Revision : //// +//// 0.1 - 13th Sept 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// +// + + +module gpio_dglitch ( + input logic reset_n, + input logic mclk, + input logic pulse_1us, + input logic cfg_mode, // 0 - 1 us, 1 - every system clock + input logic gpio_in, + output logic gpio_out + ); + +logic [3:0] gpio_ss; +logic gpio_reg; + +// Pass the input data , if there is no transition, else send old data +assign gpio_out = ((gpio_ss[3] == gpio_ss[2]) && (gpio_ss[2] == gpio_ss[1])) ? gpio_ss[3] : gpio_reg; + + +always@(negedge reset_n or posedge mclk) +begin + if(reset_n == 1'b0) begin + gpio_ss <= 'h0; + gpio_reg <= 'h0; + end else begin + gpio_reg <= gpio_out; + if(cfg_mode == 1'b0) begin // De-glitch sampling at 1us pulse + if(pulse_1us) gpio_ss <= {gpio_ss[2:0],gpio_in}; + end else begin // De-glitch on on every system clock + gpio_ss <= {gpio_ss[2:0],gpio_in}; + end + end +end + + +endmodule
diff --git a/verilog/rtl/gpio/src/gpio_intr.sv b/verilog/rtl/gpio/src/gpio_intr.sv new file mode 100644 index 0000000..9bcefee --- /dev/null +++ b/verilog/rtl/gpio/src/gpio_intr.sv
@@ -0,0 +1,43 @@ + +// GPIO Interrupt Generation +module gpio_intr_gen ( + input logic mclk ,// System clk + input logic h_reset_n ,// system reset + input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data + input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this + input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg + input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level + input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt + input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt + + + output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg + output logic [31:0] gpio_int_event // to the cfg interrupt status reg + +); + + +integer i; +//----------------------------------------------------------------------- +// Logic for interrupt detection +//----------------------------------------------------------------------- + +reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg +always_comb +begin + for (i=0; i<32; i=i+1) + begin + // looking for rising edge int + local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i] + & cfg_gpio_data_in[i]) | + (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] & + ~cfg_gpio_data_in[i])); + // looking for falling edge int + end +end + +assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg + +assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus + +endmodule
diff --git a/verilog/rtl/gpio/src/gpio_reg.sv b/verilog/rtl/gpio/src/gpio_reg.sv new file mode 100644 index 0000000..a8528eb --- /dev/null +++ b/verilog/rtl/gpio/src/gpio_reg.sv
@@ -0,0 +1,319 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// GPIO Register //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesh.annayya@gmail.com //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// +// +module gpio_reg ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + + // Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [3:0] reg_addr , + input logic [31:0] reg_wdata , + input logic [3:0] reg_be , + + // Outputs + output logic [31:0] reg_rdata , + output logic reg_ack , + + + input logic [31:0] gpio_in_data , + output logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data + input logic [31:0] gpio_int_event , + output logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg + output logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output + output logic [31:0] cfg_gpio_out_type ,// GPIO Type, 1 - WS_281X port + output logic [31:0] cfg_multi_func_sel ,// GPIO Multi function type + output logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt + output logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt + output logic [31:00] cfg_gpio_data_in , + + output logic [31:0] gpio_intr + + + ); + +//----------------------------------------------------------------------- +// Internal Wire Declarations +//----------------------------------------------------------------------- + +logic sw_rd_en ; +logic sw_wr_en ; +logic [3:0] sw_addr ; // addressing 16 registers +logic [31:0] sw_reg_wdata ; +logic [3:0] sw_be ; + +logic [31:0] reg_out ; +logic [31:0] reg_0 ; // GPIO Direction Select +logic [31:0] reg_1 ; // GPIO TYPE - Unused +logic [31:0] reg_2 ; // GPIO IN DATA +logic [31:0] reg_3 ; // GPIO OUT DATA +logic [31:0] reg_4 ; // GPIO INTERRUPT STATUS/CLEAR +logic [31:0] reg_5 ; // GPIO INTERRUPT SET +logic [31:0] reg_6 ; // GPIO INTERRUPT MASK +logic [31:0] reg_7 ; // GPIO POSEDGE INTERRUPT SEL +logic [31:0] reg_8 ; // GPIO NEGEDGE INTERRUPT SEL + +assign sw_addr = reg_addr; +assign sw_rd_en = reg_cs & !reg_wr; +assign sw_wr_en = reg_cs & reg_wr; +assign sw_be = reg_be; +assign sw_reg_wdata = reg_wdata; + +//----------------------------------------------------------------------- +// register read enable and write enable decoding logic +//----------------------------------------------------------------------- +wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0); +wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1); +wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2); +wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3); +wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4); +wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5); +wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6); +wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7); +wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8); + +wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0); +wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1); +wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2); +wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3); +wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4); +wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5); +wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6); +wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7); +wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8); + + +always @ (posedge mclk or negedge h_reset_n) +begin : preg_out_Seq + if (h_reset_n == 1'b0) begin + reg_rdata <= 'h0; + reg_ack <= 1'b0; + end else if (reg_cs && !reg_ack) begin + reg_rdata <= reg_out; + reg_ack <= 1'b1; + end else begin + reg_ack <= 1'b0; + end +end + +//----------------------------------------------------------------------- +// Logic for cfg_gpio_dir_sel +//----------------------------------------------------------------------- +assign cfg_gpio_dir_sel = reg_0[31:0]; // data to the GPIO O/P pins + +gen_32b_reg #(32'h0) u_reg_0 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_0 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_0 ) + ); +//----------------------------------------------------------------------- +// Logic for cfg_gpio_out_type +//----------------------------------------------------------------------- +assign cfg_gpio_out_type = reg_1[31:0]; // Un-used + +gen_32b_reg #(32'h0) u_reg_1 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_1 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_1 ) + ); +//----------------------------------------------------------------------- +// Logic for gpio_data_in +//----------------------------------------------------------------------- +// Double Sync the gpio pin data for edge detection +always @ (posedge mclk or negedge h_reset_n) +begin + if (h_reset_n == 1'b0) begin + reg_2 <= 'h0 ; + end + else begin + reg_2 <= gpio_in_data; + end +end + + +assign cfg_gpio_data_in = gpio_in_data; // to be used for edge interrupt detect +assign gpio_prev_indata = reg_2[31:0]; + +//----------------------------------------------------------------------- +// Logic for cfg_gpio_out_data +//----------------------------------------------------------------------- +assign cfg_gpio_out_data = reg_3[31:0]; // data to the GPIO control blk + +gen_32b_reg #(32'h0) u_reg_3 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_3 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_3 ) + ); + + + +//-------------------------------------------------------- +// Interrupt Status Generation +// Note: Reg_4 --> Interrupt Status Register, Writting '1' will clear the +// corresponding interrupt status bit. Writting '0' has no +// effect +// Reg_5 --> Writting one to this register will set the interrupt in +// interrupt status register (reg_4), Writting '0' does not has any +// effect. +/// Always update int_status, even if no register write is occuring. +// Interrupt posting is higher priority than int clear by host +//-------------------------------------------------------- +wire [31:0] gpio_int_status = reg_4; + +generic_intr_stat_reg #(.WD(32), + .RESET_DEFAULT(0)) u_reg_4 ( + //inputs + .clk (mclk ), + .reset_n (h_reset_n ), + .reg_we ({ + {8{sw_wr_en_4 & reg_ack & sw_be[2]}}, + {8{sw_wr_en_4 & reg_ack & sw_be[2]}}, + {8{sw_wr_en_4 & reg_ack & sw_be[1]}}, + {8{sw_wr_en_4 & reg_ack & sw_be[0]}} + } ), + .reg_din (sw_reg_wdata[31:0] ), + .hware_req (gpio_int_event | { + {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[31:24], + {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[23:16], + {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[15:8] , + {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[7:0] + } ), + + //outputs + .data_out (reg_4[31:0] ) + ); +//------------------------------------------------- +// Returns same value as interrupt status register +//------------------------------------------------ + +assign reg_5 = reg_4; +//----------------------------------------------------------------------- +// Logic for cfg_gpio_int_mask : GPIO interrupt mask +//----------------------------------------------------------------------- +wire [31:0] cfg_gpio_int_mask = reg_6[31:0]; // to be used for read + +assign gpio_intr = reg_4 & reg_6; // interrupt pin to the RISC + + +// Register-11 +gen_32b_reg #(32'h0) u_reg_6 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_6 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_6 ) + ); +//----------------------------------------------------------------------- +// Logic for cfg_gpio_posedge_int_sel : Enable posedge GPIO interrupt +//----------------------------------------------------------------------- +assign cfg_gpio_posedge_int_sel = reg_7[31:0]; // to be used for read +gen_32b_reg #(32'h0) u_reg_7 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_7 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_7 ) + ); +//----------------------------------------------------------------------- +// Logic for cfg_gpio_negedge_int_sel : Enable negedge GPIO interrupt +//----------------------------------------------------------------------- +assign cfg_gpio_negedge_int_sel = reg_8[31:0]; // to be used for read +gen_32b_reg #(32'h0) u_reg_8 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_8 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_8 ) + ); + + +//----------------------------------------------------------------------- +// Register Read Path Multiplexer instantiation +//----------------------------------------------------------------------- + +always_comb +begin + reg_out [31:0] = 32'h0; + + case (sw_addr [3:0]) + 4'b0000 : reg_out [31:0] = reg_0 [31:0]; + 4'b0001 : reg_out [31:0] = reg_1 [31:0]; + 4'b0010 : reg_out [31:0] = reg_2 [31:0]; + 4'b0011 : reg_out [31:0] = reg_3 [31:0]; + 4'b0100 : reg_out [31:0] = reg_4 [31:0]; + 4'b0101 : reg_out [31:0] = reg_5 [31:0]; + 4'b0110 : reg_out [31:0] = reg_6 [31:0]; + 4'b0111 : reg_out [31:0] = reg_7 [31:0]; + 4'b1000 : reg_out [31:0] = reg_8 [31:0]; + default : reg_out [31:0] = 32'h0; + endcase +end + +endmodule
diff --git a/verilog/rtl/gpio/src/gpio_top.sv b/verilog/rtl/gpio/src/gpio_top.sv new file mode 100644 index 0000000..57a0092 --- /dev/null +++ b/verilog/rtl/gpio/src/gpio_top.sv
@@ -0,0 +1,163 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// GPIO Top //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +/// //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// + +module gpio_top ( + // System Signals + // Inputs + input logic mclk, + input logic h_reset_n, + input logic cfg_gpio_dgmode, // 0 - De-glitch sampling on 1us + input logic pulse_1us, + + // Reg Bus Interface Signal + input logic reg_cs, + input logic reg_wr, + input logic [3:0] reg_addr, + input logic [31:0] reg_wdata, + input logic [3:0] reg_be, + + // Outputs + output logic [31:0] reg_rdata, + output logic reg_ack, + + output logic [31:0] cfg_gpio_out_type ,// GPIO Type, 1 - ws281x + output logic [31:0] cfg_gpio_dir_sel, + input logic [31:0] pad_gpio_in, + output logic [31:0] pad_gpio_out, + + output logic [7:0] pwm_gpio_in, + + output logic [31:0] gpio_intr + + ); + + +logic [31:0] gpio_prev_indata ;// previously captured GPIO I/P pins data +logic [31:0] cfg_gpio_out_data ;// GPIO statuc O/P data from config reg +logic [31:0] cfg_multi_func_sel ;// GPIO Multi function type +logic [31:0] cfg_gpio_posedge_int_sel ;// select posedge interrupt +logic [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt +logic [31:00] cfg_gpio_data_in ; +logic [31:0] gpio_int_event ; +logic [31:0] gpio_dsync ; + + +//------------------------------------------ +// Assign GPIO PORT-C as PWM GPIO +//---------------------------------------- + +assign pwm_gpio_in = gpio_dsync[23:16]; + +//-------------------------------------- +// GPIO Ge-glitch logic +//-------------------------------------- +genvar port; +generate +for (port = 0; $unsigned(port) < 32; port=port+1) begin : u_bit + +gpio_dglitch u_dglitch( + .reset_n (h_reset_n ), + .mclk (mclk ), + .pulse_1us (pulse_1us ), + .cfg_mode (cfg_gpio_dgmode ), + .gpio_in (pad_gpio_in[port] ), + .gpio_out (gpio_dsync[port]) + ); + +end +endgenerate // dglitch + + + + +gpio_reg u_reg ( + .mclk (mclk ), + .h_reset_n (h_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 ), + + // GPIO input pins + .gpio_in_data (gpio_dsync ), + .gpio_prev_indata (gpio_prev_indata ), + .gpio_int_event (gpio_int_event ), + + // GPIO config pins + .cfg_gpio_out_data (cfg_gpio_out_data ), + .cfg_gpio_dir_sel (cfg_gpio_dir_sel ), + .cfg_gpio_out_type (cfg_gpio_out_type ), + .cfg_gpio_posedge_int_sel (cfg_gpio_posedge_int_sel), + .cfg_gpio_negedge_int_sel (cfg_gpio_negedge_int_sel), + .cfg_multi_func_sel (cfg_multi_func_sel ), + .cfg_gpio_data_in (cfg_gpio_data_in ), + + .gpio_intr (gpio_intr ) + + + ); + + +gpio_intr_gen u_gpio_intr ( + // System Signals + // Inputs + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + // GPIO cfg input pins + .gpio_prev_indata (gpio_prev_indata ), + .cfg_gpio_data_in (cfg_gpio_data_in ), + .cfg_gpio_dir_sel (cfg_gpio_dir_sel ), + .cfg_gpio_out_data (cfg_gpio_out_data ), + .cfg_gpio_posedge_int_sel(cfg_gpio_posedge_int_sel), + .cfg_gpio_negedge_int_sel(cfg_gpio_negedge_int_sel), + + + // GPIO output pins + .pad_gpio_out (pad_gpio_out ), + .gpio_int_event (gpio_int_event ) + ); + +endmodule
diff --git a/verilog/rtl/lib/reset_sync.sv b/verilog/rtl/lib/reset_sync.sv index d96c719..5b5c7fa 100644 --- a/verilog/rtl/lib/reset_sync.sv +++ b/verilog/rtl/lib/reset_sync.sv
@@ -81,7 +81,6 @@ 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 @@ -96,6 +95,7 @@ in_data_2s <= in_data_s; end end - +//assign srst_n = (scan_mode) ? arst_n : in_data_2s; +ctech_mux2x1 u_buf (.A0(in_data_2s), .A1(arst_n), .S(scan_mode), .X(srst_n)); endmodule
diff --git a/verilog/rtl/pinmux/src/glbl_reg.sv b/verilog/rtl/pinmux/src/glbl_reg.sv index 5dffbf8..acbd36f 100644 --- a/verilog/rtl/pinmux/src/glbl_reg.sv +++ b/verilog/rtl/pinmux/src/glbl_reg.sv
@@ -93,6 +93,7 @@ output logic [2:0] user_irq , input logic usb_intr , input logic i2cm_intr , + input logic pwm_intr , output logic [15:0] cfg_riscv_ctrl , output logic [31:0] cfg_multi_func_sel ,// multifunction pins @@ -108,7 +109,8 @@ output logic[25:0] cfg_dc_trim , // External trim for DCO mode output logic pll_ref_clk , // Input oscillator to match - output logic dbg_clk_mon + output logic dbg_clk_mon , + output logic cfg_gpio_dgmode ); @@ -134,9 +136,6 @@ logic [31:0] reg_6; // logic [31:0] reg_7; // logic [31:0] reg_8; // -logic [31:0] reg_9; // -logic [31:0] reg_10; // -logic [31:0] reg_11; // logic [31:0] reg_12; // Latched Strap logic [31:0] reg_13; // Strap Sticky logic [31:0] reg_14; // System Strap @@ -150,14 +149,6 @@ logic [31:0] reg_21; // Software Reg-5 - s_reset logic [31:0] reg_22; // Software Reg-6 - s_reset logic [31:0] reg_23; // Software Reg-7 - s_reset -logic [31:0] reg_24; // Reserved -logic [31:0] reg_25; // Reserved -logic [31:0] reg_26; // Reserved -logic [31:0] reg_27; // Reserved -logic [31:0] reg_28; // Reserved -logic [31:0] reg_29; // Reserved -logic [31:0] reg_30; // Reserved -logic [31:0] reg_31; // Reserved logic cs_int; logic [3:0] cfg_mon_sel; @@ -348,10 +339,11 @@ .data_out (reg_2 ) ); -assign cfg_mon_sel = reg_2[7:4]; -assign soft_irq = reg_2[3]; -assign user_irq = reg_2[2:0]; -assign cfg_riscv_ctrl = reg_2[31:16]; +assign cfg_gpio_dgmode = reg_2[8]; // gpio de-glitch mode selection +assign cfg_mon_sel = reg_2[7:4]; +assign soft_irq = reg_2[3]; +assign user_irq = reg_2[2:0]; +assign cfg_riscv_ctrl = reg_2[31:16]; //----------------------------------------------------------------------- // reg-3 : Global Interrupt Mask @@ -375,7 +367,7 @@ assign irq_lines = reg_3[31:0] & reg_4[31:0]; // In Arduino GPIO[7:0] is corresponds to PORT-A which is not available for user access -wire [31:0] hware_intr_req = {gpio_intr[31:8], 3'b0,usb_intr, i2cm_intr,timer_intr[2:0]}; +wire [31:0] hware_intr_req = {gpio_intr[31:8], 2'b0,pwm_intr,usb_intr, i2cm_intr,timer_intr[2:0]}; generic_intr_stat_reg #(.WD(32), .RESET_DEFAULT(0)) u_reg4 ( @@ -657,9 +649,9 @@ 5'b00110 : reg_out [31:0] = reg_6 ; 5'b00111 : reg_out [31:0] = reg_7 ; 5'b01000 : reg_out [31:0] = reg_8 ; - 5'b01001 : reg_out [31:0] = reg_9 ; - 5'b01010 : reg_out [31:0] = reg_10 ; - 5'b01011 : reg_out [31:0] = reg_11 ; + 5'b01001 : reg_out [31:0] = 'h0 ; + 5'b01010 : reg_out [31:0] = 'h0 ; + 5'b01011 : reg_out [31:0] = 'h0 ; 5'b01100 : reg_out [31:0] = reg_12 ; 5'b01101 : reg_out [31:0] = reg_13 ; 5'b01110 : reg_out [31:0] = reg_14 ; @@ -672,14 +664,14 @@ 5'b10101 : reg_out [31:0] = reg_21 ; 5'b10110 : reg_out [31:0] = reg_22 ; 5'b10111 : reg_out [31:0] = reg_23 ; - 5'b11000 : reg_out [31:0] = reg_24 ; - 5'b11001 : reg_out [31:0] = reg_25 ; - 5'b11010 : reg_out [31:0] = reg_26 ; - 5'b11011 : reg_out [31:0] = reg_27 ; - 5'b11100 : reg_out [31:0] = reg_28 ; - 5'b11101 : reg_out [31:0] = reg_29 ; - 5'b11110 : reg_out [31:0] = reg_30 ; - 5'b11111 : reg_out [31:0] = reg_31 ; + 5'b11000 : reg_out [31:0] = 'h0 ; + 5'b11001 : reg_out [31:0] = 'h0 ; + 5'b11010 : reg_out [31:0] = 'h0 ; + 5'b11011 : reg_out [31:0] = 'h0 ; + 5'b11100 : reg_out [31:0] = 'h0 ; + 5'b11101 : reg_out [31:0] = 'h0 ; + 5'b11110 : reg_out [31:0] = 'h0 ; + 5'b11111 : reg_out [31:0] = 'h0 ; default : reg_out [31:0] = 32'h0; endcase end @@ -759,7 +751,7 @@ ); // Debug clock monitor optin -assign dbg_clk_ref = (cfg_mon_sel == 4'b000) ? user_clock1 : +wire dbg_clk_ref = (cfg_mon_sel == 4'b000) ? user_clock1 : (cfg_mon_sel == 4'b001) ? user_clock2 : (cfg_mon_sel == 4'b010) ? xtal_clk : (cfg_mon_sel == 4'b011) ? int_pll_clock: @@ -769,6 +761,7 @@ (cfg_mon_sel == 4'b111) ? rtc_clk : 1'b0; // DIv16 to debug monitor purpose +logic dbg_clk_div16; clk_ctl #(3) u_dbgclk ( // Outputs
diff --git a/verilog/rtl/pinmux/src/pinmux_top.sv b/verilog/rtl/pinmux/src/pinmux_top.sv index 0b3121f..82cbeae 100755 --- a/verilog/rtl/pinmux/src/pinmux_top.sv +++ b/verilog/rtl/pinmux/src/pinmux_top.sv
@@ -206,11 +206,13 @@ logic s_reset_ssn; // Sync Reset logic p_reset_ssn; // Sync Reset logic [15:0] pad_strap_in; -logic dbg_clk_mon; - +logic dbg_clk_mon; +logic cfg_gpio_dgmode; // gpio de-glitch mode +logic pwm_intr; /* clock pulse */ //******************************************************** logic pulse_1ms ; // 1 Milli Second Pulse for waveform Generator +logic pulse_1us ; // 1 Micro Second Pulse for waveform Generator logic [5:0] cfg_pwm_enb ; @@ -282,6 +284,8 @@ logic [31:0] reg_ws_rdata; logic reg_ws_ack; +logic [7:0] pwm_gpio_in; + assign reg_rdata = (reg_addr[9:7] == `SEL_GLBL) ? {reg_glbl_rdata} : (reg_addr[9:7] == `SEL_GPIO) ? {reg_gpio_rdata} : (reg_addr[9:7] == `SEL_PWM) ? {reg_pwm_rdata} : @@ -394,6 +398,7 @@ .user_irq (user_irq ), .usb_intr (usb_intr ), .i2cm_intr (i2cm_intr ), + .pwm_intr (pwm_intr ), @@ -407,7 +412,8 @@ .cfg_dc_trim (cfg_dc_trim ), // External trim for DCO mode .pll_ref_clk (pll_ref_clk ), // Input oscillator to match - .dbg_clk_mon (dbg_clk_mon ) + .dbg_clk_mon (dbg_clk_mon ), + .cfg_gpio_dgmode (cfg_gpio_dgmode ) @@ -421,6 +427,8 @@ // Inputs .mclk ( mclk ), .h_reset_n (s_reset_ssn ), + .cfg_gpio_dgmode (cfg_gpio_dgmode ), + .pulse_1us (pulse_1us ), // Reg Bus Interface Signal .reg_cs (reg_gpio_cs ), @@ -438,6 +446,7 @@ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ), .pad_gpio_in (pad_gpio_in ), .pad_gpio_out (pad_gpio_out ), + .pwm_gpio_in (pwm_gpio_in ), .gpio_intr (gpio_intr ) @@ -456,7 +465,7 @@ // Reg Bus Interface Signal .reg_cs (reg_pwm_cs ), .reg_wr (reg_wr ), - .reg_addr (reg_addr[4:2] ), + .reg_addr (reg_addr[6:2] ), .reg_wdata (reg_wdata ), .reg_be (reg_be ), @@ -464,9 +473,9 @@ .reg_rdata (reg_pwm_rdata ), .reg_ack (reg_pwm_ack ), - .pulse_1ms (pulse_1ms ), - .cfg_pwm_enb (cfg_pwm_enb ), - .pwm_wfm (pwm_wfm ) + .pad_gpio (pwm_gpio_in ), + .pwm_wfm (pwm_wfm ), + .pwm_intr (pwm_intr ) ); //----------------------------------------------------------------------- @@ -489,7 +498,8 @@ .reg_rdata (reg_timer_rdata ), .reg_ack (reg_timer_ack ), - .pulse_1ms (pulse_1ms ), + .pulse_1us (pulse_1us ), + .pulse_1ms (pulse1m_mclk ), .timer_intr (timer_intr ) );
diff --git a/verilog/rtl/pinmux/src/strap_ctrl.sv b/verilog/rtl/pinmux/src/strap_ctrl.sv index c0405b0..54ecdf4 100644 --- a/verilog/rtl/pinmux/src/strap_ctrl.sv +++ b/verilog/rtl/pinmux/src/strap_ctrl.sv
@@ -92,9 +92,9 @@ 2'b10 - Default value + 4 2'b11 - Default value - 4 bit [4:13] - uart master config control - 2'b00 - constant value based on system clock-50Mhz (Default) - 2'b01 - constant value based on system clock-40Mhz - 2'b10 - constant value based on system clock-60Mhz (USB Ref Clock) + 2'b00 - Auto Detect (Default) + 2'b01 - constant value based on system clock-50Mhz + 2'b10 - constant value based on system clock-4Mhz 2'b11 - load from LA bit [14:13] - Reserved bit [15] - Strap Mode
diff --git a/verilog/rtl/pwm/src/pwm.sv b/verilog/rtl/pwm/src/pwm.sv new file mode 100644 index 0000000..922c369 --- /dev/null +++ b/verilog/rtl/pwm/src/pwm.sv
@@ -0,0 +1,270 @@ + +//------------------------------------------------------------------- +// PWM waveform period: 1000/((cfg_pwm_high+1) + (cfg_pwm_low+1)) +// For 1 Second with Duty cycle 50 = 1000/((499+1) + (499+1)) +// For 1 Second with 1ms On and 999ms Off = 1000/((0+1) + (998+1)) +// Timing Run's with 1 Milisecond pulse +//------------------------------------------------------------------- + +module pwm( + + input logic h_reset_n , + input logic mclk , + + output logic pwm_wfm_o , + output logic pwm_os_done , + output logic pwm_ovflow_pe , + output logic gpio_tgr , + + input logic [7:0] pad_gpio , + + input logic cfg_pwm_enb , // pwm operation enable + input logic cfg_pwm_run , // pwm operation enable + input logic [3:0] cfg_pwm_scale , // pwm clock scaling + input logic cfg_pwm_oneshot , // pwm OneShot mode + input logic cfg_pwm_frun , // pwm is free running + input logic cfg_pwm_gpio_enb , // pwm gpio based trigger + input logic cfg_pwm_gpio_edge , // pwm gpio based trigger edge + input logic [2:0] cfg_pwm_gpio_sel , // gpio Selection + input logic cfg_pwm_hold , // Hold data pwm data During pwm Disable + input logic cfg_pwm_inv , // invert output + input logic cfg_pwm_zeropd , // Reset on pmw_cnt match to period + input logic [1:0] cfg_pwm_mode , // pwm Pulse Generation mode + input logic cfg_comp0_center , // Compare cnt at comp0 center + input logic cfg_comp1_center , // Compare cnt at comp1 center + input logic cfg_comp2_center , // Compare cnt at comp2 center + input logic cfg_comp3_center , // Compare cnt at comp3 center + input logic [15:0] cfg_pwm_period , // pwm period + input logic [15:0] cfg_pwm_comp0 , // compare0 + input logic [15:0] cfg_pwm_comp1 , // compare1 + input logic [15:0] cfg_pwm_comp2 , // compare2 + input logic [15:0] cfg_pwm_comp3 // compare3 +); + +logic [14:0] pwm_scnt ; // PWM Scaling counter +logic [15:0] pwm_cnt ; // PWM counter +logic cnt_trg ; +logic pwm_wfm_i ; +logic pwm_wfm_hold; +logic comp0_match ; +logic comp1_match ; +logic comp2_match ; +logic comp3_match ; +//-------------------------------- +// Counter Scaling +// In GPIO mode, wait for first GPIO transition +//-------------------------------- + +always @(posedge mclk or negedge h_reset_n) +begin + if ( ~h_reset_n ) begin + pwm_scnt <= 15'h0; + end else begin + //------------------------------------------------------- + // Added additional case to handle when new gpio trigger + // generated before completing the current Run + //------------------------------------------------------- + if(cfg_pwm_enb && cfg_pwm_run && !gpio_tgr) begin + pwm_scnt <= pwm_scnt + 1; + end else begin + pwm_scnt <= 15'h0; + end + end +end + +//----------------------------------------------------------------------------- +// pwm_scaling used to decide on the trigger event for the pwm_cnt +// 0 ==> pwm_cnt increment every system cycle +// 1 ==> 2^0 => pmw_cnt increase once in two system cycle +// 15 ==>a 2^15 => pwm_cnt increase once in 32768 system cycle +//----------------------------------------------------------------------------- + +always_comb +begin + cnt_trg = 0; + case(cfg_pwm_scale) + 4'b0000: cnt_trg = 1; + 4'b0001: cnt_trg = pwm_scnt[0]; + 4'b0010: cnt_trg = &pwm_scnt[1:0]; + 4'b0011: cnt_trg = &pwm_scnt[2:0]; + 4'b0100: cnt_trg = &pwm_scnt[3:0]; + 4'b0101: cnt_trg = &pwm_scnt[4:0]; + 4'b0110: cnt_trg = &pwm_scnt[5:0]; + 4'b0111: cnt_trg = &pwm_scnt[6:0]; + 4'b1000: cnt_trg = &pwm_scnt[7:0]; + 4'b1001: cnt_trg = &pwm_scnt[8:0]; + 4'b1010: cnt_trg = &pwm_scnt[9:0]; + 4'b1011: cnt_trg = &pwm_scnt[10:0]; + 4'b1100: cnt_trg = &pwm_scnt[11:0]; + 4'b1101: cnt_trg = &pwm_scnt[12:0]; + 4'b1110: cnt_trg = &pwm_scnt[13:0]; + 4'b1111: cnt_trg = &pwm_scnt[14:0]; + default: cnt_trg = 0; + endcase +end + +//---------------------------------------------------------- +//Counter Overflow condition +// 1. At Roll Over +// 2. If compare on period enable, then at period +//---------------------------------------------------------- +logic pwm_ovflow_l; +wire pwm_ovflow = ((&pwm_cnt) | (cfg_pwm_zeropd && (pwm_cnt == cfg_pwm_period))) & cfg_pwm_enb; + + +// overflow single cycle pos edge pulse +assign pwm_ovflow_pe = (!pwm_ovflow_l & pwm_ovflow); + +// Don't generate PWM done at exact clash at gpio trigger, higer priority to gpio trigger +assign pwm_os_done = (cfg_pwm_oneshot && !gpio_tgr) ? pwm_ovflow_pe : 1'b0; + +always @(posedge mclk or negedge h_reset_n) +begin + if ( ~h_reset_n ) begin + pwm_cnt <= 16'h0; + pwm_ovflow_l <= 1'b0; + end else begin + pwm_ovflow_l <= pwm_ovflow; + //------------------------------------------------------- + // Added additional case to handle when new gpio trigger + // generated before completing the current Run + //------------------------------------------------------- + if(cfg_pwm_enb && cfg_pwm_run && !gpio_tgr) begin + if(cnt_trg) begin + if(pwm_ovflow) begin + pwm_cnt <= 'h0; + end else begin + pwm_cnt <= pwm_cnt + 1; + end + end + end else begin + pwm_cnt <= 16'h0; + end + end +end + +//----------------------------- +// compare-0 match logic generation +//------------------------------ + +always_comb begin + comp0_match = 0; + if(cfg_comp0_center)begin + comp0_match = (({16{pwm_cnt[15]}} ^ pwm_cnt) >= cfg_pwm_comp0); + end else begin + comp0_match = (pwm_cnt >= cfg_pwm_comp0); + end +end + +//----------------------------- +// compare-1 match logic generation +//------------------------------ +always_comb begin + comp1_match = 0; + if(cfg_comp1_center)begin + comp1_match = (({16{pwm_cnt[15]}}^ pwm_cnt) >= cfg_pwm_comp1); + end else begin + comp1_match = (pwm_cnt >= cfg_pwm_comp1); + end +end + +//----------------------------- +// compare-2 match logic generation +//------------------------------ +always_comb begin + comp2_match = 0; + if(cfg_comp2_center)begin + comp2_match = (({16{pwm_cnt[15]}} ^ pwm_cnt) >= cfg_pwm_comp2); + end else begin + comp2_match = (pwm_cnt >= cfg_pwm_comp2); + end +end + +//----------------------------- +// compare-3 match logic generation +//------------------------------ +always_comb begin + comp3_match = 0; + if(cfg_comp3_center) begin + comp3_match = (({16{pwm_cnt[15]}} ^ pwm_cnt) >= cfg_pwm_comp3); + end else begin + comp3_match = (pwm_cnt >= cfg_pwm_comp3); + end +end + +//--------------------------------------------- +// Consolidated pwm waform generation +// based on pwm mode +//--------------------------------------------- + +always_comb begin + pwm_wfm_i = 0; + case(cfg_pwm_mode) + 2'b00: pwm_wfm_i = comp0_match; + 2'b01: pwm_wfm_i = comp0_match ^ comp1_match; + 2'b10: pwm_wfm_i = comp0_match ^ comp1_match ^ comp2_match; + 2'b11: pwm_wfm_i = comp0_match ^ comp1_match ^ comp2_match ^ comp3_match; + default: pwm_wfm_i=0; + endcase +end + +//----------------------------------------------- +// Holding the pwm waveform in active region +//------------------------------------------------ +always @(posedge mclk or negedge h_reset_n) +begin + if ( ~h_reset_n ) begin + pwm_wfm_hold <= 1'b0; + end else if(cfg_pwm_enb) begin + pwm_wfm_hold <= pwm_wfm_i; + end +end + +//-------------------------------------------- +// Final Waveform output generation based +// on pwm_hold and pwm_inv combination +//-------------------------------------------- +always_comb begin + pwm_wfm_o = 0; + if(!cfg_pwm_enb && cfg_pwm_hold) begin + if(cfg_pwm_inv) pwm_wfm_o = !pwm_wfm_hold; + else pwm_wfm_o = pwm_wfm_hold; + end else begin + if(cfg_pwm_inv) pwm_wfm_o = !pwm_wfm_i; + else pwm_wfm_o = pwm_wfm_i; + end +end + +//---------------------------------------- +// GPIO Trigger Generation +//---------------------------------------- +logic gpio_l; +wire gpio = pad_gpio[cfg_pwm_gpio_sel]; + +// GPIO Pos and Neg Edge Selection +wire gpio_pe = (gpio & !gpio_l); +wire gpio_ne = (!gpio & gpio_l); + +always @(posedge mclk or negedge h_reset_n) +begin + if ( ~h_reset_n ) begin + gpio_l <= 1'b0; + gpio_tgr <= 1'b0; + end else begin + gpio_l <= gpio; + if(cfg_pwm_enb && cfg_pwm_gpio_enb) begin + gpio_l <= gpio; + if(cfg_pwm_gpio_edge) begin + gpio_tgr <= gpio_ne; + end else begin + gpio_tgr <= gpio_pe; + end + end else begin + gpio_l <= 1'b0; + gpio_tgr <= 1'b0; + end + end +end + + +endmodule
diff --git a/verilog/rtl/pwm/src/pwm_blk_reg.sv b/verilog/rtl/pwm/src/pwm_blk_reg.sv new file mode 100644 index 0000000..9d9554d --- /dev/null +++ b/verilog/rtl/pwm/src/pwm_blk_reg.sv
@@ -0,0 +1,285 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesh.annayya@gmail.com> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// PWM Register //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +//// 0.2 - 13th Sept 2022, Dinesh A //// +//// Change Register to PWM Based //// +////////////////////////////////////////////////////////////////////// +// +module pwm_blk_reg ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + + // Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [1:0] reg_addr , + input logic [31:0] reg_wdata , + input logic [3:0] reg_be , + + // Outputs + output logic [31:0] reg_rdata , + output logic reg_ack , + + input logic cfg_pwm_enb , // PWM operation enable + input logic cfg_pwm_dupdate , // Disable Config update + input logic pwm_cfg_update , // Update the pwm config on roll-over or completion + + output logic [3:0] cfg_pwm_scale , // clock scaling + output logic cfg_pwm_oneshot , // PWM OneShot mode + output logic cfg_pwm_frun , // PWM is free running + output logic cfg_pwm_gpio_enb , // PWM GPIO based trigger enable + output logic cfg_pwm_gpio_edge , // PWM GPIO based trigger edge + output logic [2:0] cfg_pwm_gpio_sel , // GPIO Selection + output logic cfg_pwm_hold , // Hold data PWM data During PWM Disable + output logic cfg_pwm_inv , // invert output + output logic cfg_pwm_zeropd , // Reset on pmw_cnt match to period + output logic [1:0] cfg_pwm_mode , // PWM Pulse Generation mode + output logic cfg_comp0_center , // Compare cnt at comp0 center + output logic cfg_comp1_center , // Compare cnt at comp1 center + output logic cfg_comp2_center , // Compare cnt at comp2 center + output logic cfg_comp3_center , // Compare cnt at comp3 center + output logic [15:0] cfg_pwm_period , // PWM period + output logic [15:0] cfg_pwm_comp0 , // compare0 + output logic [15:0] cfg_pwm_comp1 , // compare1 + output logic [15:0] cfg_pwm_comp2 , // compare2 + output logic [15:0] cfg_pwm_comp3 // compare3 + + ); + +//----------------------------------------------------------------------- +// Internal Wire Declarations +//----------------------------------------------------------------------- + +logic sw_rd_en ; +logic sw_wr_en ; +logic [1:0] sw_addr ; // addressing 16 registers +logic [31:0] sw_reg_wdata ; +logic [3:0] sw_be ; + +logic [31:0] reg_out ; +logic [31:0] reg_0 ; // CONFIG - Unused +logic [31:0] reg_1 ; // PWM-REG-0 +logic [31:0] reg_2 ; // PWM-REG-1 +logic [31:0] reg_3 ; // PWM-REG-2 +logic [31:0] reg_4 ; // PWM-REG-3 +logic [31:0] reg_5 ; // PWM-REG-4 +logic [31:0] reg_6 ; // PWM-REG-5 + +assign sw_addr = reg_addr; +assign sw_rd_en = reg_cs & !reg_wr; +assign sw_wr_en = reg_cs & reg_wr; +assign sw_be = reg_be; +assign sw_reg_wdata = reg_wdata; + +//----------------------------------------------------------------------- +// register read enable and write enable decoding logic +//----------------------------------------------------------------------- +wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0); +wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1); +wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2); +wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3); + +wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0); +wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1); +wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2); +wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3); + + +always @ (posedge mclk or negedge h_reset_n) +begin : preg_out_Seq + if (h_reset_n == 1'b0) begin + reg_rdata <= 'h0; + reg_ack <= 1'b0; + end else if (reg_cs && !reg_ack) begin + reg_rdata <= reg_out; + reg_ack <= 1'b1; + end else begin + reg_ack <= 1'b0; + end +end + +//-------------------------------------------- +// PWM-0 Config +//--------------------------------------------- +logic [31:0] pwm_cfg0; + +assign cfg_pwm_scale = pwm_cfg0[3:0]; +assign cfg_pwm_oneshot = pwm_cfg0[4]; +assign cfg_pwm_frun = pwm_cfg0[5]; +assign cfg_pwm_gpio_enb = pwm_cfg0[6]; +assign cfg_pwm_gpio_edge = pwm_cfg0[7]; // 1 -> negedge +assign cfg_pwm_gpio_sel = pwm_cfg0[10:8]; +assign cfg_pwm_hold = pwm_cfg0[11]; +assign cfg_pwm_mode = pwm_cfg0[13:12]; +assign cfg_pwm_inv = pwm_cfg0[14]; +assign cfg_pwm_zeropd = pwm_cfg0[15]; // Reset on Matching Period +assign cfg_comp0_center = pwm_cfg0[16]; +assign cfg_comp1_center = pwm_cfg0[17]; +assign cfg_comp2_center = pwm_cfg0[18]; +assign cfg_comp3_center = pwm_cfg0[19]; + +gen_32b_reg #(32'h0) u_reg_0 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_0 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_0 ) + ); + +pwm_cfg_dglitch u_dglitch_0 ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + .enb (cfg_pwm_enb ), + .cfg_update (pwm_cfg_update ), + .cfg_dupdate (cfg_pwm_dupdate ), + .reg_in (reg_0 ), + .reg_out (pwm_cfg0 ) + + + ); +//----------------------------------------------------------------------- +// Logic for PWM-1 Config +//----------------------------------------------------------------------- +logic [31:0] pwm_cfg1; +assign cfg_pwm_period = pwm_cfg1[15:0]; + +gen_32b_reg #(32'h0) u_reg_1 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_1 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_1 ) + ); + +pwm_cfg_dglitch u_dglitch_1 ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + .enb (cfg_pwm_enb ), + .cfg_update (pwm_cfg_update ), + .cfg_dupdate (cfg_pwm_dupdate ), + .reg_in (reg_1 ), + .reg_out (pwm_cfg1 ) + + + ); + +//----------------------------------------------------------------------- +// Logic for PWM-2 Config +//----------------------------------------------------------------------- +logic [31:0] pwm_cfg2; +assign cfg_pwm_comp0 = pwm_cfg2[15:0]; // Comparator-0 +assign cfg_pwm_comp1 = pwm_cfg2[31:16]; // Comparator-1 +gen_32b_reg #(32'h0) u_reg_2 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_2 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_2 ) + ); + +pwm_cfg_dglitch u_dglitch_2 ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + .enb (cfg_pwm_enb ), + .cfg_update (pwm_cfg_update ), + .cfg_dupdate (cfg_pwm_dupdate ), + .reg_in (reg_2 ), + .reg_out (pwm_cfg2 ) + + + ); +//----------------------------------------------------------------------- +// Logic for PWM-3 Config +//----------------------------------------------------------------------- +logic [31:0] pwm_cfg3; +assign cfg_pwm_comp2 = reg_3[15:0]; // Comparator-2 +assign cfg_pwm_comp3 = reg_3[31:16]; // Comparator-3 +gen_32b_reg #(32'h0) u_reg_3 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_3 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_3 ) + ); + + +pwm_cfg_dglitch u_dglitch_3 ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + .enb (cfg_pwm_enb ), + .cfg_update (pwm_cfg_update ), + .cfg_dupdate (cfg_pwm_dupdate ), + .reg_in (reg_3 ), + .reg_out (pwm_cfg3 ) + + + ); + +always_comb +begin + reg_out [31:0] = 32'h0; + + case (sw_addr [1:0]) + 2'b00 : reg_out [31:0] = reg_0 [31:0]; + 2'b01 : reg_out [31:0] = reg_1 [31:0]; + 2'b10 : reg_out [31:0] = reg_2 [31:0]; + 2'b11 : reg_out [31:0] = reg_3 [31:0]; + default : reg_out [31:0] = 32'h0; + endcase +end + +endmodule
diff --git a/verilog/rtl/pwm/src/pwm_cfg_dglitch.sv b/verilog/rtl/pwm/src/pwm_cfg_dglitch.sv new file mode 100644 index 0000000..87d536b --- /dev/null +++ b/verilog/rtl/pwm/src/pwm_cfg_dglitch.sv
@@ -0,0 +1,37 @@ + +/************************************************************* + This block added to block abort changing of config during PWM config. + pwm config will be update only in following condition + 1. When pwm is in disable condition + 2. When disable_update = 0 and cfg_update = 1 +*************************************************************/ + + +module pwm_cfg_dglitch ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + input logic enb , // Operation Enable + input logic cfg_update , // Update config + input logic cfg_dupdate , // Disable config update + input logic [31:0] reg_in , + output logic [31:0] reg_out + + ); + + + +always @(posedge mclk or negedge h_reset_n) begin + if ( ~h_reset_n ) begin + reg_out <= 'h0; + end else begin + if(!cfg_dupdate) begin + if(!enb || cfg_update) begin + reg_out <= reg_in; + end + end + end +end + +endmodule
diff --git a/verilog/rtl/pwm/src/pwm_core.sv b/verilog/rtl/pwm/src/pwm_core.sv new file mode 100644 index 0000000..b0bb234 --- /dev/null +++ b/verilog/rtl/pwm/src/pwm_core.sv
@@ -0,0 +1,146 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesh.annayya@gmail.com> +// +////////////////////////////////////////////////////////////////////// +module pwm_core ( + + input logic h_reset_n , + input logic mclk , + +// Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [1:0] reg_addr , + input logic [31:0] reg_wdata , + input logic [3:0] reg_be , + + // Outputs + output logic [31:0] reg_rdata , + output logic reg_ack , + + input logic cfg_pwm_enb , // pwm operation enable + input logic cfg_pwm_run , // pwm operation Run + input logic cfg_pwm_dupdate , // Disable Config update + input logic [7:0] pad_gpio , + output logic pwm_wfm_o , + output logic pwm_os_done , + output logic pwm_ovflow , + output logic gpio_tgr + + + +); + +logic [3:0] cfg_pwm_scale ; // pwm clock scaling +logic cfg_pwm_oneshot ; // pwm OneShot mode +logic cfg_pwm_frun ; // pwm is free running +logic cfg_pwm_gpio_enb ; // pwm gpio based trigger +logic cfg_pwm_gpio_edge ; // pwm gpio based trigger edge +logic [2:0] cfg_pwm_gpio_sel ; // gpio Selection +logic cfg_pwm_hold ; // Hold data pwm data During pwm Disable +logic cfg_pwm_inv ; // invert output +logic cfg_pwm_zeropd ; // Reset on pmw_cnt match to period +logic [1:0] cfg_pwm_mode ; // pwm Pulse Generation mode +logic cfg_comp0_center ; // Compare cnt at comp0 center +logic cfg_comp1_center ; // Compare cnt at comp1 center +logic cfg_comp2_center ; // Compare cnt at comp2 center +logic cfg_comp3_center ; // Compare cnt at comp3 center +logic [15:0] cfg_pwm_period ; // pwm period +logic [15:0] cfg_pwm_comp0 ; // compare0 +logic [15:0] cfg_pwm_comp1 ; // compare1 +logic [15:0] cfg_pwm_comp2 ; // compare2 +logic [15:0] cfg_pwm_comp3 ; // compare3 + + + + +pwm_blk_reg u_reg ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + .reg_cs (reg_cs ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata ), + .reg_ack (reg_ack ), + + .cfg_pwm_enb (cfg_pwm_enb ), // PWM operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate ), // Disable Config update + .pwm_cfg_update (pwm_ovflow ), // Update the pwm config on roll-over or completion + + .cfg_pwm_scale (cfg_pwm_scale ), // clock scaling + .cfg_pwm_oneshot (cfg_pwm_oneshot ), // PWM OneShot mode + .cfg_pwm_frun (cfg_pwm_frun ), // PWM is free running + .cfg_pwm_gpio_enb (cfg_pwm_gpio_enb ), // PWM GPIO based trigger enable + .cfg_pwm_gpio_edge (cfg_pwm_gpio_edge ), // PWM GPIO based trigger edge + .cfg_pwm_gpio_sel (cfg_pwm_gpio_sel ), // GPIO Selection + .cfg_pwm_hold (cfg_pwm_hold ), // Hold data PWM data During PWM Disable + .cfg_pwm_inv (cfg_pwm_inv ), // invert output + .cfg_pwm_zeropd (cfg_pwm_zeropd ), // Reset on pmw_cnt match to period + .cfg_pwm_mode (cfg_pwm_mode ), // PWM Pulse Generation mode + .cfg_comp0_center (cfg_comp0_center ), // Compare cnt at comp0 center + .cfg_comp1_center (cfg_comp1_center ), // Compare cnt at comp1 center + .cfg_comp2_center (cfg_comp2_center ), // Compare cnt at comp2 center + .cfg_comp3_center (cfg_comp3_center ), // Compare cnt at comp3 center + .cfg_pwm_period (cfg_pwm_period ), // PWM period + .cfg_pwm_comp0 (cfg_pwm_comp0 ), // compare0 + .cfg_pwm_comp1 (cfg_pwm_comp1 ), // compare1 + .cfg_pwm_comp2 (cfg_pwm_comp2 ), // compare2 + .cfg_pwm_comp3 (cfg_pwm_comp3 ) // compare3 + + ); + + + +pwm u_pwm ( + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .pwm_wfm_o (pwm_wfm_o ), + .pwm_os_done (pwm_os_done ), + .pwm_ovflow_pe (pwm_ovflow ), + .gpio_tgr (gpio_tgr ), + + .pad_gpio (pad_gpio ), + + .cfg_pwm_enb (cfg_pwm_enb ), + .cfg_pwm_run (cfg_pwm_run ), + .cfg_pwm_scale (cfg_pwm_scale ), + .cfg_pwm_oneshot (cfg_pwm_oneshot ), + .cfg_pwm_frun (cfg_pwm_frun ), + .cfg_pwm_gpio_enb (cfg_pwm_gpio_enb ), + .cfg_pwm_gpio_edge (cfg_pwm_gpio_edge ), + .cfg_pwm_gpio_sel (cfg_pwm_gpio_sel ), + .cfg_pwm_hold (cfg_pwm_hold ), + .cfg_pwm_inv (cfg_pwm_inv ), + .cfg_pwm_zeropd (cfg_pwm_zeropd ), + .cfg_pwm_mode (cfg_pwm_mode ), + .cfg_comp0_center (cfg_comp0_center ), + .cfg_comp1_center (cfg_comp1_center ), + .cfg_comp2_center (cfg_comp2_center ), + .cfg_comp3_center (cfg_comp3_center ), + .cfg_pwm_period (cfg_pwm_period ), + .cfg_pwm_comp0 (cfg_pwm_comp0 ), + .cfg_pwm_comp1 (cfg_pwm_comp1 ), + .cfg_pwm_comp2 (cfg_pwm_comp2 ), + .cfg_pwm_comp3 (cfg_pwm_comp3 ) + ); + +endmodule
diff --git a/verilog/rtl/pwm/src/pwm_glbl_reg.sv b/verilog/rtl/pwm/src/pwm_glbl_reg.sv new file mode 100644 index 0000000..f3d9ae6 --- /dev/null +++ b/verilog/rtl/pwm/src/pwm_glbl_reg.sv
@@ -0,0 +1,228 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesh.annayya@gmail.com> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// PWM Register //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +//// 0.2 - 13th Sept 2022, Dinesh A //// +//// Change Register to PWM Based //// +////////////////////////////////////////////////////////////////////// +// +module pwm_glbl_reg ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + + // Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [1:0] reg_addr , + input logic [31:0] reg_wdata , + input logic [3:0] reg_be , + + // Outputs + output logic [31:0] reg_rdata , + output logic reg_ack , + + output logic [5:0] cfg_pwm_enb , // PWM operation enable + output logic [5:0] cfg_pwm_run , // PWM operation Run + output logic [5:0] cfg_pwm_dupdate , // Disable Config update + + input logic [5:0] pwm_os_done , // Indicate oneshot sequence over + input logic [5:0] pwm_ovflow , // pwm sequence cross over + input logic [5:0] gpio_tgr , // Enable PWM based on trigger + + output logic pwm_intr + + + ); + +//----------------------------------------------------------------------- +// Internal Wire Declarations +//----------------------------------------------------------------------- + +logic sw_rd_en ; +logic sw_wr_en ; +logic [1:0] sw_addr ; // addressing 16 registers +logic [31:0] sw_reg_wdata ; +logic [3:0] sw_be ; + +logic [31:0] reg_out ; +logic [31:0] reg_0 ; // CONFIG - Unused +logic [31:0] reg_1 ; // PWM-REG-0 +logic [31:0] reg_2 ; // PWM-REG-1 +logic [31:0] reg_3 ; // PWM-REG-2 + +assign sw_addr = reg_addr; +assign sw_rd_en = reg_cs & !reg_wr; +assign sw_wr_en = reg_cs & reg_wr; +assign sw_be = reg_be; +assign sw_reg_wdata = reg_wdata; + +//----------------------------------------------------------------------- +// register read enable and write enable decoding logic +//----------------------------------------------------------------------- +wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0); +wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1); +wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2); +wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3); + +wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0); +wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1); +wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2); +wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3); + + +always @ (posedge mclk or negedge h_reset_n) +begin : preg_out_Seq + if (h_reset_n == 1'b0) begin + reg_rdata <= 'h0; + reg_ack <= 1'b0; + end else if (reg_cs && !reg_ack) begin + reg_rdata <= reg_out; + reg_ack <= 1'b1; + end else begin + reg_ack <= 1'b0; + end +end + + +//----------------------------------------- +// PWM Enable Generation +//---------------------------------------- + +assign cfg_pwm_enb = {3'b0,reg_0[2:0]}; +assign cfg_pwm_run = {3'b0,reg_0[10:8]}; +assign cfg_pwm_dupdate = {3'b0,reg_0[18:16]}; + +//------------------------------------------------------------------------ +// Design wise has avoided the pwm_os_done & gpio_tgr occur at same cycle +//------------------------------------------------------------------------ +logic [2:0] reg_0_0; +always @ (posedge mclk or negedge h_reset_n) +begin + if (h_reset_n == 1'b0) begin + reg_0_0[2:0] <= 'h0; + end else if (reg_cs && sw_wr_en_0 && sw_be[0] && reg_ack) begin + reg_0_0[2:0] <= sw_reg_wdata[2:0] ; + end +end +assign reg_0[2:0] = reg_0_0; // Modified due to iverilog issue +assign reg_0[7:3] = 'h0; + +logic [2:0] reg_0_1; +always @ (posedge mclk or negedge h_reset_n) +begin + if (h_reset_n == 1'b0) begin + reg_0_1[2:0] <= 'h0; + end else if (reg_cs && sw_wr_en_0 && sw_be[1] && reg_ack) begin + reg_0_1[2:0] <= sw_reg_wdata[10:8] | gpio_tgr; + end else begin + reg_0_1[2:0] <= (reg_0_1[2:0] | gpio_tgr) ^ pwm_os_done; + end +end +assign reg_0[10:8] = reg_0_1; // Modified due to iverilog issue +assign reg_0[15:11] = 'h0; + +logic [2:0] reg_0_2; +always @ (posedge mclk or negedge h_reset_n) +begin + if (h_reset_n == 1'b0) begin + reg_0_2[2:0] <= 'h0; + end else if (reg_cs && sw_wr_en_0 && sw_be[2] && reg_ack) begin + reg_0_2[2:0] <= sw_reg_wdata[18:16] ; + end +end +assign reg_0[18:16] = reg_0_2; // Modified due to iverilog issue +assign reg_0[31:19] = 'h0; + +//----------------------------------------------------------------------- +// Logic for PWM-1 Config - Reserved +//----------------------------------------------------------------------- +assign reg_1 = 'h0; + + +//----------------------------------------------------------------------- +// Reg-2: Interrupt Mask +//----------------------------------------------------------------------- + +generic_register #(6,6'h0 ) u_reg_2 ( + .we ({6{sw_wr_en_2 & + reg_ack & + sw_be[0] }} ), + .data_in (sw_reg_wdata[5:0] ), + .reset_n (h_reset_n ), + .clk (mclk ), + + //List of Outs + .data_out (reg_2[5:0] ) + ); + +assign reg_2[31:6] = 'h0; +//----------------------------------------------------------------------- +// Reg-3: Interrupt Status +//----------------------------------------------------------------------- + +assign pwm_intr = |(reg_2[5:0] & reg_3[5:0]); + +generic_intr_stat_reg #(.WD(6), + .RESET_DEFAULT(0)) u_reg4 ( + //inputs + .clk (mclk ), + .reset_n (h_reset_n ), + .reg_we ({6{sw_wr_en_3 & + reg_ack & + sw_be[0]}}), + .reg_din ( sw_reg_wdata[5:0] ), + .hware_req ( pwm_ovflow ), + + //outputs + .data_out ( reg_3[5:0] ) + ); + +assign reg_3[31:6] = 'h0; + +always_comb +begin + reg_out [31:0] = 32'h0; + + case (sw_addr [1:0]) + 2'b00 : reg_out [31:0] = reg_0 [31:0]; + 2'b01 : reg_out [31:0] = reg_1 [31:0]; + 2'b10 : reg_out [31:0] = reg_2 [31:0]; + 2'b11 : reg_out [31:0] = reg_3 [31:0]; + default : reg_out [31:0] = 32'h0; + endcase +end + +endmodule
diff --git a/verilog/rtl/pwm/src/pwm_top.sv b/verilog/rtl/pwm/src/pwm_top.sv new file mode 100644 index 0000000..7e914d2 --- /dev/null +++ b/verilog/rtl/pwm/src/pwm_top.sv
@@ -0,0 +1,320 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// PWM Top //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +/// Includes 6 PWM //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +//// 0.2 - 14th Sept 2022, Dinesh A //// +//// Improved PWM logic //// +////////////////////////////////////////////////////////////////////// + +module pwm_top ( + // System Signals + // Inputs + input logic mclk, + input logic h_reset_n, + + // Reg Bus Interface Signal + input logic reg_cs, + input logic reg_wr, + input logic [4:0] reg_addr, + input logic [31:0] reg_wdata, + input logic [3:0] reg_be, + + // Outputs + output logic [31:0] reg_rdata, + output logic reg_ack, + + input logic [7:0] pad_gpio, + output logic [5:0] pwm_wfm , + output logic pwm_intr + + ); + +//--------------------------------------------------- +// 3 PWM variabled +//--------------------------------------------------- + +logic [5:0] cfg_pwm_enb ; +logic [5:0] cfg_pwm_run ; +logic [5:0] cfg_pwm_dupdate ; +logic [5:0] pwm_os_done ; +logic [5:0] pwm_ovflow ; +logic [5:0] gpio_tgr ; +logic reg_cs_glbl ; +logic [5:0] reg_cs_pwm ; +logic reg_ack_glbl ; +logic [31:0] reg_rdata_glbl ; +logic reg_ack_pwm0 ; +logic [31:0] reg_rdata_pwm0 ; +logic reg_ack_pwm1 ; +logic [31:0] reg_rdata_pwm1 ; +logic reg_ack_pwm2 ; +logic [31:0] reg_rdata_pwm2 ; +logic reg_ack_pwm3 ; +logic [31:0] reg_rdata_pwm3 ; +logic reg_ack_pwm4 ; +logic [31:0] reg_rdata_pwm4 ; +logic reg_ack_pwm5 ; +logic [31:0] reg_rdata_pwm5 ; + +//------------------------------------------------------ +// Register Map Decoding + +`define SEL_GLBL 3'b000 // GLOBAL REGISTER +`define SEL_PWM0 3'b001 // PWM-0 +`define SEL_PWM1 3'b010 // PWM-1 +`define SEL_PWM2 3'b011 // PWM-2 +`define SEL_PWM3 3'b100 // PWM-3 +`define SEL_PWM4 3'b101 // PWM-4 +`define SEL_PWM5 3'b110 // PWM-5 + +assign reg_rdata = (reg_addr[4:2] == `SEL_GLBL) ? {reg_rdata_glbl} : + (reg_addr[4:2] == `SEL_PWM0) ? {reg_rdata_pwm0} : + (reg_addr[4:2] == `SEL_PWM1) ? {reg_rdata_pwm1} : + (reg_addr[4:2] == `SEL_PWM2) ? {reg_rdata_pwm2} :'h0; + +assign reg_ack = (reg_addr[4:2] == `SEL_GLBL) ? reg_ack_glbl : + (reg_addr[4:2] == `SEL_PWM0) ? reg_ack_pwm0 : + (reg_addr[4:2] == `SEL_PWM1) ? reg_ack_pwm1 : + (reg_addr[4:2] == `SEL_PWM2) ? reg_ack_pwm2 : 'h0; + +assign reg_cs_glbl = (reg_addr[4:2] == `SEL_GLBL) ? reg_cs : 1'b0; +assign reg_cs_pwm[0] = (reg_addr[4:2] == `SEL_PWM0) ? reg_cs : 1'b0; +assign reg_cs_pwm[1] = (reg_addr[4:2] == `SEL_PWM1) ? reg_cs : 1'b0; +assign reg_cs_pwm[2] = (reg_addr[4:2] == `SEL_PWM2) ? reg_cs : 1'b0; +assign reg_cs_pwm[3] = (reg_addr[4:2] == `SEL_PWM3) ? reg_cs : 1'b0; +assign reg_cs_pwm[4] = (reg_addr[4:2] == `SEL_PWM4) ? reg_cs : 1'b0; +assign reg_cs_pwm[5] = (reg_addr[4:2] == `SEL_PWM5) ? reg_cs : 1'b0; + +pwm_glbl_reg u_glbl_reg ( + .mclk (mclk ), + .h_reset_n (h_reset_n ), + + // Reg Bus Interface Signal + .reg_cs (reg_cs_glbl ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + // Outputs + .reg_rdata (reg_rdata_glbl ), + .reg_ack (reg_ack_glbl ), + + .cfg_pwm_enb (cfg_pwm_enb ), + .cfg_pwm_run (cfg_pwm_run ), + .cfg_pwm_dupdate (cfg_pwm_dupdate ), + + .pwm_os_done (pwm_os_done ), + .pwm_ovflow (pwm_ovflow ), + .gpio_tgr (gpio_tgr ), + + .pwm_intr (pwm_intr ) + + + ); + + +// 6 PWM Waveform Generator + +pwm_core u_pwm_0( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[0] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm0 ), + .reg_ack (reg_ack_pwm0 ), + + .cfg_pwm_enb (cfg_pwm_enb[0] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[0] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[0] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[0] ), + .pwm_ovflow (pwm_ovflow[0] ), + .gpio_tgr (gpio_tgr[0] ), + .pwm_wfm_o (pwm_wfm[0] ) + +); + +pwm_core u_pwm_1( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[1] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm1 ), + .reg_ack (reg_ack_pwm1 ), + + .cfg_pwm_enb (cfg_pwm_enb[1] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[1] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[1] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[1] ), + .pwm_ovflow (pwm_ovflow[1] ), + .gpio_tgr (gpio_tgr[1] ), + .pwm_wfm_o (pwm_wfm[1] ) + +); +pwm_core u_pwm_2( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[2] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm2 ), + .reg_ack (reg_ack_pwm2 ), + + .cfg_pwm_enb (cfg_pwm_enb[2] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[2] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[2] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[2] ), + .pwm_ovflow (pwm_ovflow[2] ), + .gpio_tgr (gpio_tgr[2] ), + .pwm_wfm_o (pwm_wfm[2] ) + +); + + +/*** +pwm_core u_pwm_3( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[3] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm3 ), + .reg_ack (reg_ack_pwm3 ), + + .cfg_pwm_enb (cfg_pwm_enb[3] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[3] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[3] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[3] ), + .pwm_ovflow (pwm_ovflow[3] ), + .gpio_tgr (gpio_tgr[3] ), + .pwm_wfm_o (pwm_wfm[3] ) + +); +***/ +assign pwm_wfm[3] = pwm_wfm[0]; +assign pwm_os_done[3] = 1'b0; +assign pwm_ovflow[3] = 1'b0; +assign gpio_tgr[3] = 1'b0; + +/**** +pwm_core u_pwm_4( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[4] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm4 ), + .reg_ack (reg_ack_pwm4 ), + + .cfg_pwm_enb (cfg_pwm_enb[4] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[4] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[4] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[4] ), + .pwm_ovflow (pwm_ovflow[4] ), + .gpio_tgr (gpio_tgr[4] ), + .pwm_wfm_o (pwm_wfm[4] ) + +); +***/ +assign pwm_wfm[4] = pwm_wfm[1]; +assign pwm_os_done[4] = 1'b0; +assign pwm_ovflow[4] = 1'b0; +assign gpio_tgr[4] = 1'b0; + +/*** +pwm_core u_pwm_5( + + .h_reset_n (h_reset_n ), + .mclk (mclk ), + + .reg_cs (reg_cs_pwm[5] ), + .reg_wr (reg_wr ), + .reg_addr (reg_addr[1:0] ), + .reg_wdata (reg_wdata ), + .reg_be (reg_be ), + + .reg_rdata (reg_rdata_pwm5 ), + .reg_ack (reg_ack_pwm5 ), + + .cfg_pwm_enb (cfg_pwm_enb[5] ), // pwm operation enable + .cfg_pwm_run (cfg_pwm_run[5] ), // pwm operation enable + .cfg_pwm_dupdate (cfg_pwm_dupdate[5] ), // Disable Config update + .pad_gpio (pad_gpio ), + .pwm_os_done (pwm_os_done[5] ), + .pwm_ovflow (pwm_ovflow[5] ), + .gpio_tgr (gpio_tgr[5] ), + .pwm_wfm_o (pwm_wfm[5] ) + +); + +**/ +assign pwm_wfm[5] = pwm_wfm[2]; +assign pwm_os_done[5] = 1'b0; +assign pwm_ovflow[5] = 1'b0; +assign gpio_tgr[5] = 1'b0; + +endmodule
diff --git a/verilog/rtl/sspim/src/sspim_top.sv b/verilog/rtl/sspim/src/sspim_top.sv index 6f0f17f..97a3cae 100755 --- a/verilog/rtl/sspim/src/sspim_top.sv +++ b/verilog/rtl/sspim/src/sspim_top.sv
@@ -132,6 +132,13 @@ logic cfg_cpol ; // spi clock idle phase logic cfg_cpha ; // spi data sample and lanch phase +logic shift ; +logic sample ; +logic sck_int ; +logic sck_active ; +logic cs_int_n ; +logic load_byte ; + sspim_if u_spi_if ( . clk (clk ),
diff --git a/verilog/rtl/timer/src/timer.sv b/verilog/rtl/timer/src/timer.sv new file mode 100755 index 0000000..55b7349 --- /dev/null +++ b/verilog/rtl/timer/src/timer.sv
@@ -0,0 +1,66 @@ + +module timer + ( + input logic reset_n, // system syn reset + input logic mclk, // master clock + input logic pulse_1us, + input logic pulse_1ms, + input logic pulse_1s, + + input logic cfg_timer_enb, + input logic cfg_timer_update, + input logic [15:0] cfg_timer_compare, + input logic [1:0] cfg_timer_clksel, // to select the timer 1us/1ms reference clock + + output logic timer_intr + + ); + + + + +reg timer_hit_s1; +wire timer_hit; +reg [15:0] timer_counter; +wire timer_pulse; + + +// select between 1us timer and 1ms timer +assign timer_pulse = (cfg_timer_clksel == 2'b00) ? pulse_1us : + (cfg_timer_clksel == 2'b01) ? pulse_1ms : pulse_1s; + + +/************************************************ + Timer Counter +************************************************/ +always @(negedge reset_n or posedge mclk) +begin + if (!reset_n) + timer_counter <= 16'b0; + else if (cfg_timer_update || (timer_pulse && timer_hit)) + timer_counter <= cfg_timer_compare; + else if (timer_pulse && cfg_timer_enb) + timer_counter <= timer_counter - 1; +end + + + +/*********************************************** + Timer Interrupt Generation +***********************************************/ + assign timer_hit = (timer_counter == 1'b0); + + assign timer_intr = !timer_hit_s1 && timer_hit && cfg_timer_enb; + + + always @(negedge reset_n or posedge mclk) + begin + if (!reset_n) begin + timer_hit_s1 <= 1'b1; + end else begin + timer_hit_s1 <= timer_hit; + end + end + + +endmodule
diff --git a/verilog/rtl/timer/src/timer_reg.sv b/verilog/rtl/timer/src/timer_reg.sv new file mode 100644 index 0000000..1a561f6 --- /dev/null +++ b/verilog/rtl/timer/src/timer_reg.sv
@@ -0,0 +1,212 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// Timer Register //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// +// +module timer_reg ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + + // Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [1:0] reg_addr , + input logic [31:0] reg_wdata , + input logic [3:0] reg_be , + + // Outputs + output logic [31:0] reg_rdata , + output logic reg_ack , + + output logic [9:0] cfg_pulse_1us , + output logic [2:0] cfg_timer_update , // CPU write to timer register + output logic [18:0] cfg_timer0 , // Timer-0 register + output logic [18:0] cfg_timer1 , // Timer-1 register + output logic [18:0] cfg_timer2 // Timer-2 register + + ); + +//----------------------------------------------------------------------- +// Internal Wire Declarations +//----------------------------------------------------------------------- + +logic sw_rd_en ; +logic sw_wr_en ; +logic [1:0] sw_addr ; // addressing 16 registers +logic [31:0] sw_reg_wdata ; +logic [3:0] sw_be ; + +logic [31:0] reg_out ; +logic [31:0] reg_0 ; // TIMER GLOBAL CONFIG +logic [31:0] reg_1 ; // TIMER-0 +logic [31:0] reg_2 ; // TIMER-1 +logic [31:0] reg_3 ; // TIMER-2 + +assign sw_addr = reg_addr; +assign sw_rd_en = reg_cs & !reg_wr; +assign sw_wr_en = reg_cs & reg_wr; +assign sw_be = reg_be; +assign sw_reg_wdata = reg_wdata; + +//----------------------------------------------------------------------- +// register read enable and write enable decoding logic +//----------------------------------------------------------------------- +wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0); +wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1); +wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2); +wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3); + +wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0); +wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1); +wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2); +wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3); + + +always @ (posedge mclk or negedge h_reset_n) +begin : preg_out_Seq + if (h_reset_n == 1'b0) begin + reg_rdata <= 'h0; + reg_ack <= 1'b0; + end else if (reg_cs && !reg_ack) begin + reg_rdata <= reg_out; + reg_ack <= 1'b1; + end else begin + reg_ack <= 1'b0; + end +end + + +//---------------------------------------------- +// reg-0: GLBL_CFG +//------------------------------------------ + +gen_32b_reg #('h0) u_reg_0 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_0 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_0 ) + ); + +assign cfg_pulse_1us = reg_0[9:0]; + +//----------------------------------------------------------------------- +// reg-1 +// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle +// In first cycle, local register will be updated +// In second cycle, update indication sent to timer block +// ----------------------------------------------------------------- +assign cfg_timer0 = reg_1[18:0]; +assign cfg_timer_update[0] = sw_wr_en_1 & reg_ack; + +gen_32b_reg #(32'h0) u_reg_1 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_1 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_1[31:0] ) + ); + +//----------------------------------------------------------------------- +// reg-2 +// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle +// In first cycle, local register will be updated +// In second cycle, update indication sent to timer block +// ----------------------------------------------------------------- +assign cfg_timer1 = reg_2[18:0]; +assign cfg_timer_update[1] = sw_wr_en_2 & reg_ack; + +gen_32b_reg #(32'h0) u_reg_2 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_2 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_2[31:0] ) + ); + + +//----------------------------------------------------------------------- +// reg-3 +// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle +// In first cycle, local register will be updated +// In second cycle, update indication sent to timer block +// ----------------------------------------------------------------- +assign cfg_timer2 = reg_3[18:0]; +assign cfg_timer_update[2] = sw_wr_en_3 & reg_ack; + +gen_32b_reg #(32'h0) u_reg_3 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_3 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_3[31:0] ) + ); + +//----------------------------------------------------------------------- +// Register Read Path Multiplexer instantiation +//----------------------------------------------------------------------- + +always_comb +begin + reg_out [31:0] = 32'h0; + + case (sw_addr [1:0]) + 2'b00 : reg_out [31:0] = reg_0 [31:0]; + 2'b01 : reg_out [31:0] = reg_1 [31:0]; + 2'b10 : reg_out [31:0] = reg_2 [31:0]; + 2'b11 : reg_out [31:0] = reg_3 [31:0]; + default : reg_out [31:0] = 32'h0; + endcase +end + +endmodule
diff --git a/verilog/rtl/timer/src/timer_top.sv b/verilog/rtl/timer/src/timer_top.sv new file mode 100644 index 0000000..c6aa3f9 --- /dev/null +++ b/verilog/rtl/timer/src/timer_top.sv
@@ -0,0 +1,191 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// Timer Top //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 15th Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// + +module timer_top ( + // System Signals + // Inputs + input logic mclk, + input logic h_reset_n, + + // Reg Bus Interface Signal + input logic reg_cs, + input logic reg_wr, + input logic [1:0] reg_addr, + input logic [31:0] reg_wdata, + input logic [3:0] reg_be, + + // Outputs + output logic [31:0] reg_rdata, + output logic reg_ack, + + output logic pulse_1ms, + output logic pulse_1us, + output logic [2:0] timer_intr + + ); + +//--------------------------------------------------------- +// Timer Register +// ------------------------------------------------------- +logic [2:0] cfg_timer_update ; // CPU write to timer register +logic [18:0] cfg_timer0 ; // Timer-0 register +logic [18:0] cfg_timer1 ; // Timer-1 register +logic [18:0] cfg_timer2 ; // Timer-2 register + +/* clock pulse */ +//******************************************************** +logic pulse_1s ; // 1Second Pulse for waveform Generator +logic [9:0] cfg_pulse_1us ; // 1us pulse generation config + +timer_reg u_reg ( + .mclk (mclk ), + .h_reset_n (h_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 ), + + .cfg_pulse_1us (cfg_pulse_1us ), + .cfg_timer_update (cfg_timer_update ), + .cfg_timer0 (cfg_timer0 ), + .cfg_timer1 (cfg_timer1 ), + .cfg_timer2 (cfg_timer2 ) + + ); + +// 1us pulse +pulse_gen_type2 #(.WD(10)) u_pulse_1us ( + + .clk_pulse_o (pulse_1us ), + .clk (mclk ), + .reset_n (h_reset_n ), + .cfg_max_cnt (cfg_pulse_1us ) + + ); + +// 1us/1000 to 1millisecond pulse +pulse_gen_type1 u_pulse_1ms ( + + .clk_pulse_o (pulse_1ms ), + .clk (mclk ), + .reset_n (h_reset_n ), + .trigger (pulse_1us ) + + ); + +// 1ms/1000 => 1 second pulse +pulse_gen_type1 u_pulse_1s ( + + .clk_pulse_o (pulse_1s ), + .clk (mclk ), + .reset_n (h_reset_n ), + .trigger (pulse_1ms ) + + ); + +// Timer + +wire [1:0] cfg_timer0_clksel = cfg_timer0[18:17]; +wire cfg_timer0_enb = cfg_timer0[16]; +wire [15:0] cfg_timer0_compare = cfg_timer0[15:0]; + +timer u_timer_0 + ( + .reset_n (h_reset_n ),// system syn reset + .mclk (mclk ),// master clock + .pulse_1us (pulse_1us ), + .pulse_1ms (pulse_1ms ), + .pulse_1s (pulse_1s ), + + .cfg_timer_update (cfg_timer_update[0] ), + .cfg_timer_enb (cfg_timer0_enb ), + .cfg_timer_compare (cfg_timer0_compare ), + .cfg_timer_clksel (cfg_timer0_clksel ),// to select the timer 1us/1ms reference clock + + .timer_intr (timer_intr[0] ) + ); + +// Timer +wire [1:0] cfg_timer1_clksel = cfg_timer1[18:17]; +wire cfg_timer1_enb = cfg_timer1[16]; +wire [15:0] cfg_timer1_compare = cfg_timer1[15:0]; +timer u_timer_1 + ( + .reset_n (h_reset_n ),// system syn reset + .mclk (mclk ),// master clock + .pulse_1us (pulse_1us ), + .pulse_1ms (pulse_1ms ), + .pulse_1s (pulse_1s ), + + .cfg_timer_update (cfg_timer_update[1] ), + .cfg_timer_enb (cfg_timer1_enb ), + .cfg_timer_compare (cfg_timer1_compare ), + .cfg_timer_clksel (cfg_timer1_clksel ),// to select the timer 1us/1ms reference clock + + .timer_intr (timer_intr[1] ) + ); + +// Timer +wire [1:0] cfg_timer2_clksel = cfg_timer2[18:17]; +wire cfg_timer2_enb = cfg_timer2[16]; +wire [15:0] cfg_timer2_compare = cfg_timer2[15:0]; + +timer u_timer_2 + ( + .reset_n (h_reset_n ),// system syn reset + .mclk (mclk ),// master clock + .pulse_1us (pulse_1us ), + .pulse_1ms (pulse_1ms ), + .pulse_1s (pulse_1s ), + + .cfg_timer_update (cfg_timer_update[2] ), + .cfg_timer_enb (cfg_timer2_enb ), + .cfg_timer_compare (cfg_timer2_compare ), + .cfg_timer_clksel (cfg_timer2_clksel ),// to select the timer 1us/1ms reference clock + + .timer_intr (timer_intr[2] ) + ); + + +endmodule
diff --git a/verilog/rtl/uart/src/uart_cfg.sv b/verilog/rtl/uart/src/uart_cfg.sv index ca4dea6..14297c4 100644 --- a/verilog/rtl/uart/src/uart_cfg.sv +++ b/verilog/rtl/uart/src/uart_cfg.sv
@@ -271,17 +271,17 @@ 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'b0101 : reg_out [7:0] = 'h0; 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]; + 4'b1001 : reg_out [7:0] = 'h0; + 4'b1010 : reg_out [7:0] = 'h0; + 4'b1011 : reg_out [7:0] = 'h0; + 4'b1100 : reg_out [7:0] = 'h0; + 4'b1101 : reg_out [7:0] = 'h0; + 4'b1110 : reg_out [7:0] = 'h0; + 4'b1111 : reg_out [7:0] = 'h0; endcase end
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv index 653e285..b9b0186 100644 --- a/verilog/rtl/uart/src/uart_core.sv +++ b/verilog/rtl/uart/src/uart_core.sv
@@ -192,6 +192,7 @@ //############################################################### wire line_clk_16x_in; +wire line_clk_16x; // OpenSource CTS tool does not work with buffer as source point // changed buf to max with select tied=0
diff --git a/verilog/rtl/uart2wb/src/uart2wb.sv b/verilog/rtl/uart2wb/src/uart2wb.sv index 0bf50b3..25e6e2f 100755 --- a/verilog/rtl/uart2wb/src/uart2wb.sv +++ b/verilog/rtl/uart2wb/src/uart2wb.sv
@@ -29,6 +29,10 @@ //// Author(s): //// //// - Dinesh Annayya, dinesha@opencores.org //// //// //// +//// Revision : //// +//// 0.1 - 12th Sep 2022, Dinesh A //// +//// baud config auto detect for unknow system clock case//// +//// implemented specific to unknown caravel system clk //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Authors and OPENCORES.ORG //// @@ -61,11 +65,12 @@ input wire app_clk , // sys clock // configuration control + input wire cfg_auto_det , // Auto Baud Config detect mode input wire cfg_tx_enable , // Enable Transmit Path input wire cfg_rx_enable , // Enable Received Path input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd - input wire [11:0] cfg_baud_16x , // 16x Baud clock generation + input wire [11:0] cfg_baud_16x , // 16x Baud clock generation // Master Port output wire wbm_cyc_o , // strobe/request @@ -80,7 +85,7 @@ // Status information output wire frm_error , // framing error - output wire par_error , // par error + output wire par_error , // par error output wire baud_clk_16x , // 16x Baud clock @@ -122,9 +127,26 @@ wire rx_wr ; // Valid RXD Data wire line_reset_n ; +wire arst_ssn ; +wire [11:0] auto_baud_16x ; +wire auto_tx_enb ; +wire auto_rx_enb ; + + +wire cfg_tx_enable_i = (cfg_auto_det) ? auto_tx_enb: cfg_tx_enable; +wire cfg_rx_enable_i = (cfg_auto_det) ? auto_rx_enb: cfg_rx_enable; +wire [11:0] cfg_baud_16x_i = (cfg_auto_det) ? auto_baud_16x: cfg_baud_16x; + assign wbm_cyc_o = wbm_stb_o; +reset_sync u_arst_sync ( + .scan_mode (1'b0 ), + .dclk (app_clk ), // Destination clock domain + .arst_n (arst_n ), // active low async reset + .srst_n (arst_ssn ) + ); + // Async App clock to Uart clock handling @@ -148,7 +170,7 @@ // Target Declaration .out_clk (app_clk), - .out_reset_n (arst_n), + .out_reset_n (arst_ssn), // Reg Bus Slave // output .out_reg_cs (wbm_stb_o), @@ -163,16 +185,30 @@ ); + +uart_auto_det u_aut_det ( + .mclk (app_clk ), + .reset_n (arst_ssn ), + .cfg_auto_det (cfg_auto_det ), + .rxd (rxd ), + + .auto_baud_16x (auto_baud_16x ), + .auto_tx_enb (auto_tx_enb ), + .auto_rx_enb (auto_rx_enb ) + + ); + + uart2_core u_core ( .arst_n (arst_n) , .app_clk (app_clk) , // configuration control - .cfg_tx_enable (cfg_tx_enable) , - .cfg_rx_enable (cfg_rx_enable) , + .cfg_tx_enable (cfg_tx_enable_i) , + .cfg_rx_enable (cfg_rx_enable_i) , .cfg_stop_bit (cfg_stop_bit) , .cfg_pri_mod (cfg_pri_mod) , - .cfg_baud_16x (cfg_baud_16x) , + .cfg_baud_16x (cfg_baud_16x_i) , // TXD Information .tx_data_avail (tx_data_avail) , @@ -187,10 +223,10 @@ // Status information .frm_error (frm_error) , - .par_error (par_error) , + .par_error (par_error) , - .baud_clk_16x (baud_clk_16x) , - .line_reset_n (line_reset_n), + .baud_clk_16x (baud_clk_16x) , + .line_reset_n (line_reset_n), // Line Interface .rxd (rxd) , @@ -201,8 +237,9 @@ uart_msg_handler u_msg ( - .reset_n (arst_n ) , + .reset_n (line_reset_n ) , .sys_clk (baud_clk_16x ) , + .cfg_uart_enb (cfg_tx_enable_i), // UART-TX Information
diff --git a/verilog/rtl/uart2wb/src/uart_auto_det.sv b/verilog/rtl/uart2wb/src/uart_auto_det.sv new file mode 100644 index 0000000..1507c77 --- /dev/null +++ b/verilog/rtl/uart2wb/src/uart_auto_det.sv
@@ -0,0 +1,163 @@ +/********************************************************* + This block try to auto detect the baud-16x value for incoming 9600 data. + Here the System clock is unknown, As in caravel user_clock can be any thing between + 4Mhz to 60Mhz. + + local counter width: 20bit should be good enough the check idle OR struck at low state + Assumption is 9600 Baud => 0.104ms per bit => 1.04ms per chapter (Assumpting 10 bit per character including start+ parity bit) + With System clock 100Mhz, 1.04ms => 1,000,000 clock count, which can be easily check by 20 bit count => 2^20 = 1048576 + + + 1.Input data in double sync with local clock + 2. State: IDLE: Wait for High to low edge, + On Fall edge, STATE = POS_EDGE + 2. State: POS_EDGE1: + Wait for Pos edge, If Pos edge detected, STATE= NEG_EDGE1 + increase local clk_cnt, if counter each 0xF_FFFF without transition, move to State: IDLE + 3. State: NEG_EDGE1: + Wait for Neg edge, If Neg edge detected, capture the clk_cnt => ref1_cnt; State: POS_EDGE2 + if counter reached 0xF_FFFF without transition, then STATE: IDLE + + 4. State: POS_EDGE2: + Wait for Pos edge, If Pos edge detected, STATE= NEG_EDGE2 + increase local clk_cnt, if counter each 0xF_FFFF without transition, move to State: IDLE + 5. State: NEG_EDGE2: + Wait for Neg edge, If Neg edge detected, capture the clk_cnt => ref2_cnt; State: COMPUTE + if counter reached 0xF_FFFF without transition, then STATE: IDLE + 6. State: COMPUTE + if difference between ref1_cnt and ref2_cnt less than 16, then average out and divide by 16, Sub by 2, + and update Baud Value and STOP_EDGE + 7. STATE:STOP_EDGE Wait pos edge, if timeout then go to IDLE, else enable tx/rx + ***************************************************************************/ +module uart_auto_det ( + input logic mclk , + input logic reset_n , + input logic cfg_auto_det , + input logic rxd , + + output logic [11:0] auto_baud_16x , + output logic auto_tx_enb , + output logic auto_rx_enb + + ); + +parameter IDLE = 3'b000; +parameter POS_EDGE1 = 3'b001; +parameter NEG_EDGE1 = 3'b010; +parameter POS_EDGE2 = 3'b011; +parameter NEG_EDGE2 = 3'b100; +parameter COMPUTE = 3'b101; +parameter STOP_EDGE = 3'b110; +parameter AUTO_DONE = 3'b111; + + +logic [19:0] clk_cnt,ref1_cnt,ref2_cnt,ref_diff,baud_16x; +logic [2:0] state; +logic [2:0] rxd_sync; +logic timeout; +logic rxd_pedge; +logic rxd_nedge; + +assign timeout = (clk_cnt == 20'hF_FFFF); +assign rxd_pedge = (rxd_sync[2] == 1'b0) & (rxd_sync[1] == 1'b1); +assign rxd_nedge = (rxd_sync[2] == 1'b1) & (rxd_sync[1] == 1'b0); +assign ref_diff = (ref1_cnt > ref2_cnt) ? (ref1_cnt - ref2_cnt) : (ref2_cnt - ref1_cnt); + +assign baud_16x = (((ref1_cnt + ref2_cnt) >> 1) >> 4); + +always @(negedge reset_n or posedge mclk) +begin + if(reset_n == 1'b0) begin + state <= IDLE; + clk_cnt <= 'b0; + ref1_cnt <= 'b0; + ref1_cnt <= 'b0; + auto_baud_16x <= 'b0; + auto_tx_enb <= 'b0; + auto_rx_enb <= 'b0; + rxd_sync <= 'b0; + end else begin + rxd_sync <= {rxd_sync[1:0],rxd}; + case(state) + IDLE : begin + if(cfg_auto_det && rxd_nedge) begin + clk_cnt <= 'h0; + state <= POS_EDGE1; + end + end + POS_EDGE1 : begin + if(rxd_pedge) begin + clk_cnt <= 'h0; + state <= NEG_EDGE1; + end else if(timeout) begin + state <= IDLE; + end else begin + clk_cnt <= clk_cnt + 1; + end + end + NEG_EDGE1 : begin + if(rxd_nedge) begin + ref1_cnt <= clk_cnt; + clk_cnt <= 'h0; + state <= POS_EDGE2; + end else if(timeout) begin + state <= IDLE; + end else begin + clk_cnt <= clk_cnt + 1; + end + end + POS_EDGE2 : begin + if(rxd_pedge) begin + clk_cnt <= 'h0; + state <= NEG_EDGE2; + end else if(timeout) begin + state <= IDLE; + end else begin + clk_cnt <= clk_cnt + 1; + end + end + NEG_EDGE2 : begin + if(rxd_nedge) begin + ref2_cnt <= clk_cnt; + clk_cnt <= 'h0; + state <= COMPUTE; + end else if(timeout) begin + state <= IDLE; + end else begin + clk_cnt <= clk_cnt + 1; + end + end + COMPUTE: begin + if(ref_diff < 16) begin + // Average it, Generate Div-16 + Additional Sub by 2 is due to clk_ctl module div n implementation + if(baud_16x > 1) + auto_baud_16x <= baud_16x -1; + else + auto_baud_16x <= 0; + state <= STOP_EDGE; + end else begin + state <= IDLE; + end + end + STOP_EDGE : begin + if(rxd_pedge) begin + state <= AUTO_DONE; + end else if(timeout) begin + state <= IDLE; + end else begin + clk_cnt <= clk_cnt + 1; + end + end + AUTO_DONE: begin + auto_tx_enb <= 1'b1; + auto_rx_enb <= 1'b1; + end + endcase + + end +end + + +endmodule + +
diff --git a/verilog/rtl/uart2wb/src/uart_msg_handler.v b/verilog/rtl/uart2wb/src/uart_msg_handler.v index e6436e5..860c073 100755 --- a/verilog/rtl/uart2wb/src/uart_msg_handler.v +++ b/verilog/rtl/uart2wb/src/uart_msg_handler.v
@@ -44,6 +44,7 @@ module uart_msg_handler ( reset_n , sys_clk , + cfg_uart_enb, // UART-TX Information @@ -69,16 +70,17 @@ // Define the Message Hanlde States -`define IDLE 4'h0 -`define IDLE_TX_MSG1 4'h1 -`define IDLE_TX_MSG2 4'h2 -`define RX_CMD_PHASE 4'h3 -`define ADR_PHASE 4'h4 -`define WR_DATA_PHASE 4'h5 -`define SEND_WR_REQ 4'h6 -`define SEND_RD_REQ 4'h7 -`define SEND_RD_DATA 4'h8 -`define TX_MSG 4'h9 +`define POWERON_WAIT 4'h0 +`define IDLE 4'h1 +`define IDLE_TX_MSG1 4'h2 +`define IDLE_TX_MSG2 4'h3 +`define RX_CMD_PHASE 4'h4 +`define ADR_PHASE 4'h5 +`define WR_DATA_PHASE 4'h6 +`define SEND_WR_REQ 4'h7 +`define SEND_RD_REQ 4'h8 +`define SEND_RD_DATA 4'h9 +`define TX_MSG 4'hA `define BREAK_CHAR 8'h0A @@ -88,6 +90,7 @@ input reset_n ; // line reset input sys_clk ; // line clock +input cfg_uart_enb ; //-------------------------------------- @@ -131,7 +134,7 @@ reg [31:0] reg_wdata ; // reg_addr reg reg_wr ; // 1 -> Reg Write request, 0 -> Read Requestion reg reg_req ; // 1 -> Register request - +reg [7:0] wait_cnt ; wire rx_ready = 1; /**************************************************************** @@ -164,17 +167,27 @@ reg_addr <= 0; reg_wr <= 1'b0; // Read request reg_wdata <= 0; - State <= `IDLE; - NextState <= `IDLE; + State <= `POWERON_WAIT; + NextState <= `POWERON_WAIT; + wait_cnt <= 'h0; end else begin case(State) // Send Default Message + `POWERON_WAIT: begin + if(cfg_uart_enb) begin + if(wait_cnt == 8'hff) begin + State <= `IDLE; + end else begin + wait_cnt <= wait_cnt+1; + end + end + end `IDLE: begin - TxMsgBuf <= "Command Format:\n"; // Align to 16 character format by appending space character - TxMsgSize <= 16; - tx_data_avail <= 0; - State <= `TX_MSG; - NextState <= `IDLE_TX_MSG1; + TxMsgBuf <= "Command Format:\n"; // Align to 16 character format by appending space character + TxMsgSize <= 16; + tx_data_avail <= 0; + State <= `TX_MSG; + NextState <= `IDLE_TX_MSG1; end // Send Default Message (Contd..)
diff --git a/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v index f83656d..83d444c 100644 --- a/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v +++ b/verilog/rtl/usb1_host/src/phy/usb_fs_phy.v
@@ -633,7 +633,6 @@ //----------------------------------------------------------------- // Tx //----------------------------------------------------------------- -wire out_bit_w = sample_w ? data_q[0] : 1'bz; always @ (posedge clk_i or negedge rstn_i) if (!rstn_i)
diff --git a/verilog/rtl/user_params.svh b/verilog/rtl/user_params.svh index a8b8341..325c436 100644 --- a/verilog/rtl/user_params.svh +++ b/verilog/rtl/user_params.svh
@@ -4,11 +4,11 @@ // ASCI Representation of RISC = 32'h8273_8343 parameter CHIP_SIGNATURE = 32'h8273_8343; // Software Reg-1, Release date: <DAY><MONTH><YEAR> -parameter CHIP_RELEASE_DATE = 32'h0709_2022; +parameter CHIP_RELEASE_DATE = 32'h1409_2022; // Software Reg-2: Poject Revison 5.1 = 0005200 -parameter CHIP_REVISION = 32'h0005_4000; +parameter CHIP_REVISION = 32'h0005_5000; -parameter SKEW_RESET_VAL = 32'b0000_0000_1000_0111_1001_1000_1001_1000; +parameter SKEW_RESET_VAL = 32'b0000_0000_1000_0111_1001_1000_1001_0111; parameter PSTRAP_DEFAULT_VALUE = 15'b000_0111_1010_0000; @@ -48,9 +48,9 @@ 2'b10 - Default value + 4 2'b11 - Default value - 4 bit [4:13] - uart master config control - 2'b00 - constant value based on system clock-50Mhz (Default) - 2'b01 - constant value based on system clock-40Mhz - 2'b10 - constant value based on system clock-60Mhz (USB Ref Clock) + 2'b00 - Auto Detect (Default) + 2'b01 - constant value based on system clock-50Mhz + 2'b10 - constant value based on system clock-4Mhz 2'b11 - load from LA bit[15] - Strap Mode
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index 0373cc9..f6d483d 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v
@@ -270,7 +270,13 @@ //// boot up config //// //// 2'b00 - 50Mhz, 2'b01 - 40Mhz, 2'b10 - 50Mhz, //// //// 2'b11 - LA control //// -//// //// +//// 5.5 Sept 14 2022, Dinesh A //// +//// A. Auto Baud detection added in uart master as //// +//// power on user_clock1 is not decided, strap def //// +//// changed //// +//// 2'b00 - Auto, 2'b01 - 50Mhz, 2'b10 - 4Mhz, //// +//// 2'b11 - LA control //// +//// B. digital_pll is re-synth with maual placement //// //// //// ////////////////////////////////////////////////////////////////////// //// //// @@ -747,6 +753,11 @@ wire [1:0] pll_clk_out ; // Two 90 degree clock phases wire [3:0] spi_csn ; +wire xtal_clk ; +wire e_reset_n ; +wire p_reset_n ; +wire s_reset_n ; +wire cfg_strap_pad_ctrl ; //--------------------------------------------------------------------- // Strap
diff --git a/verilog/rtl/user_reg_map.v b/verilog/rtl/user_reg_map.v index ff6a316..28b4293 100644 --- a/verilog/rtl/user_reg_map.v +++ b/verilog/rtl/user_reg_map.v
@@ -68,13 +68,34 @@ //-------------------------------------------------- // PWM Register // ------------------------------------------------- -`define PWM_GLBL_CFG 8'h00 // reg_0 - PWM Global Config -`define PWM_CFG_PWM_0 8'h04 // reg_1 - PWM Reg-0 -`define PWM_CFG_PWM_1 8'h08 // reg_2 - PWM Reg-1 -`define PWM_CFG_PWM_2 8'h0C // reg_3 - PWM Reg-2 -`define PWM_CFG_PWM_3 8'h10 // reg_4 - PWM Reg-3 -`define PWM_CFG_PWM_4 8'h14 // reg_5 - PWM Reg-4 -`define PWM_CFG_PWM_5 8'h18 // reg_6 - PWM Reg-5 +`define PWM_GLBL_CFG0 8'h00 // reg_0 - PWM Global Config-0 +`define PWM_GLBL_CFG1 8'h04 // reg_1 - PWM Global Config-1 +`define PWM_GLBL_INTR_MASK 8'h08 // reg_2 - PWM Global Interrupt Status +`define PWM_GLBL_INTR_STAT 8'h0C // reg_3 - PWM Global Interrupt Mask +`define PWM_BLK0_CFG0 8'h10 // reg_0 - PWM BLK-0 Reg-0 +`define PWM_BLK0_CFG1 8'h14 // reg_1 - PWM BLK-0 Reg-1 +`define PWM_BLK0_CFG2 8'h18 // reg_2 - PWM BLK-0 Reg-2 +`define PWM_BLK0_CFG3 8'h1C // reg_3 - PWM BLK-0 Reg-3 +`define PWM_BLK1_CFG0 8'h20 // reg_0 - PWM BLK-1 Reg-0 +`define PWM_BLK1_CFG1 8'h24 // reg_1 - PWM BLK-1 Reg-1 +`define PWM_BLK1_CFG2 8'h28 // reg_2 - PWM BLK-1 Reg-2 +`define PWM_BLK1_CFG3 8'h2C // reg_3 - PWM BLK-1 Reg-3 +`define PWM_BLK2_CFG0 8'h30 // reg_0 - PWM BLK-2 Reg-0 +`define PWM_BLK2_CFG1 8'h34 // reg_1 - PWM BLK-2 Reg-1 +`define PWM_BLK2_CFG2 8'h38 // reg_2 - PWM BLK-2 Reg-2 +`define PWM_BLK2_CFG3 8'h3C // reg_3 - PWM BLK-2 Reg-3 +`define PWM_BLK3_CFG0 8'h40 // reg_0 - PWM BLK-3 Reg-0 +`define PWM_BLK3_CFG1 8'h44 // reg_1 - PWM BLK-3 Reg-1 +`define PWM_BLK3_CFG2 8'h48 // reg_2 - PWM BLK-3 Reg-2 +`define PWM_BLK3_CFG3 8'h4C // reg_3 - PWM BLK-3 Reg-3 +`define PWM_BLK4_CFG0 8'h50 // reg_0 - PWM BLK-4 Reg-0 +`define PWM_BLK4_CFG1 8'h54 // reg_1 - PWM BLK-4 Reg-1 +`define PWM_BLK4_CFG2 8'h58 // reg_2 - PWM BLK-4 Reg-2 +`define PWM_BLK4_CFG3 8'h5C // reg_3 - PWM BLK-4 Reg-3 +`define PWM_BLK5_CFG0 8'h60 // reg_0 - PWM BLK-5 Reg-0 +`define PWM_BLK5_CFG1 8'h64 // reg_1 - PWM BLK-5 Reg-1 +`define PWM_BLK5_CFG2 8'h68 // reg_2 - PWM BLK-5 Reg-2 +`define PWM_BLK5_CFG3 8'h6C // reg_3 - PWM BLK-5 Reg-3 //-------------------------------------------------- // TIMER Register
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv index e35f5cb..d56b92a 100644 --- a/verilog/rtl/wb_host/src/wb_host.sv +++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -272,9 +272,9 @@ // it has additional 1 cycle additional count, // so we are subtracting desired count by 2 // strap_uartm -// 2'b00 - 50Mhz - 324 -// 2'b01 - 40Mhz - 258 -// 2'b10 - 60Mhz - 389 +// 2'b00 - Auto Baud Detect +// 2'b01 - 50Mhz - 324 +// 2'b10 - 4Mhz - 24 // 2'b11 - Load from LA //------------------------------------------------- @@ -284,9 +284,12 @@ wire cfg_uartm_stop_bit = (strap_uartm==2'b11) ? la_data_in[3] : 1'b1; wire [1:0] cfg_uartm_cfg_pri_mod = (strap_uartm==2'b11) ? la_data_in[17:16] : 2'b0; -wire [11:0]cfg_uart_baud_16x = (strap_uartm==2'b00) ? 324: - (strap_uartm==2'b01) ? 258: - (strap_uartm==2'b10) ? 389: la_data_in[15:4]; +wire [11:0]cfg_uart_baud_16x = (strap_uartm==2'b00) ? 'h0: + (strap_uartm==2'b01) ? 324: + (strap_uartm==2'b10) ? 24: la_data_in[15:4]; + +wire cfg_uartm_aut_det = (strap_uartm==2'b00) ? 1'b1: 1'b0; + // UART Master @@ -295,6 +298,7 @@ .app_clk (wbm_clk_i ), // sys clock // configuration control + .cfg_auto_det (cfg_uartm_aut_det ), // Auto Baud Value detect .cfg_tx_enable (cfg_uartm_tx_enable ), // Enable Transmit Path .cfg_rx_enable (cfg_uartm_rx_enable ), // Enable Received Path .cfg_stop_bit (cfg_uartm_stop_bit ), // 0 -> 1 Start , 1 -> 2 Stop Bits
diff --git a/verilog/rtl/ws281x/src/ws281x_driver.sv b/verilog/rtl/ws281x/src/ws281x_driver.sv new file mode 100644 index 0000000..9974a83 --- /dev/null +++ b/verilog/rtl/ws281x/src/ws281x_driver.sv
@@ -0,0 +1,110 @@ + +// 24 bit ws281x led driver + +module ws281x_driver ( + input logic clk , // Clock input. + input logic reset_n , // Resets the internal state of the driver + + input logic[15:0] cfg_reset_period , // Reset period interm of clk + input logic [9:0] cfg_clk_period , // Total bit clock period + input logic [9:0] cfg_th0_period , // bit-0 drive low period + input logic [9:0] cfg_th1_period , // bit-1 drive low period + + input logic port_enb , + input logic data_available , + input logic [7:0] green_in , // 8-bit green data + input logic [7:0] red_in , // 8-bit red data + input logic [7:0] blue_in , // 8-bit blue data + output logic data_rd , // data read + + output logic txd // Signal to send to WS2811 chain. + ); + + + parameter STATE_RESET = 1'd0; + parameter STATE_TRANSMIT = 1'd1; + ///////////////////////////////////////////////////////////// + // Timing parameters for the WS2811 // + // The LEDs are reset by driving D0 low for at least 50us. // + // Data is transmitted using a 800kHz signal. // + // A '1' is 50% duty cycle, a '0' is 20% duty cycle. // + ///////////////////////////////////////////////////////////// + + reg [15:0] clk_cnt ; // Clock divider for a cycle + reg state ; // FSM state + reg [23:0] led_data ; // Current byte to send + reg [4:0] bit_cnt ; // Current bit index to send + + + + + always @ (posedge clk or negedge reset_n) begin + if (reset_n == 1'b0) begin + state <= STATE_RESET; + txd <= 0; + data_rd <= 0; + bit_cnt <= 23; + clk_cnt <= 0; + led_data <= 0; + end + else begin + case (state) + STATE_RESET: begin + if(port_enb) begin + if (clk_cnt == cfg_reset_period) begin + if(data_available) begin + led_data <= {green_in,red_in,blue_in}; + bit_cnt <= 23; + clk_cnt <= 0; + txd <= 1; + data_rd <= 1; + state <= STATE_TRANSMIT; + end + end + else begin + // De-assert txd , and wait for 75 us. + txd <= 0; + clk_cnt <= clk_cnt + 1; + end + end else begin + txd <= 0; + clk_cnt <= 0; + end + end // case: STATE_RESET + STATE_TRANSMIT: begin + // Advance cycle counter + if (clk_cnt == cfg_clk_period) begin + txd <= 1; + clk_cnt <= 'h0; + if (bit_cnt != 0) begin + bit_cnt <= bit_cnt -1; + // Start sending next bit of data + led_data <= {led_data [22:0], 1'b0}; + end else begin + if(data_available) begin // if new data available + led_data <= {green_in,red_in,blue_in}; + bit_cnt <= 23; + data_rd <= 1; + end else begin + state <= STATE_RESET; + end + + end + end else begin + data_rd <= 0; + // De-assert txd after a certain amount of time, depending on if you're transmitting a 1 or 0. + if (led_data[23] == 0 && clk_cnt >= cfg_th0_period) begin + txd <= 0; + end + else if (led_data[23] == 1 && clk_cnt >= cfg_th1_period) begin + txd <= 0; + end + clk_cnt <= clk_cnt + 1; + end + end + endcase + end + end + +endmodule +
diff --git a/verilog/rtl/ws281x/src/ws281x_reg.sv b/verilog/rtl/ws281x/src/ws281x_reg.sv new file mode 100644 index 0000000..0444b92 --- /dev/null +++ b/verilog/rtl/ws281x/src/ws281x_reg.sv
@@ -0,0 +1,280 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// ws281x Register //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// Manages the 4x ws281x driver register //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 23rd Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// + + +module ws281x_reg #( parameter NP = 2, // Number of PORT + parameter DW = 32, // DATA WIDTH + parameter AW = 4, // ADDRESS WIDTH + parameter BW = 4 // BYTE WIDTH + ) ( + // System Signals + // Inputs + input logic mclk , + input logic h_reset_n , + + // Reg Bus Interface Signal + input logic reg_cs , + input logic reg_wr , + input logic [AW-1:0] reg_addr , + input logic [DW-1:0] reg_wdata , + input logic [BW-1:0] reg_be , + + // Outputs + output logic [DW-1:0] reg_rdata , + output logic reg_ack , + + output logic[15:0] cfg_reset_period , // Reset period interm of clk + output logic [9:0] cfg_clk_period , // Total bit clock period + output logic [9:0] cfg_th0_period , // bit-0 drive low period + output logic [9:0] cfg_th1_period , // bit-1 drive low period + + // wd281x port-0 data + output logic port0_enb , + input logic port0_rd , + output logic [23:0] port0_data , + output logic port0_dval , + + // wd281x port-1 data + output logic port1_enb , + input logic port1_rd , + output logic [23:0] port1_data , + output logic port1_dval + + //// wd281x port-2 data + //output logic port2_enb , + //input logic port2_rd , + //output logic [23:0] port2_data , + //output logic port2_dval , + + //// wd281x port-3 data + //output logic port3_enb , + //input logic port3_rd , + //output logic [23:0] port3_data , + //output logic port3_dval + + + ); + +//----------------------------------------------------------------------- +// Internal Wire Declarations +//----------------------------------------------------------------------- + +logic sw_rd_en ; +logic sw_wr_en ; +logic [AW-1:0] sw_addr ; +logic [DW-1:0] sw_reg_wdata ; +logic [BW-1:0] sw_be ; + +logic [DW-1:0] reg_out ; +logic [DW-1:0] reg_0 ; +logic [DW-1:0] reg_1 ; +logic [DW-1:0] reg_2 ; +logic [DW-1:0] reg_3 ; + +logic [NP-1:0] fifo_full ; +logic [NP-1:0] fifo_empty ; +logic [NP-1:0] fifo_wr ; +logic [NP-1:0] fifo_rd ; +logic [23:0] fifo_rdata[0:NP-1] ; +logic [NP-1:0] port_op_done ; + +assign sw_addr = reg_addr; +assign sw_be = reg_be; +assign sw_rd_en = reg_cs & !reg_wr; +assign sw_wr_en = reg_cs & reg_wr; +assign sw_reg_wdata = reg_wdata; + +//----------------------------------------------------------------------- +// register read enable and write enable decoding logic +//----------------------------------------------------------------------- +wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0); +wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1); +wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2); +wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3); +wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4) & !fifo_full[0]; // Write only if fifo is not full +wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5) & !fifo_full[1]; // Write only if fifo is not full + + +// Generated seperate write enable case to block the reg ack duration when fifo is full +wire sw_wr_en_t = sw_wr_en_0 | sw_wr_en_1 | sw_wr_en_2 | sw_wr_en_3 | sw_wr_en_4 | sw_wr_en_5 ; + + +always @ (posedge mclk or negedge h_reset_n) +begin : preg_out_Seq + if (h_reset_n == 1'b0) begin + reg_rdata <= 'h0; + reg_ack <= 1'b0; + end else if (reg_cs && !reg_ack && sw_rd_en) begin + reg_rdata <= reg_out[DW-1:0] ; + reg_ack <= 1'b1; + end else if (reg_cs && !reg_ack && sw_wr_en_t) begin // Block Ack generation when FIFO is full + reg_ack <= 1'b1; + end else begin + reg_ack <= 1'b0; + end +end + +//---------------------------------------- +// Hardware Command Register +// Assumption: Maximum 32 port assumed +//---------------------------------------- + +assign port0_enb = reg_0[0]; +assign port1_enb = reg_0[1]; +//assign port2_enb = reg_0[2]; +//assign port3_enb = reg_0[3]; + + generic_register #(.WD(4)) u_reg_0( + //List of Inputs + .we ({4{sw_wr_en_0 & + sw_be[0] }}), + .data_in (sw_reg_wdata[3:0]), + .reset_n (h_reset_n ), + .clk (mclk ), + + //List of Outs + .data_out (reg_0[3:0] ) + ); + +assign reg_0[31:4] = 'h0; + +// CONFIG-0 +assign cfg_reset_period = reg_1[15:0]; +gen_16b_reg #(32'h0) u_reg_1 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_1 ), + .we (sw_be[1:0] ), + .data_in (sw_reg_wdata[15:0] ), + + //List of Outs + .data_out (reg_1[15:0] ) + ); + +assign reg_1[31:16] = 0; + +// CONFIG-1 + +assign cfg_th1_period = reg_2[29:20]; // High Exit Period for Data-1 +assign cfg_th0_period = reg_2[19:10]; // High Exit period for Data-0 +assign cfg_clk_period = reg_2[9:0]; + +gen_32b_reg #(32'h0) u_reg_2 ( + //List of Inputs + .reset_n (h_reset_n ), + .clk (mclk ), + .cs (sw_wr_en_2 ), + .we (sw_be ), + .data_in (sw_reg_wdata ), + + //List of Outs + .data_out (reg_2 ) + ); + + + +assign port0_dval =!fifo_empty[0]; +assign port1_dval =!fifo_empty[1]; +//assign port2_dval =!fifo_empty[2]; +//assign port3_dval =!fifo_empty[3]; + +assign reg_3 = { 2'b00,fifo_empty[1],fifo_full[1], + 2'b00,fifo_empty[0],fifo_full[0]}; + + +//---------------------------------------------------- +// DATA FIFO +//---------------------------------------------------- + +assign fifo_wr[0] = sw_wr_en_4 & reg_ack; +assign fifo_wr[1] = sw_wr_en_5 & reg_ack; +//assign fifo_wr[2] = sw_wr_en_6 & reg_ack; +//assign fifo_wr[3] = sw_wr_en_7 & reg_ack; + +assign fifo_rd[0] = port0_rd; +assign fifo_rd[1] = port1_rd; +//assign fifo_rd[2] = port2_rd; +//assign fifo_rd[3] = port3_rd; + +assign port0_data = fifo_rdata[0]; +assign port1_data = fifo_rdata[1]; +//assign port2_data = fifo_rdata[2]; +//assign port3_data = fifo_rdata[3]; + +genvar port; +generate +for (port = 0; $unsigned(port) < NP; port=port+1) begin : gfifo + +sync_fifo #(.W(24), .D(2)) u_fifo + ( + .clk (mclk ), + .reset_n (h_reset_n ), + .wr_en (fifo_wr[port] ), + .wr_data (sw_reg_wdata[23:0] ), + .full (fifo_full[port] ), + .empty (fifo_empty[port] ), + .rd_en (fifo_rd[port] ), + .rd_data (fifo_rdata[port] ) + ); + +end +endgenerate // gfifo + + +//----------------------------------------------------------------------- +// Register Read Path Multiplexer instantiation +//----------------------------------------------------------------------- + +always_comb +begin + reg_out [31:0] = 32'h0; + + case (sw_addr [3:0]) + 4'b0000 : reg_out [31:0] = reg_0 [31:0]; + 4'b0001 : reg_out [31:0] = reg_1 [31:0]; + 4'b0010 : reg_out [31:0] = reg_2 [31:0]; + 4'b0011 : reg_out [31:0] = reg_3 [31:0]; + 4'b0100 : reg_out [31:0] = port0_data; + 4'b0101 : reg_out [31:0] = port1_data; +// 4'b0110 : reg_out [31:0] = port2_data; +// 4'b0111 : reg_out [31:0] = port3_data; + default : reg_out [31:0] = 32'h0; + endcase +end +endmodule
diff --git a/verilog/rtl/ws281x/src/ws281x_top.sv b/verilog/rtl/ws281x/src/ws281x_top.sv new file mode 100644 index 0000000..138414b --- /dev/null +++ b/verilog/rtl/ws281x/src/ws281x_top.sv
@@ -0,0 +1,200 @@ +////////////////////////////////////////////////////////////////////////////// +// SPDX-FileCopyrightText: 2021 , Dinesh Annayya +// +// 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 +// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// ws281x Top //// +//// //// +//// This file is part of the riscduino cores project //// +//// https://github.com/dineshannayya/riscduino.git //// +//// //// +//// Description //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 23rd Aug 2022, Dinesh A //// +//// initial version //// +////////////////////////////////////////////////////////////////////// + +module ws281x_top ( + // System Signals + // Inputs + input logic mclk, + input logic h_reset_n, + + // Reg Bus Interface Signal + input logic reg_cs, + input logic reg_wr, + input logic [3:0] reg_addr, + input logic [31:0] reg_wdata, + input logic [3:0] reg_be, + + // Outputs + output logic [31:0] reg_rdata, + output logic reg_ack, + + output logic [3:0] txd + + ); + +assign txd[2] = txd[0]; +assign txd[3] = txd[1]; + +logic[15:0] cfg_reset_period ; // Reset period interm of clk +logic [9:0] cfg_clk_period ; // Total bit clock period +logic [9:0] cfg_th0_period ; // bit-0 drive low period +logic [9:0] cfg_th1_period ; // bit-1 drive low period + +logic port0_enb ; +logic port0_rd ; +logic port0_dval ; +logic [23:0] port0_data ; +logic port1_enb ; +logic port1_rd ; +logic port1_dval ; +logic [23:0] port1_data ; +//logic [23:0] port2_data ; +//logic [23:0] port3_data ; + +ws281x_reg u_reg ( + .mclk ( mclk ), + .h_reset_n ( h_reset_n ), + + .reg_cs ( reg_cs ), + .reg_wr ( reg_wr ), + .reg_addr ( reg_addr ), + .reg_wdata ( reg_wdata ), + .reg_be ( reg_be ), + + .reg_rdata ( reg_rdata ), + .reg_ack ( reg_ack ), + + .cfg_reset_period ( cfg_reset_period ), // Reset period interm of clk + .cfg_clk_period ( cfg_clk_period ), // Total bit clock period + .cfg_th0_period ( cfg_th0_period ), // bit-0 drive low period + .cfg_th1_period ( cfg_th1_period ), // bit-1 drive low period + + .port0_enb ( port0_enb ), + .port0_rd ( port0_rd ), + .port0_data ( port0_data ), + .port0_dval ( port0_dval ), + + .port1_enb ( port1_enb ), + .port1_rd ( port1_rd ), + .port1_data ( port1_data ), + .port1_dval ( port1_dval ) + + //.port2_enb ( port2_enb ), + //.port2_rd ( port2_rd ), + //.port2_data ( port2_data ), + //.port2_dval ( port2_dval ), + + //.port3_enb ( port3_enb ), + //.port3_rd ( port3_rd ), + //.port3_data ( port3_data ), + //.port3_dval ( port3_dval ) + + ); + + +//wx281x port-0 +ws281x_driver u_txd_0( + .clk (mclk ), // Clock input. + .reset_n (h_reset_n ), // Resets the internal state of the driver + + .cfg_reset_period (cfg_reset_period ), // Reset period interm of clk + .cfg_clk_period (cfg_clk_period ), // Total bit clock period + .cfg_th0_period (cfg_th0_period ), // bit-0 drive low period + .cfg_th1_period (cfg_th1_period ), // bit-1 drive low period + + .port_enb (port0_enb ), + .data_available (port0_dval ), + .green_in (port0_data[23:16]), // 8-bit green data + .red_in (port0_data[15:8] ), // 8-bit red data + .blue_in (port0_data[7:0] ), // 8-bit blue data + .data_rd (port0_rd ), // data read + + .txd (txd[0] ) // Signal to send to WS2811 chain. + ); + +//wx281x port-1 +ws281x_driver u_txd_1( + .clk (mclk ), // Clock input. + .reset_n (h_reset_n ), // Resets the internal state of the driver + + .cfg_reset_period (cfg_reset_period ), // Reset period interm of clk + .cfg_clk_period (cfg_clk_period ), // Total bit clock period + .cfg_th0_period (cfg_th0_period ), // bit-0 drive low period + .cfg_th1_period (cfg_th1_period ), // bit-1 drive low period + + .port_enb (port1_enb ), + .data_available (port1_dval ), + .green_in (port1_data[23:16]), // 8-bit green data + .red_in (port1_data[15:8] ), // 8-bit red data + .blue_in (port1_data[7:0] ), // 8-bit blue data + .data_rd (port1_rd ), // data read + + .txd (txd[1] ) // Signal to send to WS2811 chain. + ); + +/*** +//wx281x port-2 +ws281x_driver u_txd_2( + .clk (mclk ), // Clock input. + .reset_n (h_reset_n ), // Resets the internal state of the driver + + .cfg_reset_period (cfg_reset_period ), // Reset period interm of clk + .cfg_clk_period (cfg_clk_period ), // Total bit clock period + .cfg_th0_period (cfg_th0_period ), // bit-0 drive low period + .cfg_th1_period (cfg_th1_period ), // bit-1 drive low period + + .port_enb (port2_enb ), + .data_available (port2_dval ), + .green_in (port2_data[23:16]), // 8-bit green data + .red_in (port2_data[15:8] ), // 8-bit red data + .blue_in (port2_data[7:0] ), // 8-bit blue data + .data_rd (port2_rd ), // data read + + .txd (txd[2] ) // Signal to send to WS2811 chain. + ); + +//wx281x port-3 +ws281x_driver u_txd_3( + .clk (mclk ), // Clock input. + .reset_n (h_reset_n ), // Resets the internal state of the driver + + .cfg_reset_period (cfg_reset_period ), // Reset period interm of clk + .cfg_clk_period (cfg_clk_period ), // Total bit clock period + .cfg_th0_period (cfg_th0_period ), // bit-0 drive low period + .cfg_th1_period (cfg_th1_period ), // bit-1 drive low period + + .port_enb (port3_enb ), + .data_available (port3_dval ), + .green_in (port3_data[23:16]), // 8-bit green data + .red_in (port3_data[15:8] ), // 8-bit red data + .blue_in (port3_data[7:0] ), // 8-bit blue data + .data_rd (port3_rd ), // data read + + .txd (txd[3] ) // Signal to send to WS2811 chain. + ); +***/ +endmodule