rtl update
diff --git a/verilog/dv/common/agents/uart_master_tasks.sv b/verilog/dv/common/agents/uart_master_tasks.sv
index cd0af94..e18eff4 100644
--- a/verilog/dv/common/agents/uart_master_tasks.sv
+++ b/verilog/dv/common/agents/uart_master_tasks.sv
@@ -73,7 +73,7 @@
8'd17 : data[3:0] = char2hex(read_data);
endcase
i = i+1;
- $display("received Data: %x",data);
+ $display("received Data: 0x%x",data);
end
end
@@ -119,9 +119,9 @@
i = i+1;
end
if(rxd_data == exp_data) begin
- // $display("STATUS: ADDRESS: %x RXD: %x", addr,rxd_data);
+ $display("STATUS: ADDRESS: 0x%x RXD: 0x%x", addr,rxd_data);
end else begin
- $display("ERROR: ADDRESS: %x EXP: %x RXD: %x", addr,exp_data,rxd_data);
+ $display("ERROR: ADDRESS: 0x%x EXP: %x RXD: 0x%x", addr,exp_data,rxd_data);
test_fail = 1;
end
diff --git a/verilog/dv/common/agents/user_tasks.sv b/verilog/dv/common/agents/user_tasks.sv
index 2a1edbe..d78e5dc 100644
--- a/verilog/dv/common/agents/user_tasks.sv
+++ b/verilog/dv/common/agents/user_tasks.sv
@@ -145,6 +145,10 @@
);
+//--------------------------------------------------------
+// Apply Reset Sequence and wait for reset completion
+//-------------------------------------------------------
+
task init;
begin
//#1 - Apply Reset
@@ -231,9 +235,10 @@
// bit[31:24] - core-3
$display("Status: Waiting for RISCV Core Boot ... ");
read_data = 0;
- while((read_data >> (d_risc_id*8)) != 8'h1) begin
+ //while((read_data >> (d_risc_id*8)) != 8'h1) begin
+ while(read_data != 8'h1) begin // Temp fix - Hardcoded to risc_id = 0
wb_user_core_read(`ADDR_SPACE_GLBL+`GLBL_CFG_MAIL_BOX,read_data);
- repeat (1000) @(posedge clock);
+ repeat (100) @(posedge clock);
end
$display("Status: RISCV Core is Booted ");
@@ -250,7 +255,8 @@
// bit[31:24] - core-3
$display("Status: Waiting for RISCV Core Boot ... ");
read_data = 0;
- while((read_data >> (d_risc_id*8)) != 8'hFF) begin
+ //while((read_data >> (d_risc_id*8)) != 8'hFF) begin
+ while(read_data != 8'hFF) begin
wb_user_core_read(`ADDR_SPACE_GLBL+`GLBL_CFG_MAIL_BOX,read_data);
repeat (1000) @(posedge clock);
end
@@ -260,6 +266,23 @@
end
endtask
+//-----------------------
+// Set TB ready indication
+//-----------------------
+task set_tb_ready;
+begin
+ // GLBL_CFG_MAIL_BOX used as mail box, each core update boot up handshake at 8 bit
+ // bit[7:0] - core-0
+ // bit[15:8] - core-1
+ // bit[23:16] - core-2
+ // bit[31:24] - core-3
+ wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_MAIL_BOX,32'h81818181);
+
+ $display("Status: Set TB Ready Indication");
+
+end
+endtask
+
`endif
//-------------------------------
@@ -398,6 +421,34 @@
end
endtask
+ /*************************************************************************
+ * This is Baud Rate to clock divider conversion for Test Bench
+ * Note: DUT uses 16x baud clock, where are test bench uses directly
+ * baud clock, Due to 16x Baud clock requirement at RTL, there will be
+ * some resolution loss, we expect at lower baud rate this resolution
+ * loss will be less. For Quick simulation perpose higher baud rate used
+ * *************************************************************************/
+ task tb_set_uart_baud;
+ input [31:0] ref_clk;
+ input [31:0] baud_rate;
+ output [31:0] baud_div;
+ reg [31:0] baud_div;
+ begin
+// for 230400 Baud = (50Mhz/230400) = 216.7
+baud_div = ref_clk/baud_rate; // Get the Bit Baud rate
+// Baud 16x = 216/16 = 13
+ baud_div = baud_div/16; // To find the RTL baud 16x div value to find similar resolution loss in test bench
+// Test bench baud clock , 16x of above value
+// 13 * 16 = 208,
+// (Note if you see original value was 216, now it's 208 )
+ baud_div = baud_div * 16;
+// Test bench half cycle counter to toggle it
+// 208/2 = 104
+ baud_div = baud_div/2;
+//As counter run's from 0 , substract from 1
+ baud_div = baud_div-1;
+ end
+ endtask
/**
`ifdef GL
diff --git a/verilog/rtl/gpio/src/gpio_reg.sv b/verilog/rtl/gpio/src/gpio_reg.sv
index 10b90bd..a8528eb 100644
--- a/verilog/rtl/gpio/src/gpio_reg.sv
+++ b/verilog/rtl/gpio/src/gpio_reg.sv
@@ -28,7 +28,7 @@
//// nothing ////
//// ////
//// Author(s): ////
-//// - Dinesh Annayya, dinesha@opencores.org ////
+//// - Dinesh Annayya, dinesh.annayya@gmail.com ////
//// ////
//// Revision : ////
//// 0.1 - 15th Aug 2022, Dinesh A ////
@@ -168,26 +168,20 @@
//-----------------------------------------------------------------------
// Logic for gpio_data_in
//-----------------------------------------------------------------------
-logic [31:0] gpio_in_data_s;
-logic [31:0] gpio_in_data_ss;
// Double Sync the gpio pin data for edge detection
always @ (posedge mclk or negedge h_reset_n)
begin
if (h_reset_n == 1'b0) begin
reg_2 <= 'h0 ;
- gpio_in_data_s <= 32'd0;
- gpio_in_data_ss <= 32'd0;
end
else begin
- gpio_in_data_s <= gpio_in_data;
- gpio_in_data_ss <= gpio_in_data_s;
- reg_2 <= gpio_in_data_ss;
+ reg_2 <= gpio_in_data;
end
end
-assign cfg_gpio_data_in = reg_2[31:0]; // to be used for edge interrupt detect
-assign gpio_prev_indata = gpio_in_data_ss;
+assign cfg_gpio_data_in = gpio_in_data; // to be used for edge interrupt detect
+assign gpio_prev_indata = reg_2[31:0];
//-----------------------------------------------------------------------
// Logic for cfg_gpio_out_data
diff --git a/verilog/rtl/gpio/src/gpio_top.sv b/verilog/rtl/gpio/src/gpio_top.sv
index 097623f..57a0092 100644
--- a/verilog/rtl/gpio/src/gpio_top.sv
+++ b/verilog/rtl/gpio/src/gpio_top.sv
@@ -41,6 +41,8 @@
// Inputs
input logic mclk,
input logic h_reset_n,
+ input logic cfg_gpio_dgmode, // 0 - De-glitch sampling on 1us
+ input logic pulse_1us,
// Reg Bus Interface Signal
input logic reg_cs,
@@ -58,6 +60,8 @@
input logic [31:0] pad_gpio_in,
output logic [31:0] pad_gpio_out,
+ output logic [7:0] pwm_gpio_in,
+
output logic [31:0] gpio_intr
);
@@ -70,6 +74,35 @@
logic [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt
logic [31:00] cfg_gpio_data_in ;
logic [31:0] gpio_int_event ;
+logic [31:0] gpio_dsync ;
+
+
+//------------------------------------------
+// Assign GPIO PORT-C as PWM GPIO
+//----------------------------------------
+
+assign pwm_gpio_in = gpio_dsync[23:16];
+
+//--------------------------------------
+// GPIO Ge-glitch logic
+//--------------------------------------
+genvar port;
+generate
+for (port = 0; $unsigned(port) < 32; port=port+1) begin : u_bit
+
+gpio_dglitch u_dglitch(
+ .reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse_1us (pulse_1us ),
+ .cfg_mode (cfg_gpio_dgmode ),
+ .gpio_in (pad_gpio_in[port] ),
+ .gpio_out (gpio_dsync[port])
+ );
+
+end
+endgenerate // dglitch
+
+
gpio_reg u_reg (
@@ -88,7 +121,7 @@
.reg_ack (reg_ack ),
// GPIO input pins
- .gpio_in_data (pad_gpio_in ),
+ .gpio_in_data (gpio_dsync ),
.gpio_prev_indata (gpio_prev_indata ),
.gpio_int_event (gpio_int_event ),
diff --git a/verilog/rtl/pinmux/src/glbl_reg.sv b/verilog/rtl/pinmux/src/glbl_reg.sv
index a8e21c7..46e5140 100644
--- a/verilog/rtl/pinmux/src/glbl_reg.sv
+++ b/verilog/rtl/pinmux/src/glbl_reg.sv
@@ -93,6 +93,7 @@
output logic [2:0] user_irq ,
input logic usb_intr ,
input logic i2cm_intr ,
+ input logic pwm_intr ,
output logic [15:0] cfg_riscv_ctrl ,
output logic [31:0] cfg_multi_func_sel ,// multifunction pins
@@ -108,7 +109,8 @@
output logic[25:0] cfg_dc_trim , // External trim for DCO mode
output logic pll_ref_clk , // Input oscillator to match
- output logic dbg_clk_mon
+ output logic dbg_clk_mon ,
+ output logic cfg_gpio_dgmode
);
@@ -344,10 +346,11 @@
.data_out (reg_2 )
);
-assign cfg_mon_sel = reg_2[7:4];
-assign soft_irq = reg_2[3];
-assign user_irq = reg_2[2:0];
-assign cfg_riscv_ctrl = reg_2[31:16];
+assign cfg_gpio_dgmode = reg_2[8]; // gpio de-glitch mode selection
+assign cfg_mon_sel = reg_2[7:4];
+assign soft_irq = reg_2[3];
+assign user_irq = reg_2[2:0];
+assign cfg_riscv_ctrl = reg_2[31:16];
//-----------------------------------------------------------------------
// reg-3 : Global Interrupt Mask
@@ -371,7 +374,7 @@
assign irq_lines = reg_3[31:0] & reg_4[31:0];
// In Arduino GPIO[7:0] is corresponds to PORT-A which is not available for user access
-wire [31:0] hware_intr_req = {gpio_intr[31:8], 3'b0,usb_intr, i2cm_intr,timer_intr[2:0]};
+wire [31:0] hware_intr_req = {gpio_intr[31:8], 2'b0,pwm_intr,usb_intr, i2cm_intr,timer_intr[2:0]};
generic_intr_stat_reg #(.WD(32),
.RESET_DEFAULT(0)) u_reg4 (
@@ -755,7 +758,7 @@
);
// Debug clock monitor optin
-assign dbg_clk_ref = (cfg_mon_sel == 4'b000) ? user_clock1 :
+wire dbg_clk_ref = (cfg_mon_sel == 4'b000) ? user_clock1 :
(cfg_mon_sel == 4'b001) ? user_clock2 :
(cfg_mon_sel == 4'b010) ? xtal_clk :
(cfg_mon_sel == 4'b011) ? int_pll_clock:
@@ -765,6 +768,7 @@
(cfg_mon_sel == 4'b111) ? rtc_clk : 1'b0;
// DIv16 to debug monitor purpose
+logic dbg_clk_div16;
clk_ctl #(3) u_dbgclk (
// Outputs
diff --git a/verilog/rtl/pinmux/src/pinmux_top.sv b/verilog/rtl/pinmux/src/pinmux_top.sv
index c9de5f1..706cbf0 100755
--- a/verilog/rtl/pinmux/src/pinmux_top.sv
+++ b/verilog/rtl/pinmux/src/pinmux_top.sv
@@ -206,11 +206,13 @@
logic s_reset_ssn; // Sync Reset
logic p_reset_ssn; // Sync Reset
logic [15:0] pad_strap_in;
-logic dbg_clk_mon;
-
+logic dbg_clk_mon;
+logic cfg_gpio_dgmode; // gpio de-glitch mode
+logic pwm_intr;
/* clock pulse */
//********************************************************
logic pulse_1ms ; // 1 Milli Second Pulse for waveform Generator
+logic pulse_1us ; // 1 Micro Second Pulse for waveform Generator
logic [5:0] cfg_pwm_enb ;
@@ -282,6 +284,8 @@
logic [31:0] reg_ws_rdata;
logic reg_ws_ack;
+logic [7:0] pwm_gpio_in;
+
assign reg_rdata = (reg_addr[9:7] == `SEL_GLBL) ? {reg_glbl_rdata} :
(reg_addr[9:7] == `SEL_GPIO) ? {reg_gpio_rdata} :
(reg_addr[9:7] == `SEL_PWM) ? {reg_pwm_rdata} :
@@ -394,6 +398,7 @@
.user_irq (user_irq ),
.usb_intr (usb_intr ),
.i2cm_intr (i2cm_intr ),
+ .pwm_intr (pwm_intr ),
@@ -407,7 +412,8 @@
.cfg_dc_trim (cfg_dc_trim ), // External trim for DCO mode
.pll_ref_clk (pll_ref_clk ), // Input oscillator to match
- .dbg_clk_mon (dbg_clk_mon )
+ .dbg_clk_mon (dbg_clk_mon ),
+ .cfg_gpio_dgmode (cfg_gpio_dgmode )
@@ -421,6 +427,8 @@
// Inputs
.mclk ( mclk ),
.h_reset_n (s_reset_ssn ),
+ .cfg_gpio_dgmode (cfg_gpio_dgmode ),
+ .pulse_1us (pulse_1us ),
// Reg Bus Interface Signal
.reg_cs (reg_gpio_cs ),
@@ -438,6 +446,7 @@
.cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
.pad_gpio_in (pad_gpio_in ),
.pad_gpio_out (pad_gpio_out ),
+ .pwm_gpio_in (pwm_gpio_in ),
.gpio_intr (gpio_intr )
@@ -456,7 +465,7 @@
// Reg Bus Interface Signal
.reg_cs (reg_pwm_cs ),
.reg_wr (reg_wr ),
- .reg_addr (reg_addr[4:2] ),
+ .reg_addr (reg_addr[6:2] ),
.reg_wdata (reg_wdata ),
.reg_be (reg_be ),
@@ -464,9 +473,9 @@
.reg_rdata (reg_pwm_rdata ),
.reg_ack (reg_pwm_ack ),
- .pulse_1ms (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb ),
- .pwm_wfm (pwm_wfm )
+ .pad_gpio (pwm_gpio_in ),
+ .pwm_wfm (pwm_wfm ),
+ .pwm_intr (pwm_intr )
);
//-----------------------------------------------------------------------
@@ -489,6 +498,7 @@
.reg_rdata (reg_timer_rdata ),
.reg_ack (reg_timer_ack ),
+ .pulse_1us (pulse_1us ),
.pulse_1ms (pulse_1ms ),
.timer_intr (timer_intr )
);
diff --git a/verilog/rtl/pinmux/src/strap_ctrl.sv b/verilog/rtl/pinmux/src/strap_ctrl.sv
index c0405b0..54ecdf4 100644
--- a/verilog/rtl/pinmux/src/strap_ctrl.sv
+++ b/verilog/rtl/pinmux/src/strap_ctrl.sv
@@ -92,9 +92,9 @@
2'b10 - Default value + 4
2'b11 - Default value - 4
bit [4:13] - uart master config control
- 2'b00 - constant value based on system clock-50Mhz (Default)
- 2'b01 - constant value based on system clock-40Mhz
- 2'b10 - constant value based on system clock-60Mhz (USB Ref Clock)
+ 2'b00 - Auto Detect (Default)
+ 2'b01 - constant value based on system clock-50Mhz
+ 2'b10 - constant value based on system clock-4Mhz
2'b11 - load from LA
bit [14:13] - Reserved
bit [15] - Strap Mode
diff --git a/verilog/rtl/timer/src/timer_top.sv b/verilog/rtl/timer/src/timer_top.sv
index 127d62f..c6aa3f9 100644
--- a/verilog/rtl/timer/src/timer_top.sv
+++ b/verilog/rtl/timer/src/timer_top.sv
@@ -53,6 +53,7 @@
output logic reg_ack,
output logic pulse_1ms,
+ output logic pulse_1us,
output logic [2:0] timer_intr
);
@@ -67,7 +68,6 @@
/* clock pulse */
//********************************************************
-logic pulse_1us ; // 1 UsSecond Pulse for waveform Generator
logic pulse_1s ; // 1Second Pulse for waveform Generator
logic [9:0] cfg_pulse_1us ; // 1us pulse generation config
diff --git a/verilog/rtl/uart2wb/src/uart2wb.sv b/verilog/rtl/uart2wb/src/uart2wb.sv
index 0bf50b3..25e6e2f 100755
--- a/verilog/rtl/uart2wb/src/uart2wb.sv
+++ b/verilog/rtl/uart2wb/src/uart2wb.sv
@@ -29,6 +29,10 @@
//// Author(s): ////
//// - Dinesh Annayya, dinesha@opencores.org ////
//// ////
+//// Revision : ////
+//// 0.1 - 12th Sep 2022, Dinesh A ////
+//// baud config auto detect for unknow system clock case////
+//// implemented specific to unknown caravel system clk ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
@@ -61,11 +65,12 @@
input wire app_clk , // sys clock
// configuration control
+ input wire cfg_auto_det , // Auto Baud Config detect mode
input wire cfg_tx_enable , // Enable Transmit Path
input wire cfg_rx_enable , // Enable Received Path
input wire cfg_stop_bit , // 0 -> 1 Start , 1 -> 2 Stop Bits
input wire [1:0] cfg_pri_mod , // priority mode, 0 -> nop, 1 -> Even, 2 -> Odd
- input wire [11:0] cfg_baud_16x , // 16x Baud clock generation
+ input wire [11:0] cfg_baud_16x , // 16x Baud clock generation
// Master Port
output wire wbm_cyc_o , // strobe/request
@@ -80,7 +85,7 @@
// Status information
output wire frm_error , // framing error
- output wire par_error , // par error
+ output wire par_error , // par error
output wire baud_clk_16x , // 16x Baud clock
@@ -122,9 +127,26 @@
wire rx_wr ; // Valid RXD Data
wire line_reset_n ;
+wire arst_ssn ;
+wire [11:0] auto_baud_16x ;
+wire auto_tx_enb ;
+wire auto_rx_enb ;
+
+
+wire cfg_tx_enable_i = (cfg_auto_det) ? auto_tx_enb: cfg_tx_enable;
+wire cfg_rx_enable_i = (cfg_auto_det) ? auto_rx_enb: cfg_rx_enable;
+wire [11:0] cfg_baud_16x_i = (cfg_auto_det) ? auto_baud_16x: cfg_baud_16x;
+
assign wbm_cyc_o = wbm_stb_o;
+reset_sync u_arst_sync (
+ .scan_mode (1'b0 ),
+ .dclk (app_clk ), // Destination clock domain
+ .arst_n (arst_n ), // active low async reset
+ .srst_n (arst_ssn )
+ );
+
// Async App clock to Uart clock handling
@@ -148,7 +170,7 @@
// Target Declaration
.out_clk (app_clk),
- .out_reset_n (arst_n),
+ .out_reset_n (arst_ssn),
// Reg Bus Slave
// output
.out_reg_cs (wbm_stb_o),
@@ -163,16 +185,30 @@
);
+
+uart_auto_det u_aut_det (
+ .mclk (app_clk ),
+ .reset_n (arst_ssn ),
+ .cfg_auto_det (cfg_auto_det ),
+ .rxd (rxd ),
+
+ .auto_baud_16x (auto_baud_16x ),
+ .auto_tx_enb (auto_tx_enb ),
+ .auto_rx_enb (auto_rx_enb )
+
+ );
+
+
uart2_core u_core (
.arst_n (arst_n) ,
.app_clk (app_clk) ,
// configuration control
- .cfg_tx_enable (cfg_tx_enable) ,
- .cfg_rx_enable (cfg_rx_enable) ,
+ .cfg_tx_enable (cfg_tx_enable_i) ,
+ .cfg_rx_enable (cfg_rx_enable_i) ,
.cfg_stop_bit (cfg_stop_bit) ,
.cfg_pri_mod (cfg_pri_mod) ,
- .cfg_baud_16x (cfg_baud_16x) ,
+ .cfg_baud_16x (cfg_baud_16x_i) ,
// TXD Information
.tx_data_avail (tx_data_avail) ,
@@ -187,10 +223,10 @@
// Status information
.frm_error (frm_error) ,
- .par_error (par_error) ,
+ .par_error (par_error) ,
- .baud_clk_16x (baud_clk_16x) ,
- .line_reset_n (line_reset_n),
+ .baud_clk_16x (baud_clk_16x) ,
+ .line_reset_n (line_reset_n),
// Line Interface
.rxd (rxd) ,
@@ -201,8 +237,9 @@
uart_msg_handler u_msg (
- .reset_n (arst_n ) ,
+ .reset_n (line_reset_n ) ,
.sys_clk (baud_clk_16x ) ,
+ .cfg_uart_enb (cfg_tx_enable_i),
// UART-TX Information
diff --git a/verilog/rtl/uart2wb/src/uart_auto_det.sv b/verilog/rtl/uart2wb/src/uart_auto_det.sv
new file mode 100644
index 0000000..1507c77
--- /dev/null
+++ b/verilog/rtl/uart2wb/src/uart_auto_det.sv
@@ -0,0 +1,163 @@
+/*********************************************************
+ This block try to auto detect the baud-16x value for incoming 9600 data.
+ Here the System clock is unknown, As in caravel user_clock can be any thing between
+ 4Mhz to 60Mhz.
+
+ local counter width: 20bit should be good enough the check idle OR struck at low state
+ Assumption is 9600 Baud => 0.104ms per bit => 1.04ms per chapter (Assumpting 10 bit per character including start+ parity bit)
+ With System clock 100Mhz, 1.04ms => 1,000,000 clock count, which can be easily check by 20 bit count => 2^20 = 1048576
+
+
+ 1.Input data in double sync with local clock
+ 2. State: IDLE: Wait for High to low edge,
+ On Fall edge, STATE = POS_EDGE
+ 2. State: POS_EDGE1:
+ Wait for Pos edge, If Pos edge detected, STATE= NEG_EDGE1
+ increase local clk_cnt, if counter each 0xF_FFFF without transition, move to State: IDLE
+ 3. State: NEG_EDGE1:
+ Wait for Neg edge, If Neg edge detected, capture the clk_cnt => ref1_cnt; State: POS_EDGE2
+ if counter reached 0xF_FFFF without transition, then STATE: IDLE
+
+ 4. State: POS_EDGE2:
+ Wait for Pos edge, If Pos edge detected, STATE= NEG_EDGE2
+ increase local clk_cnt, if counter each 0xF_FFFF without transition, move to State: IDLE
+ 5. State: NEG_EDGE2:
+ Wait for Neg edge, If Neg edge detected, capture the clk_cnt => ref2_cnt; State: COMPUTE
+ if counter reached 0xF_FFFF without transition, then STATE: IDLE
+ 6. State: COMPUTE
+ if difference between ref1_cnt and ref2_cnt less than 16, then average out and divide by 16, Sub by 2,
+ and update Baud Value and STOP_EDGE
+ 7. STATE:STOP_EDGE Wait pos edge, if timeout then go to IDLE, else enable tx/rx
+ ***************************************************************************/
+module uart_auto_det (
+ input logic mclk ,
+ input logic reset_n ,
+ input logic cfg_auto_det ,
+ input logic rxd ,
+
+ output logic [11:0] auto_baud_16x ,
+ output logic auto_tx_enb ,
+ output logic auto_rx_enb
+
+ );
+
+parameter IDLE = 3'b000;
+parameter POS_EDGE1 = 3'b001;
+parameter NEG_EDGE1 = 3'b010;
+parameter POS_EDGE2 = 3'b011;
+parameter NEG_EDGE2 = 3'b100;
+parameter COMPUTE = 3'b101;
+parameter STOP_EDGE = 3'b110;
+parameter AUTO_DONE = 3'b111;
+
+
+logic [19:0] clk_cnt,ref1_cnt,ref2_cnt,ref_diff,baud_16x;
+logic [2:0] state;
+logic [2:0] rxd_sync;
+logic timeout;
+logic rxd_pedge;
+logic rxd_nedge;
+
+assign timeout = (clk_cnt == 20'hF_FFFF);
+assign rxd_pedge = (rxd_sync[2] == 1'b0) & (rxd_sync[1] == 1'b1);
+assign rxd_nedge = (rxd_sync[2] == 1'b1) & (rxd_sync[1] == 1'b0);
+assign ref_diff = (ref1_cnt > ref2_cnt) ? (ref1_cnt - ref2_cnt) : (ref2_cnt - ref1_cnt);
+
+assign baud_16x = (((ref1_cnt + ref2_cnt) >> 1) >> 4);
+
+always @(negedge reset_n or posedge mclk)
+begin
+ if(reset_n == 1'b0) begin
+ state <= IDLE;
+ clk_cnt <= 'b0;
+ ref1_cnt <= 'b0;
+ ref1_cnt <= 'b0;
+ auto_baud_16x <= 'b0;
+ auto_tx_enb <= 'b0;
+ auto_rx_enb <= 'b0;
+ rxd_sync <= 'b0;
+ end else begin
+ rxd_sync <= {rxd_sync[1:0],rxd};
+ case(state)
+ IDLE : begin
+ if(cfg_auto_det && rxd_nedge) begin
+ clk_cnt <= 'h0;
+ state <= POS_EDGE1;
+ end
+ end
+ POS_EDGE1 : begin
+ if(rxd_pedge) begin
+ clk_cnt <= 'h0;
+ state <= NEG_EDGE1;
+ end else if(timeout) begin
+ state <= IDLE;
+ end else begin
+ clk_cnt <= clk_cnt + 1;
+ end
+ end
+ NEG_EDGE1 : begin
+ if(rxd_nedge) begin
+ ref1_cnt <= clk_cnt;
+ clk_cnt <= 'h0;
+ state <= POS_EDGE2;
+ end else if(timeout) begin
+ state <= IDLE;
+ end else begin
+ clk_cnt <= clk_cnt + 1;
+ end
+ end
+ POS_EDGE2 : begin
+ if(rxd_pedge) begin
+ clk_cnt <= 'h0;
+ state <= NEG_EDGE2;
+ end else if(timeout) begin
+ state <= IDLE;
+ end else begin
+ clk_cnt <= clk_cnt + 1;
+ end
+ end
+ NEG_EDGE2 : begin
+ if(rxd_nedge) begin
+ ref2_cnt <= clk_cnt;
+ clk_cnt <= 'h0;
+ state <= COMPUTE;
+ end else if(timeout) begin
+ state <= IDLE;
+ end else begin
+ clk_cnt <= clk_cnt + 1;
+ end
+ end
+ COMPUTE: begin
+ if(ref_diff < 16) begin
+ // Average it, Generate Div-16 + Additional Sub by 2 is due to clk_ctl module div n implementation
+ if(baud_16x > 1)
+ auto_baud_16x <= baud_16x -1;
+ else
+ auto_baud_16x <= 0;
+ state <= STOP_EDGE;
+ end else begin
+ state <= IDLE;
+ end
+ end
+ STOP_EDGE : begin
+ if(rxd_pedge) begin
+ state <= AUTO_DONE;
+ end else if(timeout) begin
+ state <= IDLE;
+ end else begin
+ clk_cnt <= clk_cnt + 1;
+ end
+ end
+ AUTO_DONE: begin
+ auto_tx_enb <= 1'b1;
+ auto_rx_enb <= 1'b1;
+ end
+ endcase
+
+ end
+end
+
+
+endmodule
+
+
diff --git a/verilog/rtl/user_params.svh b/verilog/rtl/user_params.svh
index a8b8341..1c03f17 100644
--- a/verilog/rtl/user_params.svh
+++ b/verilog/rtl/user_params.svh
@@ -4,9 +4,9 @@
// ASCI Representation of RISC = 32'h8273_8343
parameter CHIP_SIGNATURE = 32'h8273_8343;
// Software Reg-1, Release date: <DAY><MONTH><YEAR>
-parameter CHIP_RELEASE_DATE = 32'h0709_2022;
+parameter CHIP_RELEASE_DATE = 32'h1409_2022;
// Software Reg-2: Poject Revison 5.1 = 0005200
-parameter CHIP_REVISION = 32'h0005_4000;
+parameter CHIP_REVISION = 32'h0005_5000;
parameter SKEW_RESET_VAL = 32'b0000_0000_1000_0111_1001_1000_1001_1000;
@@ -48,9 +48,9 @@
2'b10 - Default value + 4
2'b11 - Default value - 4
bit [4:13] - uart master config control
- 2'b00 - constant value based on system clock-50Mhz (Default)
- 2'b01 - constant value based on system clock-40Mhz
- 2'b10 - constant value based on system clock-60Mhz (USB Ref Clock)
+ 2'b00 - Auto Detect (Default)
+ 2'b01 - constant value based on system clock-50Mhz
+ 2'b10 - constant value based on system clock-4Mhz
2'b11 - load from LA
bit[15] - Strap Mode
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
index e35f5cb..d56b92a 100644
--- a/verilog/rtl/wb_host/src/wb_host.sv
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -272,9 +272,9 @@
// it has additional 1 cycle additional count,
// so we are subtracting desired count by 2
// strap_uartm
-// 2'b00 - 50Mhz - 324
-// 2'b01 - 40Mhz - 258
-// 2'b10 - 60Mhz - 389
+// 2'b00 - Auto Baud Detect
+// 2'b01 - 50Mhz - 324
+// 2'b10 - 4Mhz - 24
// 2'b11 - Load from LA
//-------------------------------------------------
@@ -284,9 +284,12 @@
wire cfg_uartm_stop_bit = (strap_uartm==2'b11) ? la_data_in[3] : 1'b1;
wire [1:0] cfg_uartm_cfg_pri_mod = (strap_uartm==2'b11) ? la_data_in[17:16] : 2'b0;
-wire [11:0]cfg_uart_baud_16x = (strap_uartm==2'b00) ? 324:
- (strap_uartm==2'b01) ? 258:
- (strap_uartm==2'b10) ? 389: la_data_in[15:4];
+wire [11:0]cfg_uart_baud_16x = (strap_uartm==2'b00) ? 'h0:
+ (strap_uartm==2'b01) ? 324:
+ (strap_uartm==2'b10) ? 24: la_data_in[15:4];
+
+wire cfg_uartm_aut_det = (strap_uartm==2'b00) ? 1'b1: 1'b0;
+
// UART Master
@@ -295,6 +298,7 @@
.app_clk (wbm_clk_i ), // sys clock
// configuration control
+ .cfg_auto_det (cfg_uartm_aut_det ), // Auto Baud Value detect
.cfg_tx_enable (cfg_uartm_tx_enable ), // Enable Transmit Path
.cfg_rx_enable (cfg_uartm_rx_enable ), // Enable Received Path
.cfg_stop_bit (cfg_uartm_stop_bit ), // 0 -> 1 Start , 1 -> 2 Stop Bits
diff --git a/verilog/rtl/ws281x/src/ws281x_reg.sv b/verilog/rtl/ws281x/src/ws281x_reg.sv
index 31f25c1..741ece1 100644
--- a/verilog/rtl/ws281x/src/ws281x_reg.sv
+++ b/verilog/rtl/ws281x/src/ws281x_reg.sv
@@ -128,12 +128,10 @@
wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4) & !fifo_full[0]; // Write only if fifo is not full
wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5) & !fifo_full[1]; // Write only if fifo is not full
-wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6) & !fifo_full[2]; // Write only if fifo is not full
-wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7) & !fifo_full[3]; // Write only if fifo is not full
// Generated seperate write enable case to block the reg ack duration when fifo is full
-wire sw_wr_en_t = sw_wr_en_0 | sw_wr_en_1 | sw_wr_en_2 | sw_wr_en_3 | sw_wr_en_4 | sw_wr_en_5 | sw_wr_en_6 | sw_wr_en_7;
+wire sw_wr_en_t = sw_wr_en_0 | sw_wr_en_1 | sw_wr_en_2 | sw_wr_en_3 | sw_wr_en_4 | sw_wr_en_5 ;
always @ (posedge mclk or negedge h_reset_n)
diff --git a/verilog/rtl/ws281x/src/ws281x_top.sv b/verilog/rtl/ws281x/src/ws281x_top.sv
index 6ab06fa..138414b 100644
--- a/verilog/rtl/ws281x/src/ws281x_top.sv
+++ b/verilog/rtl/ws281x/src/ws281x_top.sv
@@ -64,7 +64,13 @@
logic [9:0] cfg_th0_period ; // bit-0 drive low period
logic [9:0] cfg_th1_period ; // bit-1 drive low period
+logic port0_enb ;
+logic port0_rd ;
+logic port0_dval ;
logic [23:0] port0_data ;
+logic port1_enb ;
+logic port1_rd ;
+logic port1_dval ;
logic [23:0] port1_data ;
//logic [23:0] port2_data ;
//logic [23:0] port3_data ;