uart master interface added
diff --git a/README.md b/README.md index 5f59d8d..28a6d02 100644 --- a/README.md +++ b/README.md
@@ -114,12 +114,12 @@ <tr align="center"> <td> SFlash </td> <td> sflash_io1 </td> <td> </td> <td> digital_io[27] </td></tr> <tr align="center"> <td> SFlash </td> <td> sflash_io2 </td> <td> </td> <td> digital_io[28] </td></tr> <tr align="center"> <td> SFlash </td> <td> sflash_io3 </td> <td> </td> <td> digital_io[29] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_sck </td> <td> </td> <td> digital_io[30] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_ss </td> <td> </td> <td> digital_io[31] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_io0 </td> <td> </td> <td> digital_io[32] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_io1 </td> <td> </td> <td> digital_io[33] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_io2 </td> <td> </td> <td> digital_io[34] </td></tr> - <tr align="center"> <td> SSRAM </td> <td> ssram_io3 </td> <td> </td> <td> digital_io[35] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> Reserved </td> <td> </td> <td> digital_io[30] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> Reserved </td> <td> </td> <td> digital_io[31] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> Reserved </td> <td> </td> <td> digital_io[32] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> Reserved </td> <td> </td> <td> digital_io[33] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> uartm rxd </td> <td> </td> <td> digital_io[34] </td></tr> + <tr align="center"> <td> SSRAM </td> <td> uartm txd </td> <td> </td> <td> digital_io[35] </td></tr> <tr align="center"> <td> usb1.1 </td> <td> usb_dp </td> <td> </td> <td> digital_io[36] </td></tr> <tr align="center"> <td> usb1.1 </td> <td> usb_dn </td> <td> </td> <td> digital_io[37] </td></tr> </table>
diff --git a/openlane/pinmux/pin_order.cfg b/openlane/pinmux/pin_order.cfg index 05643c9..eab1c0c 100644 --- a/openlane/pinmux/pin_order.cfg +++ b/openlane/pinmux/pin_order.cfg
@@ -26,6 +26,9 @@ pulse1m_mclk i2cm_intr usb_intr +uartm_rxd +uartm_txd + pinmux_debug\[0\] 0100 0 2 pinmux_debug\[1\] pinmux_debug\[2\]
diff --git a/openlane/user_project_wrapper/macro.cfg b/openlane/user_project_wrapper/macro.cfg index b98e50c..535ebc1 100644 --- a/openlane/user_project_wrapper/macro.cfg +++ b/openlane/user_project_wrapper/macro.cfg
@@ -11,4 +11,4 @@ u_sram2_2kb 150 2900 N u_sram3_2kb 950 2900 N u_intercon 1850 600 N -u_wb_host 1850 300 N +u_wb_host 1450 250 N
diff --git a/openlane/wb_host/base.sdc b/openlane/wb_host/base.sdc index 479be45..c332df0 100644 --- a/openlane/wb_host/base.sdc +++ b/openlane/wb_host/base.sdc
@@ -8,22 +8,11 @@ ############################################################################### create_clock -name wbm_clk_i -period 10.0000 [get_ports {wbm_clk_i}] create_clock -name wbs_clk_i -period 10.0000 [get_ports {wbs_clk_i}] -set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}] -hold 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}] -setup 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}] -hold 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}] -setup 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}] -hold 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -rise_to [get_clocks {wbm_clk_i}] -setup 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}] -hold 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbm_clk_i}] -fall_to [get_clocks {wbm_clk_i}] -setup 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}] -hold 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}] -setup 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}] -hold 0.2500 -set_clock_uncertainty -rise_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}] -setup 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}] -hold 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -rise_to [get_clocks {wbs_clk_i}] -setup 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}] -hold 0.2500 -set_clock_uncertainty -fall_from [get_clocks {wbs_clk_i}] -fall_to [get_clocks {wbs_clk_i}] -setup 0.2500 +create_clock -name uart_clk -period 100.0000 [get_pins {u_uart2wb.u_core.u_uart_clk.u_mux/X}] + +set_clock_transition 0.1500 [all_clocks] +set_clock_uncertainty -setup 0.2500 [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}] %" @@ -31,7 +20,8 @@ set_timing_derate -late [expr {1+$::env(SYNTH_TIMING_DERATE)}] set_clock_groups -name async_clock -asynchronous \ - -group [get_clocks {wbs_clk_i}]\ + -group [get_clocks {uart_clk}] \ + -group [get_clocks {wbs_clk_i}] \ -group [get_clocks {wbm_clk_i}] -comment {Async Clock group} ### ClkSkew Adjust
diff --git a/openlane/wb_host/config.tcl b/openlane/wb_host/config.tcl index 3ad1047..cb28644 100755 --- a/openlane/wb_host/config.tcl +++ b/openlane/wb_host/config.tcl
@@ -26,7 +26,7 @@ # Timing configuration set ::env(CLOCK_PERIOD) "10" -set ::env(CLOCK_PORT) "wbm_clk_i wbs_clk_i" +set ::env(CLOCK_PORT) "wbm_clk_i wbs_clk_i u_uart2wb.u_core.u_uart_clk.u_mux/X" set ::env(SYNTH_MAX_FANOUT) 4 @@ -46,7 +46,17 @@ $script_dir/../../verilog/rtl/lib/async_wb.sv \ $script_dir/../../verilog/rtl/lib/clk_ctl.v \ $script_dir/../../verilog/rtl/lib/ctech_cells.sv \ - $script_dir/../../verilog/rtl/lib/registers.v" + $script_dir/../../verilog/rtl/lib/registers.v \ + $script_dir/../../verilog/rtl/lib/reset_sync.sv \ + $script_dir/../../verilog/rtl/lib/async_reg_bus.sv \ + $script_dir/../../verilog/rtl/uart/src/uart_txfsm.sv \ + $script_dir/../../verilog/rtl/uart/src/uart_rxfsm.sv \ + $script_dir/../../verilog/rtl/lib/double_sync_low.v \ + $script_dir/../../verilog/rtl/wb_interconnect/src/wb_arb.sv \ + $script_dir/../../verilog/rtl/uart2wb/src/uart2wb.sv \ + $script_dir/../../verilog/rtl/uart2wb/src/uart2_core.sv \ + $script_dir/../../verilog/rtl/uart2wb/src/uart_msg_handler.v \ + " set ::env(SYNTH_READ_BLACKBOX_LIB) 1 set ::env(SYNTH_DEFINES) [list SYNTHESIS ] @@ -65,7 +75,7 @@ set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg set ::env(FP_SIZING) absolute -set ::env(DIE_AREA) "0 0 450 200" +set ::env(DIE_AREA) "0 0 800 250" # If you're going to use multiple power domains, then keep this disabled. @@ -75,7 +85,7 @@ set ::env(PL_TIME_DRIVEN) 1 -set ::env(PL_TARGET_DENSITY) "0.41" +set ::env(PL_TARGET_DENSITY) "0.33"
diff --git a/openlane/wb_host/pin_order.cfg b/openlane/wb_host/pin_order.cfg index ed4f0bd..4fac1a3 100644 --- a/openlane/wb_host/pin_order.cfg +++ b/openlane/wb_host/pin_order.cfg
@@ -146,9 +146,33 @@ wbm_dat_o\[31\] wbm_err_o +la_data_in\[0\] 300 0 2 +la_data_in\[1\] +la_data_in\[2\] +la_data_in\[3\] +la_data_in\[4\] +la_data_in\[5\] +la_data_in\[6\] +la_data_in\[7\] +la_data_in\[8\] +la_data_in\[9\] +la_data_in\[10\] +la_data_in\[11\] +la_data_in\[12\] +la_data_in\[13\] +la_data_in\[14\] +la_data_in\[15\] +la_data_in\[16\] +la_data_in\[17\] + +#E + +uartm_rxd 200 0 2 +uartm_txd + #N -wbd_int_rst_n 0000 0 2 +wbd_int_rst_n 0400 0 2 cfg_clk_ctrl2\[31\] cfg_clk_ctrl2\[30\] cfg_clk_ctrl2\[29\] @@ -208,7 +232,7 @@ -wbs_stb_o 060 0 2 +wbs_stb_o 460 0 2 wbs_we_o wbs_adr_o\[31\] wbs_adr_o\[30\] @@ -315,4 +339,3 @@ wbs_cyc_o -
diff --git a/openlane/wb_interconnect/base.sdc b/openlane/wb_interconnect/base.sdc index 68e7dde..ac76e84 100644 --- a/openlane/wb_interconnect/base.sdc +++ b/openlane/wb_interconnect/base.sdc
@@ -16,10 +16,7 @@ set_clock_uncertainty -fall_from [get_clocks {clk_i}] -fall_to [get_clocks {clk_i}] -hold 0.2500 set_clock_uncertainty -fall_from [get_clocks {clk_i}] -fall_to [get_clocks {clk_i}] -setup 0.2500 -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)}] + #Clock Skew adjustment set_case_analysis 0 [get_ports {cfg_cska_wi[0]}] @@ -141,6 +138,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 ::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)}] ############################################################################### # Design Rules ###############################################################################
diff --git a/signoff/pinmux/final_summary_report.csv b/signoff/pinmux/final_summary_report.csv index c09928a..c0a3582 100644 --- a/signoff/pinmux/final_summary_report.csv +++ b/signoff/pinmux/final_summary_report.csv
@@ -1,2 +1,2 @@ ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY -0,/project/openlane/pinmux,pinmux,pinmux,flow_completed,0h16m18s,-1,46004.0404040404,0.2475,23002.0202020202,27.03,702.81,5693,0,0,0,0,0,0,-1,1,0,-1,-1,421015,60601,0.0,0.0,-1,0.0,-1,0.0,0.0,-1,0.0,-1,309034294.0,6.6,42.63,33.16,10.43,0.49,-1,3568,8567,541,5539,0,0,0,4197,0,0,0,0,0,0,0,4,1341,1339,16,314,3259,0,3573,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.3,0.0,sky130_fd_sc_hd,4,4 +0,/project/openlane/pinmux,pinmux,pinmux,flow_completed,0h16m18s,-1,46012.12121212122,0.2475,23006.06060606061,27.04,722.42,5694,0,0,0,0,0,0,-1,1,0,-1,-1,420199,60746,0.0,0.0,-1,0.0,-1,0.0,0.0,-1,0.0,-1,309991900.0,4.36,42.79,33.18,10.07,0.41,-1,3565,8555,538,5527,0,0,0,4197,0,0,0,0,0,0,0,4,1341,1339,16,314,3259,0,3573,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.3,0.0,sky130_fd_sc_hd,4,4
diff --git a/signoff/user_project_wrapper/final_summary_report.csv b/signoff/user_project_wrapper/final_summary_report.csv index b98995d..860d0c6 100644 --- a/signoff/user_project_wrapper/final_summary_report.csv +++ b/signoff/user_project_wrapper/final_summary_report.csv
@@ -1,2 +1,2 @@ ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY -0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow_completed,0h39m20s,-1,2.529576587795766,10.2784,1.264788293897883,-1,530.09,13,0,0,0,0,0,0,-1,0,0,-1,-1,1195465,7994,0.0,-1,-1,0.0,-1,0.0,-1,-1,0.0,-1,-1,40144.36,3.25,3.57,0.37,0.62,-1,269,2530,269,2530,0,0,0,13,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,90.9090909090909,11,10,AREA 0,5,50,1,180,90,0.55,0.0,sky130_fd_sc_hd,4,0 +0,/project/openlane/user_project_wrapper,user_project_wrapper,user_project_wrapper,flow_completed,0h39m19s,-1,2.529576587795766,10.2784,1.264788293897883,-1,530.35,13,0,0,0,0,0,0,-1,0,0,-1,-1,1176061,8078,0.0,-1,-1,0.0,-1,0.0,-1,-1,0.0,-1,-1,40144.36,3.16,3.63,0.42,0.67,-1,271,2532,271,2532,0,0,0,13,0,0,0,0,0,0,0,0,-1,-1,-1,0,0,0,0,90.9090909090909,11,10,AREA 0,5,50,1,180,90,0.55,0.0,sky130_fd_sc_hd,4,0
diff --git a/signoff/wb_host/final_summary_report.csv b/signoff/wb_host/final_summary_report.csv index 8a3c4ac..5da5134 100644 --- a/signoff/wb_host/final_summary_report.csv +++ b/signoff/wb_host/final_summary_report.csv
@@ -1,2 +1,2 @@ ,design,design_name,config,flow_status,total_runtime,routed_runtime,(Cell/mm^2)/Core_Util,DIEAREA_mm^2,CellPer_mm^2,OpenDP_Util,Peak_Memory_Usage_MB,cell_count,tritonRoute_violations,Short_violations,MetSpc_violations,OffGrid_violations,MinHole_violations,Other_violations,Magic_violations,antenna_violations,lvs_total_errors,cvc_total_errors,klayout_violations,wire_length,vias,wns,pl_wns,optimized_wns,fastroute_wns,spef_wns,tns,pl_tns,optimized_tns,fastroute_tns,spef_tns,HPWL,routing_layer1_pct,routing_layer2_pct,routing_layer3_pct,routing_layer4_pct,routing_layer5_pct,routing_layer6_pct,wires_count,wire_bits,public_wires_count,public_wire_bits,memories_count,memory_bits,processes_count,cells_pre_abc,AND,DFF,NAND,NOR,OR,XOR,XNOR,MUX,inputs,outputs,level,EndCaps,TapCells,Diodes,Total_Physical_Cells,suggested_clock_frequency,suggested_clock_period,CLOCK_PERIOD,SYNTH_STRATEGY,SYNTH_MAX_FANOUT,FP_CORE_UTIL,FP_ASPECT_RATIO,FP_PDN_VPITCH,FP_PDN_HPITCH,PL_TARGET_DENSITY,GLB_RT_ADJUSTMENT,STD_CELL_LIBRARY,CELL_PAD,DIODE_INSERTION_STRATEGY -0,/project/openlane/wb_host,wb_host,wb_host,flow_completed,0h7m17s,-1,62133.33333333334,0.09,31066.66666666667,39.23,583.55,2796,0,0,0,0,0,0,0,0,0,0,-1,156439,26510,0.0,0.0,-1,0.0,-1,0.0,0.0,-1,0.0,-1,117576375.0,0.0,47.59,28.13,12.61,0.16,-1,1403,3046,726,2367,0,0,0,1466,0,0,0,0,0,0,0,4,783,970,13,130,1105,0,1235,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.41,0.0,sky130_fd_sc_hd,4,4 +0,/project/openlane/wb_host,wb_host,wb_host,flow_completed,0h9m32s,-1,49450.0,0.2,24725.0,28.76,669.94,4945,0,0,0,0,0,0,0,5,0,0,-1,347600,49741,0.0,0.0,-1,-0.03,-1,0.0,0.0,-1,-0.04,-1,290549721.0,0.48,55.89,17.29,18.18,0.0,-1,3296,5967,883,3410,0,0,0,3733,0,0,0,0,0,0,0,4,1227,1542,17,166,2592,0,2758,90.9090909090909,11,10,AREA 0,4,50,1,100,100,0.33,0.0,sky130_fd_sc_hd,4,4
diff --git a/sta/sdc/caravel.sdc b/sta/sdc/caravel.sdc index cda6027..04075b4 100644 --- a/sta/sdc/caravel.sdc +++ b/sta/sdc/caravel.sdc
@@ -19,7 +19,8 @@ create_clock -name cpu_clk -period 20.0000 [get_pins {mprj/u_wb_host/cpu_clk}] create_clock -name rtc_clk -period 50.0000 [get_pins {mprj/u_wb_host/rtc_clk}] create_clock -name usb_clk -period 20.0000 [get_pins {mprj/u_wb_host/usb_clk}] -create_clock -name line_clk -period 100.0000 [get_pins {mprj/u_uart_i2c_usb_spi/u_uart_core.u_lineclk_buf.u_mux/X}] +create_clock -name uarts_clk -period 100.0000 [get_pins {mprj/u_uart_i2c_usb_spi/u_uart_core.u_lineclk_buf.u_mux/X}] +create_clock -name uartm_clk -period 100.0000 [get_pins {mprj/u_wb_host/u_uart2wb.u_core.u_uart_clk.u_mux/X}] create_generated_clock -name mem_clk0 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/mem_no[0].u_mem_sel.u_mem_clk_sel.u_mux/X] create_generated_clock -name mem_clk1 -add -source [get_pins {mprj/u_wb_host/wbs_clk_out}] -master_clock [get_clocks wbs_clk_i] -divide_by 1 -comment {memory Clock} [get_pins mprj/u_mbist/mem_no[1].u_mem_sel.u_mem_clk_sel.u_mux/X] @@ -82,7 +83,8 @@ -group [get_clocks {cpu_ref_clk}]\ -group [get_clocks {rtc_clk}]\ -group [get_clocks {usb_clk}]\ - -group [get_clocks {line_clk}]\ + -group [get_clocks {uarts_clk}]\ + -group [get_clocks {uartm_clk}]\ -comment {Async Clock group} ## INPUT/OUTPUT DELAYS
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile index a91211b..4ee38f8 100644 --- a/verilog/dv/Makefile +++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@ .SUFFIXES: .SILENT: clean all -PATTERNS = wb_port risc_boot user_risc_boot user_uart user_spi user_i2cm riscv_regress user_basic user_mbist_test1 user_risc_soft_boot +PATTERNS = wb_port risc_boot user_risc_boot user_uart user_spi user_i2cm riscv_regress user_basic user_mbist_test1 user_risc_soft_boot user_uart_master uart_master all: ${PATTERNS} for i in ${PATTERNS}; do \
diff --git a/verilog/dv/agents/uart_agent.v b/verilog/dv/agents/uart_agent.v index f3e05ef..7c99b46 100644 --- a/verilog/dv/agents/uart_agent.v +++ b/verilog/dv/agents/uart_agent.v
@@ -46,11 +46,13 @@ integer timeout_count; integer data_bit_number; reg [15:0] clk_count; +reg debug_mode; reg error_ind; // 1 indicate error initial begin + debug_mode = 1; // Keep in debug mode and enable display txd = 1'b1; uart_clk = 0; clk_count = 0; @@ -144,6 +146,7 @@ fork begin : loop_1 @(abort) + if(debug_mode) $display ("%m: >>>>> Exceed time limit, uart no responce.\n"); ->uart_timeout_error; disable loop_2; @@ -172,6 +175,201 @@ if ((control_setup.even_odd_parity && (rxd == parity)) || (!control_setup.even_odd_parity && (rxd != parity))) begin + $display ("%m: >>>>> Parity Error"); + -> error_detected; + -> uart_parity_error; + end + end + +// stop cycle 1 + @(posedge uart_rx_clk); + if (!rxd) + begin + $display ("%m: >>>>> Stop signal 1 Error"); + -> error_detected; + -> uart_stop_error1; + end + +// stop cycle 2 + if (control_setup.stop_bit_number) + begin + @(posedge uart_rx_clk); // stop cycle 2 + if (!rxd) + begin + $display ("%m: >>>>> Stop signal 2 Error"); + -> error_detected; + -> uart_stop_error2; + end + end + + +// wait another half cycle for tx_done signal + @(negedge uart_rx_clk); + read <= 0; + -> uart_read_done; + + if (expected_data != data) + begin + $display ("%m: Error! Data return is %h, expecting %h", data, expected_data); + -> error_detected; + end + else begin + if(debug_mode) + $display ("%m: Data match %h", expected_data); + end + + if(debug_mode) + $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1); + end +join + +end + +endtask + +//////////////////////////////////////////////////////////////////////////////// +task read_char2; +output [7:0] rxd_data; +output timeout; // 1-> timeout +integer i; +reg [7:0] rxd_data; +reg [7:0] data; +reg parity; + +begin + data <= 8'h0; + parity <= 1; + timeout_count = 0; + timeout = 0; + + fork + begin + @(abort) + //$display (">>>>> Exceed time limit, uart no responce.\n"); + //->uart_timeout_error; + timeout = 1; + end + + begin + +// start cycle + @(negedge rxd) + read <= 1; + +// data cycle + @(posedge uart_rx_clk ); + for (i = 0; i < data_bit_number; i = i + 1) + begin + @(posedge uart_rx_clk) + data[i] <= rxd; + parity <= parity ^ rxd; + end + +// parity cycle + if(control_setup.parity_en) + begin + @(posedge uart_rx_clk); + if ((control_setup.even_odd_parity && (rxd == parity)) || + (!control_setup.even_odd_parity && (rxd != parity))) + begin + $display (">>>>> Parity Error"); + -> error_detected; + -> uart_parity_error; + end + end + +// stop cycle 1 + @(posedge uart_rx_clk); + if (!rxd) + begin + $display (">>>>> Stop signal 1 Error"); + -> error_detected; + -> uart_stop_error1; + end + +// stop cycle 2 + if (control_setup.stop_bit_number) + begin + @(posedge uart_rx_clk); // stop cycle 2 + if (!rxd) + begin + $display (">>>>> Stop signal 2 Error"); + -> error_detected; + -> uart_stop_error2; + end + end + +// wait another half cycle for tx_done signal + @(negedge uart_rx_clk); + read <= 0; + -> uart_read_done; + +// $display ("(%m) Received Data %c", data); +// $display ("... Read Data from UART done cnt :%d...",rx_count +1); + $write ("%c",data); + rxd_data = data; + end + join_any + disable fork; //disable pending fork activity + +end + +endtask + + +//////////////////////////////////////////////////////////////////////////////// +task read_char; +output [7:0] rxd_data; +output timeout; // 1-> timeout + +reg [7:0] rxd_data; + + +integer i; +reg [7:0] expected_data; +reg [7:0] data; +reg parity; + +begin + data <= 8'h0; + parity <= 1; + timeout_count = 0; + timeout = 0; + + +fork + begin : loop_1 + @(abort) + if(debug_mode) + $display ("%m: >>>>> Exceed time limit, uart no responce.\n"); + timeout = 1; + ->uart_timeout_error; + disable loop_2; + end + + begin : loop_2 + +// start cycle + @(negedge rxd) + disable loop_1; + read <= 1; + +// data cycle + @(posedge uart_rx_clk); + for (i = 0; i < data_bit_number; i = i + 1) + begin + @(posedge uart_rx_clk) + data[i] <= rxd; + parity <= parity ^ rxd; + end + +// parity cycle + if(control_setup.parity_en) + begin + @(posedge uart_rx_clk); + if ((control_setup.even_odd_parity && (rxd == parity)) || + (!control_setup.even_odd_parity && (rxd != parity))) + begin $display ("%m: >>>>> Parity Error"); -> error_detected; -> uart_parity_error; @@ -205,15 +403,13 @@ read <= 0; -> uart_read_done; - if (expected_data != data) - begin - $display ("%m: Error! Data return is %h, expecting %h", data, expected_data); - -> error_detected; - end - else - $display ("%m: Data match %h", expected_data); + rxd_data = data; - $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1); + + if(debug_mode) begin + $display ("%m: Received Data %h", rxd_data); + $display ("%m:... Read Data from UART done cnt :%d...",rx_count +1); + end end join @@ -221,7 +417,6 @@ endtask - //////////////////////////////////////////////////////////////////////////////// task write_char; input [7:0] data; @@ -271,7 +466,10 @@ @(posedge uart_clk); write <= #1 0; - $display ("%m:... Write data %h to UART done cnt : %d ...\n", data,tx_count+1); + if(debug_mode) + $display ("%m:... Write data %h to UART done cnt : %d ...\n", data,tx_count+1); + else + $write ("%c",data); -> uart_write_done; end endtask
diff --git a/verilog/dv/agents/uart_master_tasks.sv b/verilog/dv/agents/uart_master_tasks.sv new file mode 100644 index 0000000..f0a1a7d --- /dev/null +++ b/verilog/dv/agents/uart_master_tasks.sv
@@ -0,0 +1,201 @@ + +task uartm_reg_write; +input [31:0] addr; +input [31:0] data; +reg [7:0] read_data; +reg flag; +begin + fork + begin : loop_1 + tb_master_uart.write_char("w"); + tb_master_uart.write_char("m"); + tb_master_uart.write_char(" "); + tb_master_uart.write_char(hex2char(addr[31:28])); + tb_master_uart.write_char(hex2char(addr[27:24])); + tb_master_uart.write_char(hex2char(addr[23:20])); + tb_master_uart.write_char(hex2char(addr[19:16])); + tb_master_uart.write_char(hex2char(addr[15:12])); + tb_master_uart.write_char(hex2char(addr[11:8])); + tb_master_uart.write_char(hex2char(addr[7:4])); + tb_master_uart.write_char(hex2char(addr[3:0])); + tb_master_uart.write_char(" "); + tb_master_uart.write_char(hex2char(data[31:28])); + tb_master_uart.write_char(hex2char(data[27:24])); + tb_master_uart.write_char(hex2char(data[23:20])); + tb_master_uart.write_char(hex2char(data[19:16])); + tb_master_uart.write_char(hex2char(data[15:12])); + tb_master_uart.write_char(hex2char(data[11:8])); + tb_master_uart.write_char(hex2char(data[7:4])); + tb_master_uart.write_char(hex2char(data[3:0])); + tb_master_uart.write_char("\n"); + end + begin : loop_2 + // Wait for sucess command + flag = 0; + while(flag == 0) + begin + tb_master_uart.read_char2(read_data,flag); + //$write ("%c",read_data); + end + end + join +end +endtask + +task uartm_reg_read; +input [31:0] addr; +output [31:0] data; +reg [7:0] read_data; +reg flag; +integer i; +begin + fork + begin : loop_1 + tb_master_uart.write_char("r"); + tb_master_uart.write_char("m"); + tb_master_uart.write_char(" "); + tb_master_uart.write_char(hex2char(addr[31:28])); + tb_master_uart.write_char(hex2char(addr[27:24])); + tb_master_uart.write_char(hex2char(addr[23:20])); + tb_master_uart.write_char(hex2char(addr[19:16])); + tb_master_uart.write_char(hex2char(addr[15:12])); + tb_master_uart.write_char(hex2char(addr[11:8])); + tb_master_uart.write_char(hex2char(addr[7:4])); + tb_master_uart.write_char(hex2char(addr[3:0])); + tb_master_uart.write_char("\n"); + end + begin : loop_2 + // Wait for sucess command + flag = 0; + i = 0; + while(flag == 0) + begin + tb_master_uart.read_char2(read_data,flag); + //$write ("%d:%c",i,read_data); + case (i) + 8'd10 : data[31:28] = char2hex(read_data); + 8'd11 : data[27:24] = char2hex(read_data); + 8'd12 : data[23:20] = char2hex(read_data); + 8'd13 : data[19:16] = char2hex(read_data); + 8'd14 : data[15:12] = char2hex(read_data); + 8'd15 : data[11:8] = char2hex(read_data); + 8'd16 : data[7:4] = char2hex(read_data); + 8'd17 : data[3:0] = char2hex(read_data); + endcase + i = i+1; + end + end + join + $display("received Data: %x",data); + +end +endtask + +task uartm_reg_read_check; +input [31:0] addr; +input [31:0] exp_data; +reg [31:0] rxd_data; +reg [7:0] read_data; +reg flag; +integer i; +begin + fork + begin : loop_1 + tb_master_uart.write_char("r"); + tb_master_uart.write_char("m"); + tb_master_uart.write_char(" "); + tb_master_uart.write_char(hex2char(addr[31:28])); + tb_master_uart.write_char(hex2char(addr[27:24])); + tb_master_uart.write_char(hex2char(addr[23:20])); + tb_master_uart.write_char(hex2char(addr[19:16])); + tb_master_uart.write_char(hex2char(addr[15:12])); + tb_master_uart.write_char(hex2char(addr[11:8])); + tb_master_uart.write_char(hex2char(addr[7:4])); + tb_master_uart.write_char(hex2char(addr[3:0])); + tb_master_uart.write_char("\n"); + end + begin : loop_2 + // Wait for sucess command + flag = 0; + i = 0; + while(flag == 0) + begin + tb_master_uart.read_char2(read_data,flag); + //$write ("%d:%c",i,read_data); + case (i) + 8'd10 : rxd_data[31:28] = char2hex(read_data); + 8'd11 : rxd_data[27:24] = char2hex(read_data); + 8'd12 : rxd_data[23:20] = char2hex(read_data); + 8'd13 : rxd_data[19:16] = char2hex(read_data); + 8'd14 : rxd_data[15:12] = char2hex(read_data); + 8'd15 : rxd_data[11:8] = char2hex(read_data); + 8'd16 : rxd_data[7:4] = char2hex(read_data); + 8'd17 : rxd_data[3:0] = char2hex(read_data); + endcase + i = i+1; + end + end + join + if(rxd_data == exp_data) begin + // $display("STATUS: ADDRESS: %x RXD: %x", addr,rxd_data); + end else begin + $display("ERROR: ADDRESS: %x EXP: %x RXD: %x", addr,exp_data,rxd_data); + test_fail = 1; + end + + +end +endtask + +// Character to hex number +function [3:0] char2hex; +input [7:0] data_in; +case (data_in) + 8'h30: char2hex = 4'h0; // character '0' + 8'h31: char2hex = 4'h1; // character '1' + 8'h32: char2hex = 4'h2; // character '2' + 8'h33: char2hex = 4'h3; // character '3' + 8'h34: char2hex = 4'h4; // character '4' + 8'h35: char2hex = 4'h5; // character '5' + 8'h36: char2hex = 4'h6; // character '6' + 8'h37: char2hex = 4'h7; // character '7' + 8'h38: char2hex = 4'h8; // character '8' + 8'h39: char2hex = 4'h9; // character '9' + 8'h41: char2hex = 4'hA; // character 'A' + 8'h42: char2hex = 4'hB; // character 'B' + 8'h43: char2hex = 4'hC; // character 'C' + 8'h44: char2hex = 4'hD; // character 'D' + 8'h45: char2hex = 4'hE; // character 'E' + 8'h46: char2hex = 4'hF; // character 'F' + 8'h61: char2hex = 4'hA; // character 'a' + 8'h62: char2hex = 4'hB; // character 'b' + 8'h63: char2hex = 4'hC; // character 'c' + 8'h64: char2hex = 4'hD; // character 'd' + 8'h65: char2hex = 4'hE; // character 'e' + 8'h66: char2hex = 4'hF; // character 'f' + default : char2hex = 4'hF; + endcase +endfunction + +// Hex to Asci Character +function [7:0] hex2char; +input [3:0] data_in; +case (data_in) + 4'h0: hex2char = 8'h30; // character '0' + 4'h1: hex2char = 8'h31; // character '1' + 4'h2: hex2char = 8'h32; // character '2' + 4'h3: hex2char = 8'h33; // character '3' + 4'h4: hex2char = 8'h34; // character '4' + 4'h5: hex2char = 8'h35; // character '5' + 4'h6: hex2char = 8'h36; // character '6' + 4'h7: hex2char = 8'h37; // character '7' + 4'h8: hex2char = 8'h38; // character '8' + 4'h9: hex2char = 8'h39; // character '9' + 4'hA: hex2char = 8'h41; // character 'A' + 4'hB: hex2char = 8'h42; // character 'B' + 4'hC: hex2char = 8'h43; // character 'C' + 4'hD: hex2char = 8'h44; // character 'D' + 4'hE: hex2char = 8'h45; // character 'E' + 4'hF: hex2char = 8'h46; // character 'F' + endcase +endfunction
diff --git a/verilog/dv/uart_master/Makefile b/verilog/dv/uart_master/Makefile new file mode 100644 index 0000000..fdaa47d --- /dev/null +++ b/verilog/dv/uart_master/Makefile
@@ -0,0 +1,120 @@ +# 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 + +## PDK +PDK_PATH = $(PDK_ROOT)/sky130A + +## Caravel Pointers +CARAVEL_ROOT ?= ../../../caravel +CARAVEL_PATH ?= $(CARAVEL_ROOT) +CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel +CARAVEL_VERILOG_PATH = $(CARAVEL_PATH)/verilog +CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl +CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel + +## User Project Pointers +UPRJ_VERILOG_PATH ?= ../../../verilog +UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl +UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl +UPRJ_BEHAVIOURAL_MODELS = ../model +UPRJ_BEHAVIOURAL_AGENTS = ../agents +UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes +UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs +UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes +UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes +UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include +## RISCV GCC +GCC_PATH?=/ef/apps/bin +GCC_PREFIX?=riscv32-unknown-elf +GCC64_PREFIX?=riscv64-unknown-elf + +## Simulation mode: RTL/GL +SIM_DEFINES = -DFUNCTIONAL -DSIM +SIM?=RTL +DUMP?=OFF + +.SUFFIXES: + +PATTERN = uart_master + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +vvp: ${PATTERN:=.vvp} + +%.vvp: %_tb.v %.hex +ifeq ($(SIM),RTL) + ifeq ($(DUMP),OFF) + iverilog -g2005-sv $(SIM_DEFINES) -I $(PDK_PATH) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \ + -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \ + $< -o $@ + else + iverilog -g2005-sv -DWFDUMP $(SIM_DEFINES) -I $(PDK_PATH) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \ + -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \ + -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \ + $< -o $@ + endif +else + iverilog $(SIM_DEFINES) -DGL -I $(PDK_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I$(UPRJ_GL_PATH) -I$(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(CARAVEL_FIRMWARE_PATH)/sections.lds $(CARAVEL_FIRMWARE_PATH)/start.s check-env + ${GCC64_PREFIX}-gcc -I $(CARAVEL_PATH) -march=rv32imc -mabi=ilp32 -Wl,-Bstatic,-T,$(CARAVEL_FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(CARAVEL_FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC64_PREFIX}-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC64_PREFIX}-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +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 $(GCC64_PREFIX)-gcc )) +# $(error $(GCC64_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 *.vcd *.log + +.PHONY: clean hex all
diff --git a/verilog/dv/uart_master/run_verilog b/verilog/dv/uart_master/run_verilog new file mode 100644 index 0000000..5ffed3c --- /dev/null +++ b/verilog/dv/uart_master/run_verilog
@@ -0,0 +1,20 @@ +# ////////////////////////////////////////////////////////////////////////////// +# // 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 new file mode 100644 index 0000000..1776e93 --- /dev/null +++ b/verilog/dv/uart_master/uart_master.c
@@ -0,0 +1,155 @@ +/* + * 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 "verilog/dv/caravel/defs.h" +#include "verilog/dv/caravel/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_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; + + + reg_la0_oenb = reg_la0_iena = 0x0000000; + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + reg_mprj_datal = 0xAB600000; + + reg_la0_oenb = reg_la0_iena = 0x0000000; + reg_la0_data = 0x000; + + //----------------------------------------------------- + // Start of User Functionality and take over the GPIO Pins + // ------------------------------------------------------ + // User block decide on the GPIO function + 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); + + //uart_cfg = 0x000; + //uart_cfg |= 0x1; // bit[0] - Enable Transmit Path + //uart_cfg |= 0x2; // bit[1] - Enable Receive Path + //uart_cfg |= 0x4; // bit[2] - Set 2 Stop Bit + //uart_cfg |= 0x0; // bit[15:4] - 16x Baud Clock + //uart_cfg |= 0x0; // bit[17:16] - Priority mode = 0 + uart_cfg = 0x007; + reg_la0_data = uart_cfg; + + + +}
diff --git a/verilog/dv/uart_master/uart_master_tb.v b/verilog/dv/uart_master/uart_master_tb.v new file mode 100644 index 0000000..c9c6604 --- /dev/null +++ b/verilog/dv/uart_master/uart_master_tb.v
@@ -0,0 +1,277 @@ +// 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 "uprj_netlists.v" +`include "caravel_netlists.v" +`include "spiflash.v" +`include "uart_agent.v" + +module uart_master_tb; + 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 ; + + + 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(1, uart_master_tb); + $dumpvars(1, uart_master_tb.uut); + $dumpvars(1, uart_master_tb.uut.mprj); + $dumpvars(1, uart_master_tb.uut.mprj.u_wb_host); + //$dumpvars(2, uart_master_tb.uut.mprj.u_pinmux); + end + `endif + + initial begin + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (30) begin + repeat (1000) @(posedge clock); + // $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("##########################################################"); + `ifdef GL + $display ("Monitor: Timeout, Test UART Master (GL) Failed"); + `else + $display ("Monitor: Timeout, Test UART Master (RTL) Failed"); + `endif + $display ("##########################################################"); + $display("%c[0m",27); + $finish; + end + + initial begin + 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_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); + wait(checkbits == 16'h AB60); + $display("Monitor: UART Master Test Started"); + + repeat (1000) @(posedge clock); + //$write ("\n(%t)Response:\n",$time); + 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('h3080_0000,'h1); + + repeat (2) @(posedge clock); + #1; + + $display("Monitor: Writing expected value"); + + test_fail = 0; + uartm_reg_write(32'h30020058,32'h11223344); + uartm_reg_write(32'h3002005C,32'h22334455); + uartm_reg_write(32'h30020060,32'h33445566); + uartm_reg_write(32'h30020064,32'h44556677); + uartm_reg_write(32'h30020068,32'h55667788); + uartm_reg_write(32'h3002006C,32'h66778899); + + uartm_reg_read_check(32'h30020058,32'h11223344); + uartm_reg_read_check(32'h3002005C,32'h22334455); + uartm_reg_read_check(32'h30020060,32'h33445566); + uartm_reg_read_check(32'h30020064,32'h44556677); + uartm_reg_read_check(32'h30020068,32'h55667788); + uartm_reg_read_check(32'h3002006C,32'h66778899); + + $display("###################################################"); + if(test_fail == 0) begin + `ifdef GL + $display("Monitor: Standalone User UART Master (GL) Passed"); + `else + $display("Monitor: Standalone User Uart Master (RTL) Passed"); + `endif + end else begin + `ifdef GL + $display("Monitor: Standalone User Uart Master (GL) Failed"); + `else + $display("Monitor: Standalone User Uart Master (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 uut ( + .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[35]; +assign mprj_io[34] = uart_rxd ; + +uart_agent tb_master_uart( + .mclk (clock ), + .txd (uart_rxd ), + .rxd (uart_txd ) + ); + + +`include "uart_master_tasks.sv" + +endmodule +`default_nettype wire
diff --git a/verilog/dv/user_uart_master/Makefile b/verilog/dv/user_uart_master/Makefile new file mode 100644 index 0000000..cb31b0b --- /dev/null +++ b/verilog/dv/user_uart_master/Makefile
@@ -0,0 +1,92 @@ +# SPDX-FileCopyrightText: 2020 Efabless Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# SPDX-License-Identifier: Apache-2.0 + +## Caravel Pointers +CARAVEL_ROOT ?= ../../../caravel +CARAVEL_PATH ?= $(CARAVEL_ROOT) +CARAVEL_FIRMWARE_PATH = $(CARAVEL_PATH)/verilog/dv/caravel +CARAVEL_VERILOG_PATH = $(CARAVEL_PATH)/verilog +CARAVEL_RTL_PATH = $(CARAVEL_VERILOG_PATH)/rtl +CARAVEL_BEHAVIOURAL_MODELS = $(CARAVEL_VERILOG_PATH)/dv/caravel + + +## User Project Pointers +UPRJ_VERILOG_PATH ?= ../../../verilog +UPRJ_RTL_PATH = $(UPRJ_VERILOG_PATH)/rtl +UPRJ_GL_PATH = $(UPRJ_VERILOG_PATH)/gl +UPRJ_BEHAVIOURAL_MODELS = ../model +UPRJ_BEHAVIOURAL_AGENTS = ../agents +UPRJ_INCLUDE_PATH1 = $(UPRJ_RTL_PATH)/syntacore/scr1/src/includes +UPRJ_INCLUDE_PATH2 = $(UPRJ_RTL_PATH)/sdram_ctrl/src/defs +UPRJ_INCLUDE_PATH3 = $(UPRJ_RTL_PATH)/i2cm/src/includes +UPRJ_INCLUDE_PATH4 = $(UPRJ_RTL_PATH)/usb1_host/src/includes +UPRJ_INCLUDE_PATH5 = $(UPRJ_RTL_PATH)/mbist/include + +## SYNTACORE FIRMWARE +SYNTACORE_FIRMWARE_PATH = $(UPRJ_VERILOG_PATH)/rtl/syntacore/scr1/sim/tests/common + + +## Simulation mode: RTL/GL +SIM?=RTL +DUMP?=OFF + +.SUFFIXES: + +PATTERN = user_uart_master + +all: ${PATTERN:=.vcd} + + +vvp: ${PATTERN:=.vvp} + +%.vvp: %_tb.v +ifeq ($(SIM),RTL) + ifeq ($(DUMP),OFF) + iverilog -g2005-sv -DFUNCTIONAL -DSIM -I $(PDK_PATH) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \ + -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \ + $< -o $@ + else + iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_RTL_PATH) -I $(UPRJ_VERILOG_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + -I $(UPRJ_INCLUDE_PATH1) -I $(UPRJ_INCLUDE_PATH2) -I $(UPRJ_INCLUDE_PATH3) \ + -I $(UPRJ_INCLUDE_PATH4) -I $(UPRJ_INCLUDE_PATH5) \ + $< -o $@ + endif +else + iverilog -g2005-sv -DFUNCTIONAL -DSIM -DGL -I $(PDK_PATH) \ + -I $(CARAVEL_BEHAVIOURAL_MODELS) -I $(CARAVEL_RTL_PATH) -I $(CARAVEL_VERILOG_PATH) \ + -I $(UPRJ_BEHAVIOURAL_MODELS) -I $(UPRJ_GL_PATH) \ + -I $(UPRJ_BEHAVIOURAL_AGENTS) \ + $< -o $@ +endif + +%.vcd: %.vvp + vvp $< + + + +# ---- Clean ---- + +clean: + rm -f *.vvp *.vcd *.log + +.PHONY: clean all
diff --git a/verilog/dv/user_uart_master/run_iverilog b/verilog/dv/user_uart_master/run_iverilog new file mode 100755 index 0000000..e461fd1 --- /dev/null +++ b/verilog/dv/user_uart_master/run_iverilog
@@ -0,0 +1,42 @@ +# ////////////////////////////////////////////////////////////////////////////// +# // 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> +# // ////////////////////////////////////////////////////////////////////////// +riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common user_uart.c -o user_uart.o + +riscv64-unknown-elf-gcc -O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las -D__RVC_EXT -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=1 -Wa,-march=rv32imc -march=rv32imc -mabi=ilp32 -DFLAGS_STR=\""-O2 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las "\" -D__ASSEMBLY__=1 -c -I./ -I../../rtl/syntacore/scr1/sim/tests/common/ ../../rtl/syntacore/scr1/sim/tests/common/crt_tcm.S -o crt_tcm.o + +riscv64-unknown-elf-gcc -o user_uart.elf -T ../../rtl/syntacore/scr1/sim/tests/common/link_tcm.ld user_uart.o crt_tcm.o -nostartfiles -nostdlib -lc -lgcc -march=rv32imc -mabi=ilp32 + +riscv64-unknown-elf-objcopy -O verilog user_uart.elf user_uart.hex + +riscv64-unknown-elf-objdump -D user_uart.elf > user_uart.dump + +rm crt_tcm.o user_uart.o + +#iverilog with waveform dump +iverilog -g2005-sv -DWFDUMP -DFUNCTIONAL -DSIM -I $PDK_PATH -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../ -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I ../../../verilog/rtl/i2cm/src/includes -I ../../../verilog/rtl/usb1_host/src/includes -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp + + +#iverilog -g2005-sv -I $PDK_PATH -DFUNCTIONAL -DSIM -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/rtl -I ../../../verilog -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp + +# GLS +#iverilog -g2005-sv -D GL -D FUNCTIONAL -I $PDK_PATH -I ../../../caravel/verilog/rtl -I ../ -I ../../../verilog/gl -I ../../../verilog -I /home/dinesha/workarea/pdk/sky130A -I ../../../verilog/rtl/syntacore/scr1/src/includes -I ../../../verilog/rtl/sdram_ctrl/src/defs -I $CARAVEL_ROOT/verilog/dv/caravel -I ../model -I ../agents user_uart_tb.v -o user_uart_tb.vvp +# + +vvp user_uart_tb.vvp | tee test.log + +\rm -rf user_uart_tb.vvp
diff --git a/verilog/dv/user_uart_master/user_uart.c b/verilog/dv/user_uart_master/user_uart.c new file mode 100644 index 0000000..99e0204 --- /dev/null +++ b/verilog/dv/user_uart_master/user_uart.c
@@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////////////////////// +// 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_uart_reg0 (*(volatile uint32_t*)0x10010000) +#define reg_mprj_uart_reg1 (*(volatile uint32_t*)0x10010004) +#define reg_mprj_uart_reg2 (*(volatile uint32_t*)0x10010008) +#define reg_mprj_uart_reg3 (*(volatile uint32_t*)0x1001000C) +#define reg_mprj_uart_reg4 (*(volatile uint32_t*)0x10010010) +#define reg_mprj_uart_reg5 (*(volatile uint32_t*)0x10010014) +#define reg_mprj_uart_reg6 (*(volatile uint32_t*)0x10010018) +#define reg_mprj_uart_reg7 (*(volatile uint32_t*)0x1001001C) +#define reg_mprj_uart_reg8 (*(volatile uint32_t*)0x10010020) + +int main() +{ + + while(1) { + // Check UART RX fifo has data, if available loop back the data + if(reg_mprj_uart_reg8 != 0) { + reg_mprj_uart_reg5 = reg_mprj_uart_reg6; + } + } + + return 0; +}
diff --git a/verilog/dv/user_uart_master/user_uart_master_tb.v b/verilog/dv/user_uart_master/user_uart_master_tb.v new file mode 100644 index 0000000..174bb5a --- /dev/null +++ b/verilog/dv/user_uart_master/user_uart_master_tb.v
@@ -0,0 +1,303 @@ +//////////////////////////////////////////////////////////////////////////// +// 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: Modified by Dinesh Annayya <dinesha@opencores.org> +////////////////////////////////////////////////////////////////////// +//// //// +//// Standalone User validation Test bench //// +//// //// +//// This file is part of the YIFive cores project //// +//// https://github.com/dineshannayya/yifive_r0.git //// +//// http://www.opencores.org/cores/yifive/ //// +//// //// +//// Description //// +//// This is a standalone test bench to validate the //// +//// Digital core using uart master i/f. //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +//// Revision : //// +//// 0.1 - 16th Feb 2021, Dinesh A //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +`default_nettype wire + +`timescale 1 ns / 1 ns + +`include "uprj_netlists.v" +`include "uart_agent.v" + + +`define ADDR_SPACE_UART 32'h3001_0000 +`define ADDR_SPACE_PINMUX 32'h3002_0000 + + +module user_uart_master_tb; + +reg clock ; +reg wb_rst_i ; +reg power1, power2; +reg power3, power4; + +reg wbd_ext_cyc_i; // strobe/request +reg wbd_ext_stb_i; // strobe/request +reg [31:0] wbd_ext_adr_i; // address +reg wbd_ext_we_i; // write +reg [31:0] wbd_ext_dat_i; // data output +reg [3:0] wbd_ext_sel_i; // byte enable + +wire [31:0] wbd_ext_dat_o; // data input +wire wbd_ext_ack_o; // acknowlegement +wire wbd_ext_err_o; // error + +// User I/O +wire [37:0] io_oeb ; +wire [37:0] io_out ; +wire [37:0] io_in ; + +wire [37:0] mprj_io ; +wire [7:0] mprj_io_0 ; +reg test_fail ; +reg [31:0] read_data ; +//---------------------------------- +// Uart Configuration +// --------------------------------- +reg [1:0] uart_data_bit ; +reg uart_stop_bits ; // 0: 1 stop bit; 1: 2 stop bit; +reg uart_stick_parity ; // 1: force even parity +reg uart_parity_en ; // parity enable +reg uart_even_odd_parity ; // 0: odd parity; 1: even parity + +reg [7:0] uart_data ; +reg [15:0] uart_divisor ; // divided by n * 16 +reg [15:0] uart_timeout ;// wait time limit + +reg [15:0] uart_rx_nu ; +reg [15:0] uart_tx_nu ; +reg [7:0] uart_write_data [0:39]; +reg uart_fifo_enable ; // fifo mode disable + +reg [127:0] la_data_in; +reg flag; + + +integer i,j; + + // 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; + la_data_in = 0; + end + + `ifdef WFDUMP + initial begin + $dumpfile("risc_boot.vcd"); + $dumpvars(0, user_uart_master_tb); + end + `endif + + initial begin + clock = 0; + wbd_ext_cyc_i ='h0; // strobe/request + wbd_ext_stb_i ='h0; // strobe/request + wbd_ext_adr_i ='h0; // address + wbd_ext_we_i ='h0; // write + wbd_ext_dat_i ='h0; // data output + wbd_ext_sel_i ='h0; // byte enable + end +initial +begin + wb_rst_i <= 1'b1; + 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 + + // UPDATE the RTL UART MASTER + la_data_in[0] = 1; // Enable Transmit Path + la_data_in[1] = 1; // Enable Received Path + la_data_in[2] = 1; // Enable Received Path + la_data_in[15:4] = ((uart_divisor+1)/16)-1; // Divisor value + la_data_in[17:16] = 2'b00; // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd + + #100; + wb_rst_i <= 1'b0; // Release reset + + $display("Monitor: Standalone User Uart master Test Started"); + + tb_master_uart.debug_mode = 0; // disable debug display + 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); + 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('h3080_0000,'h1); + + repeat (2) @(posedge clock); + #1; + + $display("Monitor: Writing expected value"); + + test_fail = 0; + uartm_reg_write(32'h30020058,32'h11223344); + uartm_reg_write(32'h3002005C,32'h22334455); + uartm_reg_write(32'h30020060,32'h33445566); + uartm_reg_write(32'h30020064,32'h44556677); + uartm_reg_write(32'h30020068,32'h55667788); + uartm_reg_write(32'h3002006C,32'h66778899); + + uartm_reg_read_check(32'h30020058,32'h11223344); + uartm_reg_read_check(32'h3002005C,32'h22334455); + uartm_reg_read_check(32'h30020060,32'h33445566); + uartm_reg_read_check(32'h30020064,32'h44556677); + uartm_reg_read_check(32'h30020068,32'h55667788); + uartm_reg_read_check(32'h3002006C,32'h66778899); + + + + $display("###################################################"); + if(test_fail == 0) begin + `ifdef GL + $display("Monitor: Standalone User UART Master (GL) Passed"); + `else + $display("Monitor: Standalone User Uart Master (RTL) Passed"); + `endif + end else begin + `ifdef GL + $display("Monitor: Standalone User Uart Master (GL) Failed"); + `else + $display("Monitor: Standalone User Uart Master (RTL) Failed"); + `endif + end + $display("###################################################"); + #100 + $finish; +end + + +wire USER_VDD1V8 = 1'b1; +wire VSS = 1'b0; + + +user_project_wrapper u_top( +`ifdef USE_POWER_PINS + .vccd1(USER_VDD1V8), // User area 1 1.8V supply + .vssd1(VSS), // User area 1 digital ground +`endif + .wb_clk_i (clock), // System clock + .user_clock2 (1'b1), // Real-time clock + .wb_rst_i (wb_rst_i), // Regular Reset signal + + .wbs_cyc_i (wbd_ext_cyc_i), // strobe/request + .wbs_stb_i (wbd_ext_stb_i), // strobe/request + .wbs_adr_i (wbd_ext_adr_i), // address + .wbs_we_i (wbd_ext_we_i), // write + .wbs_dat_i (wbd_ext_dat_i), // data output + .wbs_sel_i (wbd_ext_sel_i), // byte enable + + .wbs_dat_o (wbd_ext_dat_o), // data input + .wbs_ack_o (wbd_ext_ack_o), // acknowlegement + + + // Logic Analyzer Signals + .la_data_in (la_data_in) , + .la_data_out (), + .la_oenb ('0), + + + // IOs + .io_in (io_in) , + .io_out (io_out) , + .io_oeb (io_oeb) , + + .user_irq () + +); + +`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 = io_out[35]; +assign io_in[34] = uart_rxd ; + +uart_agent tb_master_uart( + .mclk (clock ), + .txd (uart_rxd ), + .rxd (uart_txd ) + ); + + + +`include "uart_master_tasks.sv" +endmodule +`default_nettype wire
diff --git a/verilog/rtl/lib/async_reg_bus.sv b/verilog/rtl/lib/async_reg_bus.sv new file mode 100644 index 0000000..2c02701 --- /dev/null +++ b/verilog/rtl/lib/async_reg_bus.sv
@@ -0,0 +1,305 @@ + + +//---------------------------------------------------------------------------------------------- +// This block translate the Reg Bus transaction from in_clk clock domain to out_clk clock domain. +// This block also generate and terminate the transfer if 512 cycle transaction is not completed +// Assumption +// 1. in_reg_cs will be asserted untill ack is received +// 2. reg_addr/reg_wdata/reg_be will be available during reg_cs +// 3. Ever after out_reg_ack de-asserted reg_rdata holds the old data +//---------------------------------------------------------------------------------------------- + +module async_reg_bus ( + // Initiator declartion + in_clk , + in_reset_n , + // Reg Bus Master + // outputs + in_reg_rdata , + in_reg_ack , + in_reg_timeout , + + // Inputs + in_reg_cs , + in_reg_addr , + in_reg_wdata , + in_reg_wr , + in_reg_be , + + // Target Declaration + out_clk , + out_reset_n , + // Reg Bus Slave + // output + out_reg_cs , + out_reg_addr , + out_reg_wdata , + out_reg_wr , + out_reg_be , + + // Inputs + out_reg_rdata , + out_reg_ack + ); +parameter AW = 26 ; // Address width +parameter DW = 32 ; // DATA WIDTH +parameter BEW = 4 ; // Byte enable width + +//---------------------------------------- +// Reg Bus reg inout declration +//---------------------------------------- +input in_clk ; // Initiator domain clock +input in_reset_n ; // Initiator domain reset + +input in_reg_cs ; // Initiator Chip Select +input [AW-1:0] in_reg_addr ; // Address bus +input [DW-1:0] in_reg_wdata ; // Write data +input in_reg_wr ; // Read/write indication, 1-> write +input [BEW-1:0] in_reg_be ; // Byte valid for write + +output [DW-1:0] in_reg_rdata ; // Read Data +output in_reg_ack ; // Reg Access done +output in_reg_timeout ; // Access error indication pulse + // Genererated if no target ack + // received + // within 512 cycle + +//--------------------------------------------- +// Reg Bus target inout declration +//--------------------------------------------- + +input out_clk ; // Target domain clock +input out_reset_n ; // Traget domain reset + +input [DW-1:0] out_reg_rdata ; // Read data +input out_reg_ack ; // target finish + +output out_reg_cs ; // Target Start indication +output [AW-1:0] out_reg_addr ; // Target address +output [DW-1:0] out_reg_wdata ; // Target write data +output out_reg_wr ; // Target Read/write ind, 1-> Write +output [BEW-1:0] out_reg_be ; // Target Byte enable + +//----------------------------------- +// Initiator Local Declaration +// ---------------------------------- +parameter INI_IDLE = 2'b00; +parameter INI_WAIT_ACK = 2'b01; +parameter INI_WAIT_TAR_DONE = 2'b10; + +reg [1:0] in_state ; // reg state +reg [8:0] in_timer ; // reg timout monitor timer +reg in_flag ; // reg handshake flag +reg in_reg_ack ; // reg reg access finish ind +reg [DW-1:0] in_reg_rdata ; // reg reg access read data +reg in_reg_timeout ; // reg time out error pulse + +//----------------------------------- +// Target Local Declaration +// ---------------------------------- +parameter TAR_IDLE = 2'b00; +parameter TAR_WAIT_ACK = 2'b01; +parameter TAR_WAIT_INI_DONE = 2'b10; + +reg [1:0] out_state ; // target state machine +reg out_flag ; // target handshake flag +reg out_reg_cs ; // Target Start indication + +reg [8:0] inititaor_timer ; // timeout counter +//----------------------------------------------- +// Double sync local declaration +// ---------------------------------------------- + +reg in_flag_s ; // Initiator handshake flag sync + // with target clk +reg in_flag_ss ; // Initiator handshake flag sync + // with target clk + +reg out_flag_s ; // target handshake flag sync + // with initiator clk +reg out_flag_ss ; // target handshake flag sync + // with initiator clck + + + + +assign out_reg_addr = in_reg_addr; +assign out_reg_wdata = in_reg_wdata; +assign out_reg_wr = in_reg_wr; +assign out_reg_be = in_reg_be; +//------------------------------------------------------ +// Initiator Domain logic +//------------------------------------------------------ + +always @(negedge in_reset_n or posedge in_clk) +begin + if(in_reset_n == 1'b0) + begin + in_state <= INI_IDLE; + in_timer <= 9'h0; + in_flag <= 1'b0; + in_reg_ack <= 1'b0; + in_reg_rdata <= {DW {1'b0}}; + in_reg_timeout<= 1'b0; + end + else + begin + case(in_state) + INI_IDLE : + begin + in_reg_ack <= 1'b0; + in_reg_timeout <= 1'b0; + in_timer <= 'h0; + // Wait for Initiator Start Indication + // Once the reg start is detected + // Set the reg flag and move to WAIT + // for ack from Target + if(in_reg_cs) begin + in_flag <= 1'b1; + in_state <= INI_WAIT_ACK; + end + end + INI_WAIT_ACK : + begin + //-------------------------------------------- + // 1. Wait for Out Flag == 1 + // 2. If the Out Flag =1 is not + // detected witin 512 cycle, exit with error indication + // 3. If Target flag detected, then de-assert + // reg_flag = 0 and move the tar_wait_done state + // --------------------------------------------- + if(out_flag_ss == 1'b1) begin + in_flag <= 1'b0; + in_reg_rdata <= out_reg_rdata; + in_reg_ack <= 1'b1; + in_state <= INI_WAIT_TAR_DONE; + end + else begin + if(in_timer == 9'h1FF) begin + in_flag <= 1'b0; + in_reg_ack <= 1'b1; + in_reg_rdata <= 32'h0; + in_reg_timeout <= 1'b1; + in_state <= INI_IDLE; + end + else begin + in_timer <= in_timer + 1; + end + end + end + INI_WAIT_TAR_DONE : + begin + in_reg_ack <= 1'b0; + //-------------------------------------------- + // 1. Wait for Target Flag == 0 + // 2. If Target flag = 0 detected, then remove + // move the idle state + // --------------------------------------------- + if(out_flag_ss == 1'b0) begin + in_state <= INI_IDLE; + end + end + default: + begin + in_state <= INI_IDLE; + in_timer <= 9'h0; + in_flag <= 1'b0; + in_reg_rdata <= {DW {1'b0}}; + in_reg_timeout <= 1'b0; + end + endcase + end +end + + +//------------------------------------------------------ +// target Domain logic +//------------------------------------------------------ +always @(negedge out_reset_n or posedge out_clk) +begin + if(out_reset_n == 1'b0) + begin + out_state <= TAR_IDLE; + out_flag <= 1'b0; + out_reg_cs <= 1'b0; + end + else + begin + case(out_state) + TAR_IDLE : + begin + // 1. Wait for Initiator flag assertion + // 2. Once the reg flag = 1 is detected + // Set the target_flag and initiate the + // target reg bus access + out_flag <= 1'b0; + if(in_flag_ss) begin + out_reg_cs <= 1'b1; + out_state <= TAR_WAIT_ACK; + end + end + TAR_WAIT_ACK : + begin + //-------------------------------------------- + // 1. Wait for reg Flag == 0 + // 2. If reg flag = 0 detected, then + // move the idle state + // --------------------------------------------- + if(out_reg_ack == 1'b1) + begin + out_reg_cs <= 1'b0; + out_flag <= 1'b1; + out_state <= TAR_WAIT_INI_DONE; + end + end + TAR_WAIT_INI_DONE : + begin + if(in_flag_ss == 1'b0) begin + out_flag <= 1'b0; + out_state <= TAR_IDLE; + end + end + default: + begin + out_state <= TAR_IDLE; + out_reg_cs <= 1'b0; + out_flag <= 1'b0; + end + endcase + end +end + +//------------------------------------------------------- +// Double Sync Logic +// ------------------------------------------------------ +always @(negedge in_reset_n or posedge in_clk) +begin + if(in_reset_n == 1'b0) + begin + out_flag_s <= 1'b0; + out_flag_ss <= 1'b0; + end + else + begin + out_flag_s <= out_flag; + out_flag_ss <= out_flag_s; + end +end + + +always @(negedge out_reset_n or posedge out_clk) +begin + if(out_reset_n == 1'b0) + begin + in_flag_s <= 1'b0; + in_flag_ss <= 1'b0; + end + else + begin + in_flag_s <= in_flag; + in_flag_ss <= in_flag_s; + end +end + + +endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv index 3588254..e3ae61b 100755 --- a/verilog/rtl/pinmux/src/pinmux.sv +++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -75,6 +75,10 @@ input logic spim_miso, output logic spim_mosi, + // UART MASTER I/F + output logic uartm_rxd , + input logic uartm_txd , + output logic pulse1m_mclk, output logic [31:0] pinmux_debug, @@ -168,11 +172,6 @@ //input logic [3:0] ssram_oen, //input logic [3:0] ssram_do, //output logic [3:0] ssram_di, -wire ssram_sck = 1'b0; -wire ssram_ss = 1'b0; -wire [3:0] ssram_oen = 1'b0; -wire [3:0] ssram_do = 4'b0; -logic [3:0] ssram_di; // pinmux clock skew control clk_skew_adjust u_skew_pinmux @@ -414,12 +413,12 @@ * sflash_io1 digital_io[27] * sflash_io2 digital_io[28] * sflash_io3 digital_io[29] -* ssram_sck digital_io[30] -* ssram_ss digital_io[31] -* ssram_io0 digital_io[32] -* ssram_io1 digital_io[33] -* ssram_io2 digital_io[34] -* ssram_io3 digital_io[35] +* reserved digital_io[30] +* reserved digital_io[31] +* reserved digital_io[32] +* reserved digital_io[33] +* uartm_rxd digital_io[34] +* uartm_txd digital_io[35] * usb_dp digital_io[36] * usb_dn digital_io[37] **************************************************************** @@ -531,10 +530,8 @@ sflash_di[2] = digital_io_in[28]; sflash_di[3] = digital_io_in[29]; - ssram_di[0] = digital_io_in[32]; - ssram_di[1] = digital_io_in[33]; - ssram_di[2] = digital_io_in[34]; - ssram_di[3] = digital_io_in[35]; + // UAR MASTER I/F + uartm_rxd = digital_io_in[34]; usb_dp_i = digital_io_in[36]; usb_dn_i = digital_io_in[37]; @@ -635,13 +632,15 @@ digital_io_out[28] = sflash_do[2] ; digital_io_out[29] = sflash_do[3] ; - // Serail SRAM - digital_io_out[30] = ssram_sck ; - digital_io_out[31] = ssram_ss ; - digital_io_out[32] = ssram_do[0] ; - digital_io_out[33] = ssram_do[1] ; - digital_io_out[34] = ssram_do[2] ; - digital_io_out[35] = ssram_do[3] ; + // Reserved + digital_io_out[30] = 1'b0; + digital_io_out[31] = 1'b0; + digital_io_out[32] = 1'b0; + digital_io_out[33] = 1'b0; + + // UART MASTER I/f + digital_io_out[34] = 1'b0 ; // RXD + digital_io_out[35] = uartm_txd ; // TXD // USB 1.1 digital_io_out[36] = usb_dp_o ; @@ -744,13 +743,14 @@ digital_io_oen[28] = sflash_oen[2]; digital_io_oen[29] = sflash_oen[3]; - // Serail SRAM + // Reserved digital_io_oen[30] = 1'b0 ; digital_io_oen[31] = 1'b0 ; - digital_io_oen[32] = ssram_oen[0]; - digital_io_oen[33] = ssram_oen[1]; - digital_io_oen[34] = ssram_oen[2]; - digital_io_oen[35] = ssram_oen[3]; + digital_io_oen[32] = 1'b0 ; + digital_io_oen[33] = 1'b0 ; + // UART MASTER + digital_io_oen[34] = 1'b1; // RXD + digital_io_oen[35] = 1'b0; // TXD // USB 1.1 digital_io_oen[36] = usb_oen;
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/pinmux_reg.sv index 06e259e..1e1addb 100644 --- a/verilog/rtl/pinmux/src/pinmux_reg.sv +++ b/verilog/rtl/pinmux/src/pinmux_reg.sv
@@ -668,7 +668,7 @@ //----------------------------------------- // Software Reg-2, Release date: <DAY><MONTH><YEAR> // ---------------------------------------- -gen_32b_reg #(32'h2012_2021) u_reg_23 ( +gen_32b_reg #(32'h2412_2021) u_reg_23 ( //List of Inputs .reset_n (h_reset_n ), .clk (mclk ), @@ -681,9 +681,9 @@ ); //----------------------------------------- -// Software Reg-3: Poject Revison 2.1 = 0002200 +// Software Reg-3: Poject Revison 2.1 = 0002300 // ---------------------------------------- -gen_32b_reg #(32'h0002_2000) u_reg_24 ( +gen_32b_reg #(32'h0002_3000) u_reg_24 ( //List of Inputs .reset_n (h_reset_n ), .clk (mclk ), @@ -770,8 +770,7 @@ //----------------------------------------------------------------- logic [31:0] cfg_bist_status_1; -assign cfg_bist_status_1 = { 16'h0, - bist_error_cnt3, 1'b0, bist_correct[3], bist_error[3], bist_done, +assign cfg_bist_status_1 = { bist_error_cnt3, 1'b0, bist_correct[3], bist_error[3], bist_done, bist_error_cnt2, 1'b0, bist_correct[2], bist_error[2], bist_done, bist_error_cnt1, 1'b0, bist_correct[1], bist_error[1], bist_done, bist_error_cnt0, 1'b0, bist_correct[0], bist_error[0], bist_done
diff --git a/verilog/rtl/uart2wb/src/run_verilog b/verilog/rtl/uart2wb/src/run_verilog new file mode 100644 index 0000000..c689827 --- /dev/null +++ b/verilog/rtl/uart2wb/src/run_verilog
@@ -0,0 +1 @@ +iverilog uart2wb.sv uart2_core.sv uart_msg_handler.v ../../uart/src/uart_rxfsm.sv ../../uart/src/uart_txfsm.sv ../../lib/double_sync_low.v ../../lib/clk_ctl.v ../../lib/reset_sync.sv
diff --git a/verilog/rtl/uart2wb/src/uart2_core.sv b/verilog/rtl/uart2wb/src/uart2_core.sv new file mode 100755 index 0000000..78daa1a --- /dev/null +++ b/verilog/rtl/uart2wb/src/uart2_core.sv
@@ -0,0 +1,192 @@ +////////////////////////////////////////////////////////////////////////////// +// 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> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// Tubo 8051 cores UART Interface Module //// +//// //// +//// This file is part of the Turbo 8051 cores project //// +//// http://www.opencores.org/cores/turbo8051/ //// +//// //// +//// Description //// +//// Turbo 8051 definitions. //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// +module uart2_core ( + input wire arst_n , // Async reset + input wire app_clk , // Application clock + + + // configuration control + 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 rate control + + // TX PATH Information + input wire tx_data_avail , // Indicate valid TXD Data + output wire tx_rd , // Indicate TXD Data Been Read + input wire [7:0]tx_data , // Indicate TXD Data Been + + + // RXD Information + input wire rx_ready , // Indicate Ready to accept the Read Data + output wire rx_wr , // Valid RXD Data + output wire [7:0]rx_data , // RXD Data + + // Status information + output wire frm_error , // framing error + output wire par_error , // par error + + output wire baud_clk_16x , // 16x Baud clock + output wire line_reset_n , // Reset sync to 16x Baud clock + + // Line Interface + input wire rxd , // uart rxd + output wire txd // uart txd + + ); + + + +//--------------------------------- +// Global Dec +// --------------------------------- + +// Wire Declaration + +wire [1 : 0] error_ind ; +wire si_ss ; + +// OpenSource CTS tool does not work with buffer as source point +// changed buf to max with select tied=0 +//ctech_clk_buf u_lineclk_buf (.A(line_clk_16x_in), .X(line_clk_16x)); +wire line_clk_16x; +ctech_mux2x1 u_uart_clk (.A0(line_clk_16x), .A1(1'b0), .S(1'b0), .X(baud_clk_16x)); + +// 16x Baud clock generation +// Example: to generate 19200 Baud clock from 50Mhz Link clock +// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16 +// cfg_baud_16x = 0xA0 (160) + +clk_ctl #(11) u_clk_ctl ( + // Outputs + .clk_o (line_clk_16x), + + // Inputs + .mclk (app_clk), + .reset_n (arst_n), + .clk_div_ratio (cfg_baud_16x) + ); + + +//################################### +// Line Reset Synchronization +//################################### +reset_sync u_line_rst ( + .scan_mode (1'b0 ), + .dclk (baud_clk_16x ), // Destination clock domain + .arst_n (arst_n ), // active low async reset + .srst_n (line_reset_n ) + ); + + + +uart_txfsm u_txfsm ( + . reset_n ( line_reset_n ), + . baud_clk_16x ( baud_clk_16x ), + + . cfg_tx_enable ( cfg_tx_enable ), + . cfg_stop_bit ( cfg_stop_bit ), + . cfg_pri_mod ( cfg_pri_mod ), + + // FIFO control signal + . fifo_empty ( !tx_data_avail ), + . fifo_rd ( tx_rd ), + . fifo_data ( tx_data ), + + // Line Interface + . so ( txd ) + ); + + +uart_rxfsm u_rxfsm ( + . reset_n ( line_reset_n ), + . baud_clk_16x ( baud_clk_16x ) , + + . cfg_rx_enable ( cfg_rx_enable ), + . cfg_stop_bit ( cfg_stop_bit ), + . cfg_pri_mod ( cfg_pri_mod ), + + . error_ind ( error_ind ), + + // FIFO control signal + . fifo_aval ( rx_ready ), + . fifo_wr ( rx_wr ), + . fifo_data ( rx_data ), + + // Line Interface + . si (si_ss ) + ); + +// Double Sync RXD +double_sync_low u_rxd_sync ( + .in_data (rxd ), + .out_clk (baud_clk_16x ), + .out_rst_n (line_reset_n ), + .out_data (si_ss ) + ); + + +assign frm_error = (error_ind == 2'b01); +assign par_error = (error_ind == 2'b10); + + + +endmodule
diff --git a/verilog/rtl/uart2wb/src/uart2wb.sv b/verilog/rtl/uart2wb/src/uart2wb.sv new file mode 100755 index 0000000..0bf50b3 --- /dev/null +++ b/verilog/rtl/uart2wb/src/uart2wb.sv
@@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////////////////////// +// 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> +// +////////////////////////////////////////////////////////////////////// +//// //// +//// UART2WB Top Module //// +//// //// +//// Description //// +//// 1. uart_core //// +//// 2. uart_msg_handler //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +module uart2wb ( + input wire arst_n , // sync reset + input wire app_clk , // sys clock + + // configuration control + 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 + + // Master Port + output wire wbm_cyc_o , // strobe/request + output wire wbm_stb_o , // strobe/request + output wire [31:0] wbm_adr_o , // address + output wire wbm_we_o , // write + output wire [31:0] wbm_dat_o , // data output + output wire [3:0] wbm_sel_o , // byte enable + input wire [31:0] wbm_dat_i , // data input + input wire wbm_ack_i , // acknowlegement + input wire wbm_err_i , // error + + // Status information + output wire frm_error , // framing error + output wire par_error , // par error + + output wire baud_clk_16x , // 16x Baud clock + + // Line Interface + input wire rxd , // uart rxd + output wire txd // uart txd + + ); + + + + + + +//------------------------------------- +//--------------------------------------- +// Control Unit interface +// -------------------------------------- + +wire [31:0] reg_addr ; // Register Address +wire [31:0] reg_wdata ; // Register Wdata +wire reg_req ; // Register Request +wire reg_wr ; // 1 -> write; 0 -> read +wire reg_ack ; // Register Ack +wire [31:0] reg_rdata ; +//-------------------------------------- +// TXD Path +// ------------------------------------- +wire tx_data_avail ; // Indicate valid TXD Data +wire [7:0] tx_data ; // TXD Data to be transmited +wire tx_rd ; // Indicate TXD Data Been Read + + +//-------------------------------------- +// RXD Path +// ------------------------------------- +wire rx_ready ; // Indicate Ready to accept the Read Data +wire [7:0] rx_data ; // RXD Data +wire rx_wr ; // Valid RXD Data + +wire line_reset_n ; + +assign wbm_cyc_o = wbm_stb_o; + + +// Async App clock to Uart clock handling + +async_reg_bus #(.AW(32), .DW(32),.BEW(4)) + u_async_reg_bus ( + // Initiator declartion + .in_clk (baud_clk_16x), + .in_reset_n (line_reset_n), + // Reg Bus Master + // outputs + .in_reg_rdata (reg_rdata), + .in_reg_ack (reg_ack), + .in_reg_timeout (), + + // Inputs + .in_reg_cs (reg_req), + .in_reg_addr (reg_addr), + .in_reg_wdata (reg_wdata), + .in_reg_wr (reg_wr), + .in_reg_be (4'hF), // No byte enable based support + + // Target Declaration + .out_clk (app_clk), + .out_reset_n (arst_n), + // Reg Bus Slave + // output + .out_reg_cs (wbm_stb_o), + .out_reg_addr (wbm_adr_o), + .out_reg_wdata (wbm_dat_o), + .out_reg_wr (wbm_we_o), + .out_reg_be (wbm_sel_o), + + // Inputs + .out_reg_rdata (wbm_dat_i), + .out_reg_ack (wbm_ack_i) + ); + + +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_stop_bit (cfg_stop_bit) , + .cfg_pri_mod (cfg_pri_mod) , + .cfg_baud_16x (cfg_baud_16x) , + + // TXD Information + .tx_data_avail (tx_data_avail) , + .tx_rd (tx_rd) , + .tx_data (tx_data) , + + + // RXD Information + .rx_ready (rx_ready) , + .rx_wr (rx_wr) , + .rx_data (rx_data) , + + // Status information + .frm_error (frm_error) , + .par_error (par_error) , + + .baud_clk_16x (baud_clk_16x) , + .line_reset_n (line_reset_n), + + // Line Interface + .rxd (rxd) , + .txd (txd) + + ); + + + +uart_msg_handler u_msg ( + .reset_n (arst_n ) , + .sys_clk (baud_clk_16x ) , + + + // UART-TX Information + .tx_data_avail (tx_data_avail) , + .tx_rd (tx_rd) , + .tx_data (tx_data) , + + + // UART-RX Information + .rx_ready (rx_ready) , + .rx_wr (rx_wr) , + .rx_data (rx_data) , + + // Towards Control Unit + .reg_addr (reg_addr), + .reg_wr (reg_wr), + .reg_wdata (reg_wdata), + .reg_req (reg_req), + .reg_ack (reg_ack), + .reg_rdata (reg_rdata) + + ); + +endmodule
diff --git a/verilog/rtl/uart2wb/src/uart_msg_handler.v b/verilog/rtl/uart2wb/src/uart_msg_handler.v new file mode 100755 index 0000000..471ff88 --- /dev/null +++ b/verilog/rtl/uart2wb/src/uart_msg_handler.v
@@ -0,0 +1,376 @@ +////////////////////////////////////////////////////////////////////// +//// //// +//// UART Message Handler Module //// +//// //// +//// This file is part of the uart2spi cores project //// +//// http://www.opencores.org/cores/uart2spi/ //// +//// //// +//// Description //// +//// Uart Message Handler definitions. //// +//// //// +//// To Do: //// +//// nothing //// +//// //// +//// Author(s): //// +//// - Dinesh Annayya, dinesha@opencores.org //// +//// //// +////////////////////////////////////////////////////////////////////// +//// //// +//// Copyright (C) 2000 Authors and OPENCORES.ORG //// +//// //// +//// This source file may be used and distributed without //// +//// restriction provided that this copyright statement is not //// +//// removed from the file and that any derivative work contains //// +//// the original copyright notice and the associated disclaimer. //// +//// //// +//// This source file is free software; you can redistribute it //// +//// and/or modify it under the terms of the GNU Lesser General //// +//// Public License as published by the Free Software Foundation; //// +//// either version 2.1 of the License, or (at your option) any //// +//// later version. //// +//// //// +//// This source is distributed in the hope that it will be //// +//// useful, but WITHOUT ANY WARRANTY; without even the implied //// +//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR //// +//// PURPOSE. See the GNU Lesser General Public License for more //// +//// details. //// +//// //// +//// You should have received a copy of the GNU Lesser General //// +//// Public License along with this source; if not, download it //// +//// from http://www.opencores.org/lgpl.shtml //// +//// //// +////////////////////////////////////////////////////////////////////// + +module uart_msg_handler ( + reset_n , + sys_clk , + + + // UART-TX Information + tx_data_avail, + tx_rd, + tx_data, + + + // UART-RX Information + rx_ready, + rx_wr, + rx_data, + + // Towards Register Interface + reg_addr, + reg_wr, + reg_wdata, + reg_req, + reg_ack, + reg_rdata + + ); + + +// 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 BREAK_CHAR 8'h0A + +//--------------------------------- +// Global Dec +// --------------------------------- + +input reset_n ; // line reset +input sys_clk ; // line clock + + +//-------------------------------------- +// UART TXD Path +// ------------------------------------- +output tx_data_avail ; // Indicate valid TXD Data available +output [7:0] tx_data ; // TXD Data to be transmited +input tx_rd ; // Indicate TXD Data Been Read + + +//-------------------------------------- +// UART RXD Path +// ------------------------------------- +output rx_ready ; // Indicate Ready to accept the Read Data +input [7:0] rx_data ; // RXD Data +input rx_wr ; // Valid RXD Data + +//--------------------------------------- +// Control Unit interface +// -------------------------------------- + +output [31:0] reg_addr ; // Operend-1 +output [31:0] reg_wdata ; // Operend-2 +output reg_req ; // Register Request +output reg_wr ; // 1 -> write; 0 -> read +input reg_ack ; // Register Ack +input [31:0] reg_rdata ; + +// Local Wire/Register Decleration +// +// +reg tx_data_avail ; +reg [7:0] tx_data ; +reg [16*8-1:0] TxMsgBuf ; // 16 Byte Tx Message Buffer +reg [4:0] TxMsgSize ; +reg [4:0] RxMsgCnt ; // Count the Receive Message Count +reg [3:0] State ; +reg [3:0] NextState ; +reg [15:0] cmd ; // command +reg [31:0] reg_addr ; // reg_addr +reg [31:0] reg_wdata ; // reg_addr +reg reg_wr ; // 1 -> Reg Write request, 0 -> Read Requestion +reg reg_req ; // 1 -> Register request + + +wire rx_ready = 1; +/**************************************************************** +* UART Message Hanlding Steps +* +* 1. On Reset Or Unknown command, Send the Default Message +* Select Option: +* wr <addr> <data> +* rd <addr> +* 2. Wait for User command <wr/rd> +* 3. On <wr> command move to write address phase; +* phase +* A. After write address phase move to write data phase +* B. After write data phase, once user press \r command ; send register req +* and write request and address + data +* C. On receiving register ack response; send <success> message back and move +* to state-2 +* 3. On <rd> command move to read address phase; +* A. After read address phase , once user press '\r' command; send +* register req , read request +* C. On receiving register ack response; send <response + read_data> message and move +* to state-2 +* *****************************************************************/ + +always @(negedge reset_n or posedge sys_clk) +begin + if(reset_n == 1'b0) begin + tx_data_avail <= 0; + reg_req <= 0; + reg_addr <= 0; + reg_wr <= 1'b0; // Read request + reg_wdata <= 0; + State <= `IDLE; + NextState <= `IDLE; + end else begin + case(State) + // Send Default Message + `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; + end + + // Send Default Message (Contd..) + `IDLE_TX_MSG1: begin + TxMsgBuf <= "wm <ad> <data>\n "; // Align to 16 character format by appending space character + TxMsgSize <= 15; + tx_data_avail <= 0; + State <= `TX_MSG; + NextState <= `IDLE_TX_MSG2; + end + + // Send Default Message (Contd..) + `IDLE_TX_MSG2: begin + TxMsgBuf <= "rm <ad>\n>> "; // Align to 16 character format by appending space character + TxMsgSize <= 10; + tx_data_avail <= 0; + RxMsgCnt <= 0; + State <= `TX_MSG; + NextState <= `RX_CMD_PHASE; + end + + // Wait for Response + `RX_CMD_PHASE: begin + if(rx_wr == 1) begin + //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the same + if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the same + //end else if(RxMsgCnt > 0 && rx_data == " ") begin // Check the command + end else if(RxMsgCnt > 0 && rx_data == 8'h20) begin // Check the command + reg_addr <= 0; + RxMsgCnt <= 0; + //if(cmd == "wm") begin + if(cmd == 16'h776D) begin + State <= `ADR_PHASE; + //end else if(cmd == "rm") begin + end else if(cmd == 16'h726D) begin + + State <= `ADR_PHASE; + end else begin // Unknow command + State <= `IDLE; + end + //end else if(rx_data == "\n") begin // Error State + end else if(rx_data == `BREAK_CHAR) begin // Error State + State <= `IDLE; + end + else begin + cmd <= (cmd << 8) | rx_data ; + RxMsgCnt <= RxMsgCnt+1; + end + end + end + // Write Address Phase + `ADR_PHASE: begin + if(rx_wr == 1) begin + //if(RxMsgCnt == 0 && rx_data == " ") begin // Ignore the Space character + if(RxMsgCnt == 0 && rx_data == 8'h20) begin // Ignore the Space character + end else if(RxMsgCnt > 0 && (rx_data == 8'h20 || rx_data == `BREAK_CHAR)) begin // Move to write data phase + //if(RxMsgCnt > 0 && "wm" && rx_data == " ") begin // Move to write data phase + if(cmd == 16'h776D && rx_data == 8'h20) begin // Move to write data phase + reg_wdata <= 0; + State <= `WR_DATA_PHASE; + // end else if(RxMsgCnt > 0 && "rm" && rx_data == "\n") begin // Move to read data phase + end else if(cmd == 16'h726D && rx_data == `BREAK_CHAR) begin // Move to read data phase + reg_wr <= 1'b0; // Read request + reg_req <= 1'b1; // Reg Request + State <= `SEND_RD_REQ; + end else begin // Unknow command + State <= `IDLE; + end + //end else if(rx_data == "\n") begin // Error State + end else if(rx_data == `BREAK_CHAR) begin // Error State + State <= `IDLE; + end else begin + reg_addr <= (reg_addr << 4) | char2hex(rx_data); + RxMsgCnt <= RxMsgCnt+1; + end + end + end + // Write Data Phase + `WR_DATA_PHASE: begin + if(rx_wr == 1) begin + //if(rx_data == " ") begin // Ignore the Space character + if(rx_data == 8'h20) begin // Ignore the Space character + //end else if(rx_data == "\n") begin // Error State + end else if(rx_data == `BREAK_CHAR) begin // Error State + State <= `SEND_WR_REQ; + reg_wr <= 1'b1; // Write request + reg_req <= 1'b1; + end else begin // A to F + reg_wdata <= (reg_wdata << 4) | char2hex(rx_data); + end + end + end + `SEND_WR_REQ: begin + if(reg_ack) begin + reg_req <= 1'b0; + TxMsgBuf <= "cmd success\n>> "; // Align to 16 character format by appending space character + TxMsgSize <= 14; + tx_data_avail <= 0; + State <= `TX_MSG; + NextState <= `RX_CMD_PHASE; + end + end + + `SEND_RD_REQ: begin + if(reg_ack) begin + reg_req <= 1'b0; + TxMsgBuf <= "Response: "; // Align to 16 character format by appending space character + TxMsgSize <= 10; + tx_data_avail <= 0; + State <= `TX_MSG; + NextState <= `SEND_RD_DATA; + end + end + `SEND_RD_DATA: begin // Wait for Operation Completion + TxMsgBuf[16*8-1:15*8] <= hex2char(reg_rdata[31:28]); + TxMsgBuf[15*8-1:14*8] <= hex2char(reg_rdata[27:24]); + TxMsgBuf[14*8-1:13*8] <= hex2char(reg_rdata[23:20]); + TxMsgBuf[13*8-1:12*8] <= hex2char(reg_rdata[19:16]); + TxMsgBuf[12*8-1:11*8] <= hex2char(reg_rdata[15:12]); + TxMsgBuf[11*8-1:10*8] <= hex2char(reg_rdata[11:8]); + TxMsgBuf[10*8-1:9*8] <= hex2char(reg_rdata[7:4]); + TxMsgBuf[9*8-1:8*8] <= hex2char(reg_rdata[3:0]); + TxMsgBuf[8*8-1:7*8] <= "\n"; + TxMsgSize <= 9; + tx_data_avail <= 0; + State <= `TX_MSG; + NextState <= `RX_CMD_PHASE; + end + + // Send Default Message (Contd..) + `TX_MSG: begin + tx_data_avail <= 1; + tx_data <= TxMsgBuf[16*8-1:15*8]; + if(TxMsgSize == 0) begin + tx_data_avail <= 0; + State <= NextState; + end else if(tx_rd) begin + TxMsgBuf <= TxMsgBuf << 8; + TxMsgSize <= TxMsgSize -1; + end + end + endcase + end +end + + +// Character to hex number +function [3:0] char2hex; +input [7:0] data_in; +case (data_in) + 8'h30: char2hex = 4'h0; // character '0' + 8'h31: char2hex = 4'h1; // character '1' + 8'h32: char2hex = 4'h2; // character '2' + 8'h33: char2hex = 4'h3; // character '3' + 8'h34: char2hex = 4'h4; // character '4' + 8'h35: char2hex = 4'h5; // character '5' + 8'h36: char2hex = 4'h6; // character '6' + 8'h37: char2hex = 4'h7; // character '7' + 8'h38: char2hex = 4'h8; // character '8' + 8'h39: char2hex = 4'h9; // character '9' + 8'h41: char2hex = 4'hA; // character 'A' + 8'h42: char2hex = 4'hB; // character 'B' + 8'h43: char2hex = 4'hC; // character 'C' + 8'h44: char2hex = 4'hD; // character 'D' + 8'h45: char2hex = 4'hE; // character 'E' + 8'h46: char2hex = 4'hF; // character 'F' + 8'h61: char2hex = 4'hA; // character 'a' + 8'h62: char2hex = 4'hB; // character 'b' + 8'h63: char2hex = 4'hC; // character 'c' + 8'h64: char2hex = 4'hD; // character 'd' + 8'h65: char2hex = 4'hE; // character 'e' + 8'h66: char2hex = 4'hF; // character 'f' + default : char2hex = 4'hF; + endcase +endfunction + +// Hex to Asci Character +function [7:0] hex2char; +input [3:0] data_in; +case (data_in) + 4'h0: hex2char = 8'h30; // character '0' + 4'h1: hex2char = 8'h31; // character '1' + 4'h2: hex2char = 8'h32; // character '2' + 4'h3: hex2char = 8'h33; // character '3' + 4'h4: hex2char = 8'h34; // character '4' + 4'h5: hex2char = 8'h35; // character '5' + 4'h6: hex2char = 8'h36; // character '6' + 4'h7: hex2char = 8'h37; // character '7' + 4'h8: hex2char = 8'h38; // character '8' + 4'h9: hex2char = 8'h39; // character '9' + 4'hA: hex2char = 8'h41; // character 'A' + 4'hB: hex2char = 8'h42; // character 'B' + 4'hC: hex2char = 8'h43; // character 'C' + 4'hD: hex2char = 8'h44; // character 'D' + 4'hE: hex2char = 8'h45; // character 'E' + 4'hF: hex2char = 8'h46; // character 'F' + endcase +endfunction +endmodule
diff --git a/verilog/rtl/uprj_netlists.v b/verilog/rtl/uprj_netlists.v index 18389aa..1b7e48c 100644 --- a/verilog/rtl/uprj_netlists.v +++ b/verilog/rtl/uprj_netlists.v
@@ -157,6 +157,12 @@ `include "mbist/src/top/mbist_top.sv" + + `include "uart2wb/src/uart2wb.sv" + `include "uart2wb/src/uart2_core.sv" + `include "uart2wb/src/uart_msg_handler.v" + `include "lib/async_reg_bus.sv" + `include "user_project_wrapper.v" // we are using netlist file for clk_skew_adjust as it has // standard cell + power pin
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v index 916a1fd..8c699ef 100644 --- a/verilog/rtl/user_project_wrapper.v +++ b/verilog/rtl/user_project_wrapper.v
@@ -139,6 +139,8 @@ //// 2.2 Dec 20, 2021, Dinesh A //// //// 1. MBIST design issue fix for yosys //// //// 2. Full chip Timing and Transition clean-up //// +//// 2.3 Dec 24, 2021, Dinesh A //// +//// UART Master added with message handler at wb_host //// ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Authors and OPENCORES.ORG //// @@ -496,6 +498,12 @@ wire usb_intr_o ; wire i2cm_intr_o ; +//---------------------------------------------------------------- +// UART Master I/F +// ------------------------------------------------------------- +wire uartm_rxd ; +wire uartm_txd ; + //---------------------------------------------------------- // BIST I/F // --------------------------------------------------------- @@ -643,7 +651,13 @@ .wbs_err_i (wbd_int_err_o ), .cfg_clk_ctrl1 (cfg_clk_ctrl1 ), - .cfg_clk_ctrl2 (cfg_clk_ctrl2 ) + .cfg_clk_ctrl2 (cfg_clk_ctrl2 ), + + .la_data_in (la_data_in[17:0] ), + + .uartm_rxd (uartm_rxd ), + .uartm_txd (uartm_txd ) + ); @@ -1158,6 +1172,11 @@ .spim_miso (sspim_so ), .spim_mosi (sspim_si ), + // UART MASTER I/F + .uartm_rxd (uartm_rxd ), + .uartm_txd (uartm_txd ), + + .pulse1m_mclk (pulse1m_mclk ), .pinmux_debug (pinmux_debug ),
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv index 988f9eb..7cead10 100644 --- a/verilog/rtl/wb_host/src/wb_host.sv +++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -122,7 +122,12 @@ input logic wbs_err_i , // error output logic [31:0] cfg_clk_ctrl1 , - output logic [31:0] cfg_clk_ctrl2 + output logic [31:0] cfg_clk_ctrl2 , + + input logic [17:0] la_data_in , + + input logic uartm_rxd , + output logic uartm_txd ); @@ -133,9 +138,6 @@ //-------------------------------- logic wbm_rst_n; logic wbs_rst_n; -logic [31:0] wbm_dat_int; // data input -logic wbm_ack_int; // acknowlegement -logic wbm_err_int; // error logic reg_sel ; logic [1:0] sw_addr ; @@ -152,8 +154,6 @@ logic sw_wr_en_2; logic sw_wr_en_3; logic [7:0] cfg_bank_sel; -logic [31:0] wbm_adr_int; -logic wbm_stb_int; logic [31:0] reg_0; // Software_Reg_0 logic [2:0] cfg_wb_clk_ctrl; @@ -162,6 +162,32 @@ logic [3:0] cfg_usb_clk_ctrl; logic [8:0] cfg_glb_ctrl; +// uart Master Port +logic wbm_uart_cyc_i ; // strobe/request +logic wbm_uart_stb_i ; // strobe/request +logic [31:0] wbm_uart_adr_i ; // address +logic wbm_uart_we_i ; // write +logic [31:0] wbm_uart_dat_i ; // data output +logic [3:0] wbm_uart_sel_i ; // byte enable +logic [31:0] wbm_uart_dat_o ; // data input +logic wbm_uart_ack_o ; // acknowlegement +logic wbm_uart_err_o ; // error + +// Selected Master Port +logic wb_cyc_i ; // strobe/request +logic wb_stb_i ; // strobe/request +logic [31:0] wb_adr_i ; // address +logic wb_we_i ; // write +logic [31:0] wb_dat_i ; // data output +logic [3:0] wb_sel_i ; // byte enable +logic [31:0] wb_dat_o ; // data input +logic wb_ack_o ; // acknowlegement +logic wb_err_o ; // error +logic [31:0] wb_adr_int ; +logic wb_stb_int ; +logic [31:0] wb_dat_int ; // data input +logic wb_ack_int ; // acknowlegement +logic wb_err_int ; // error assign wbm_rst_n = !wbm_rst_i; assign wbs_rst_n = !wbm_rst_i; @@ -175,6 +201,73 @@ ctech_buf u_buf_usb_rst (.A(cfg_glb_ctrl[6]),.X(usb_rst_n)); ctech_buf u_buf_bist_rst (.A(cfg_glb_ctrl[7]),.X(bist_rst_n)); + +// UART Master +uart2wb u_uart2wb ( + .arst_n (wbm_rst_n ), // sync reset + .app_clk (wbm_clk_i ), // sys clock + + // configuration control + .cfg_tx_enable (la_data_in[0] ), // Enable Transmit Path + .cfg_rx_enable (la_data_in[1] ), // Enable Received Path + .cfg_stop_bit (la_data_in[2] ), // 0 -> 1 Start , 1 -> 2 Stop Bits + .cfg_baud_16x (la_data_in[15:4] ), // 16x Baud clock generation + .cfg_pri_mod (la_data_in[17:16] ), // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd + + // Master Port + .wbm_cyc_o (wbm_uart_cyc_i ), // strobe/request + .wbm_stb_o (wbm_uart_stb_i ), // strobe/request + .wbm_adr_o (wbm_uart_adr_i ), // address + .wbm_we_o (wbm_uart_we_i ), // write + .wbm_dat_o (wbm_uart_dat_i ), // data output + .wbm_sel_o (wbm_uart_sel_i ), // byte enable + .wbm_dat_i (wbm_uart_dat_o ), // data input + .wbm_ack_i (wbm_uart_ack_o ), // acknowlegement + .wbm_err_i (wbm_uart_err_o ), // error + + // Status information + .frm_error (), // framing error + .par_error (), // par error + + .baud_clk_16x (), // 16x Baud clock + + // Line Interface + .rxd (uartm_rxd) , // uart rxd + .txd (uartm_txd) // uart txd + + ); + + +// Arbitor to select between external wb vs uart wb +wire [1:0] grnt; +wb_arb u_arb( + .clk (wbm_clk_i), + .rstn (wbm_rst_n), + .req ({1'b0,wbm_uart_stb_i,wbm_stb_i}), + .gnt (grnt) + ); + +// Select the master based on the grant +assign wb_cyc_i = (grnt == 2'b00) ? wbm_cyc_i : wbm_uart_cyc_i; +assign wb_stb_i = (grnt == 2'b00) ? wbm_stb_i : wbm_uart_stb_i; +assign wb_adr_i = (grnt == 2'b00) ? wbm_adr_i : wbm_uart_adr_i; +assign wb_we_i = (grnt == 2'b00) ? wbm_we_i : wbm_uart_we_i; +assign wb_dat_i = (grnt == 2'b00) ? wbm_dat_i : wbm_uart_dat_i; +assign wb_sel_i = (grnt == 2'b00) ? wbm_sel_i : wbm_uart_sel_i; + +assign wbm_dat_o = (grnt == 2'b00) ? wb_dat_o : 'h0; +assign wbm_ack_o = (grnt == 2'b00) ? wb_ack_o : 'h0; +assign wbm_err_o = (grnt == 2'b00) ? wb_err_o : 'h0; + + +assign wbm_uart_dat_o = (grnt == 2'b01) ? wb_dat_o : 'h0; +assign wbm_uart_ack_o = (grnt == 2'b01) ? wb_ack_o : 'h0; +assign wbm_uart_err_o = (grnt == 2'b01) ? wb_err_o : 'h0; + + + + + // wb_host clock skew control clk_skew_adjust u_skew_wh ( @@ -190,27 +283,28 @@ // To reduce the load/Timing Wishbone I/F, Strobe is register to create // multi-cycle -wire [31:0] wbm_dat_o1 = (reg_sel) ? reg_rdata : wbm_dat_int; // data input -wire wbm_ack_o1 = (reg_sel) ? reg_ack : wbm_ack_int; // acknowlegement -wire wbm_err_o1 = (reg_sel) ? 1'b0 : wbm_err_int; // error +wire [31:0] wb_dat_o1 = (reg_sel) ? reg_rdata : wb_dat_int; // data input +wire wb_ack_o1 = (reg_sel) ? reg_ack : wb_ack_int; // acknowlegement +wire wb_err_o1 = (reg_sel) ? 1'b0 : wb_err_int; // error logic wb_req; // Hold fix for STROBE -wire wbm_stb_d1,wbm_stb_d2,wbm_stb_d3; -ctech_delay_buf u_delay1_stb0 (.X(wbm_stb_d1),.A(wbm_stb_i)); -ctech_delay_buf u_delay2_stb1 (.X(wbm_stb_d2),.A(wbm_stb_d1)); -ctech_delay_buf u_delay2_stb2 (.X(wbm_stb_d3),.A(wbm_stb_d2)); +wire wb_stb_d1,wb_stb_d2,wb_stb_d3; +ctech_delay_buf u_delay1_stb0 (.X(wb_stb_d1),.A(wb_stb_i)); +ctech_delay_buf u_delay2_stb1 (.X(wb_stb_d2),.A(wb_stb_d1)); +ctech_delay_buf u_delay2_stb2 (.X(wb_stb_d3),.A(wb_stb_d2)); always_ff @(negedge wbm_rst_n or posedge wbm_clk_i) begin if ( wbm_rst_n == 1'b0 ) begin wb_req <= '0; - wbm_dat_o <= '0; - wbm_ack_o <= '0; - wbm_err_o <= '0; + wb_dat_o <= '0; + wb_ack_o <= '0; + wb_err_o <= '0; end else begin - wb_req <= wbm_stb_d3 && ((wbm_ack_o == 0) && (wbm_ack_o1 == 0)) ; - wbm_dat_o <= wbm_dat_o1; - wbm_ack_o <= wbm_ack_o1; - wbm_err_o <= wbm_err_o1; + wb_req <= wb_stb_d3 && ((wb_ack_o == 0) && (wb_ack_o1 == 0)) ; + wb_ack_o <= wb_ack_o1; + wb_err_o <= wb_err_o1; + if(wb_ack_o1) // Keep last data in the bus + wb_dat_o <= wb_dat_o1; end end @@ -228,11 +322,11 @@ // added indirect MSB 8 bit address select option // So Address will be {Bank_Sel[7:0], wbm_adr_i[23:0} // --------------------------------------------------------------------- -assign reg_sel = wb_req & (wbm_adr_i[23] == 1'b1); +assign reg_sel = wb_req & (wb_adr_i[23] == 1'b1); -assign sw_addr = wbm_adr_i [3:2]; -assign sw_rd_en = reg_sel & !wbm_we_i; -assign sw_wr_en = reg_sel & wbm_we_i; +assign sw_addr = wb_adr_i [3:2]; +assign sw_rd_en = reg_sel & !wb_we_i; +assign sw_wr_en = reg_sel & wb_we_i; assign sw_wr_en_0 = sw_wr_en && (sw_addr==0); assign sw_wr_en_1 = sw_wr_en && (sw_addr==1); @@ -287,7 +381,7 @@ generic_register #(32,0 ) u_glb_ctrl ( .we ({32{sw_wr_en_0}} ), - .data_in (wbm_dat_i[31:0] ), + .data_in (wb_dat_i[31:0] ), .reset_n (wbm_rst_n ), .clk (wbm_clk_i ), @@ -297,7 +391,7 @@ generic_register #(8,8'h10 ) u_bank_sel ( .we ({8{sw_wr_en_1}} ), - .data_in (wbm_dat_i[7:0] ), + .data_in (wb_dat_i[7:0] ), .reset_n (wbm_rst_n ), .clk (wbm_clk_i ), @@ -308,7 +402,7 @@ generic_register #(32,0 ) u_clk_ctrl1 ( .we ({32{sw_wr_en_2}} ), - .data_in (wbm_dat_i[31:0] ), + .data_in (wb_dat_i[31:0] ), .reset_n (wbm_rst_n ), .clk (wbm_clk_i ), @@ -318,7 +412,7 @@ generic_register #(32,0 ) u_clk_ctrl2 ( .we ({32{sw_wr_en_3}} ), - .data_in (wbm_dat_i[31:0] ), + .data_in (wb_dat_i[31:0] ), .reset_n (wbm_rst_n ), .clk (wbm_clk_i ), @@ -327,25 +421,25 @@ ); -assign wbm_stb_int = wb_req & !reg_sel; +assign wb_stb_int = wb_req & !reg_sel; // Since design need more than 16MB address space, we have implemented // indirect access -assign wbm_adr_int = {cfg_bank_sel[7:0],wbm_adr_i[23:0]}; +assign wb_adr_int = {cfg_bank_sel[7:0],wb_adr_i[23:0]}; async_wb u_async_wb( // Master Port .wbm_rst_n (wbm_rst_n ), .wbm_clk_i (wbm_clk_i ), - .wbm_cyc_i (wbm_cyc_i ), - .wbm_stb_i (wbm_stb_int ), - .wbm_adr_i (wbm_adr_int ), - .wbm_we_i (wbm_we_i ), - .wbm_dat_i (wbm_dat_i ), - .wbm_sel_i (wbm_sel_i ), - .wbm_dat_o (wbm_dat_int ), - .wbm_ack_o (wbm_ack_int ), - .wbm_err_o (wbm_err_int ), + .wbm_cyc_i (wb_cyc_i ), + .wbm_stb_i (wb_stb_int ), + .wbm_adr_i (wb_adr_int ), + .wbm_we_i (wb_we_i ), + .wbm_dat_i (wb_dat_i ), + .wbm_sel_i (wb_sel_i ), + .wbm_dat_o (wb_dat_int ), + .wbm_ack_o (wb_ack_int ), + .wbm_err_o (wb_err_int ), // Slave Port .wbs_rst_n (wbs_rst_n ),