nec ir tx/rx and ws281x pinmux io direction bug fix
diff --git a/openlane/aes_top/base.sdc b/openlane/aes_top/base.sdc
new file mode 100644
index 0000000..f81deda
--- /dev/null
+++ b/openlane/aes_top/base.sdc
@@ -0,0 +1,276 @@
+###############################################################################
+# Created by write_sdc
+# Mon Nov  7 16:29:34 2022
+###############################################################################
+current_design aes_top
+###############################################################################
+# Timing Constraints
+###############################################################################
+create_clock -name mclk -period 10.0000 [get_ports {mclk}]
+set_clock_transition 0.1500 [get_clocks {mclk}]
+set_clock_uncertainty 0.2500 mclk
+set_propagated_clock [get_clocks {mclk}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {cfg_cska[0]}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {cfg_cska[1]}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {cfg_cska[2]}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {cfg_cska[3]}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {rst_n}]
+set_input_delay -max 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_clk_int}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {wbd_clk_out}]
+
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[1]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[2]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[3]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[4]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[5]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[6]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_cmd}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_req}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[10]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[11]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[12]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[13]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[14]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[15]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[16]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[17]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[18]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[19]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[1]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[20]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[21]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[22]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[23]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[24]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[25]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[26]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[27]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[28]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[29]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[2]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[30]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[31]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[3]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[4]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[5]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[6]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[7]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[8]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[9]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_width[0]}]
+set_input_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_width[1]}]
+
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_addr[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_cmd}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_req}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[10]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[11]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[12]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[13]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[14]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[15]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[16]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[17]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[18]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[19]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[1]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[20]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[21]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[22]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[23]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[24]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[25]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[26]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[27]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[28]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[29]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[2]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[30]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[31]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[3]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[4]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[5]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[6]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[7]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[8]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_wdata[9]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_width[0]}]
+set_input_delay -min 1.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_width[1]}]
+
+
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[0]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[10]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[11]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[12]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[13]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[14]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[15]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[16]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[17]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[18]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[19]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[1]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[20]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[21]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[22]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[23]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[24]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[25]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[26]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[27]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[28]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[29]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[2]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[30]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[31]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[3]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[4]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[5]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[6]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[7]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[8]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[9]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_req_ack}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_resp[0]}]
+set_output_delay -max 6.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_resp[1]}]
+
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[0]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[10]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[11]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[12]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[13]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[14]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[15]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[16]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[17]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[18]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[19]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[1]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[20]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[21]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[22]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[23]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[24]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[25]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[26]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[27]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[28]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[29]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[2]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[30]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[31]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[3]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[4]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[5]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[6]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[7]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[8]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_rdata[9]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_req_ack}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_resp[0]}]
+set_output_delay -min 2.0000 -clock [get_clocks {mclk}] -add_delay [get_ports {dmem_resp[1]}]
+
+###############################################################################
+# Environment
+###############################################################################
+set_load -pin_load 0.0334 [get_ports {dmem_req_ack}]
+set_load -pin_load 0.0334 [get_ports {wbd_clk_out}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[31]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[30]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[29]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[28]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[27]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[26]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[25]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[24]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[23]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[22]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[21]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[20]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[19]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[18]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[17]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[16]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[15]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[14]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[13]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[12]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[11]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[10]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[9]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[8]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[7]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[6]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[5]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[4]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[3]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[2]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[1]}]
+set_load -pin_load 0.0334 [get_ports {dmem_rdata[0]}]
+set_load -pin_load 0.0334 [get_ports {dmem_resp[1]}]
+set_load -pin_load 0.0334 [get_ports {dmem_resp[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_cmd}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_req}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {mclk}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {rst_n}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {wbd_clk_int}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {cfg_cska[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {cfg_cska[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {cfg_cska[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {cfg_cska[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_addr[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[31]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[30]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[29]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[28]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[27]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[26]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[25]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[24]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[23]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[22]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[21]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[20]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[19]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[18]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[17]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[16]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[15]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[14]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[13]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[12]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[11]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[10]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[9]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[8]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[7]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[6]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[5]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[4]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[3]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[2]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_wdata[0]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_width[1]}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_2 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {dmem_width[0]}]
+set_timing_derate -early 0.9500
+set_timing_derate -late 1.0500
+###############################################################################
+# Design Rules
+###############################################################################
+set_max_fanout 4.0000 [current_design]
diff --git a/openlane/aes_top/config.tcl b/openlane/aes_top/config.tcl
new file mode 100755
index 0000000..2d07219
--- /dev/null
+++ b/openlane/aes_top/config.tcl
@@ -0,0 +1,125 @@
+# 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>
+
+# Global
+# ------
+
+set script_dir [file dirname [file normalize [info script]]]
+# Name
+
+set ::env(DESIGN_NAME) aes_top
+
+set ::env(DESIGN_IS_CORE) "0"
+set ::env(FP_PDN_CORE_RING) "0"
+
+# Timing configuration
+set ::env(CLOCK_PERIOD) "10"
+set ::env(CLOCK_PORT) "mclk"
+
+set ::env(SYNTH_MAX_FANOUT) 4
+
+## CTS BUFFER
+set ::env(CTS_CLK_BUFFER_LIST) "sky130_fd_sc_hd__clkbuf_4 sky130_fd_sc_hd__clkbuf_8"
+set ::env(CTS_SINK_CLUSTERING_SIZE) "16"
+set ::env(CLOCK_BUFFER_FANOUT) "8"
+
+# Sources
+# -------
+
+# Local sources + no2usb sources
+set ::env(VERILOG_FILES) "\
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_cipher_top.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_inv_cipher_top.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_inv_sbox.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_key_expand_128.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_rcon.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/core/aes_sbox.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/top/aes_top.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/security_core/verilog/rtl/aes128/top/aes_reg.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/lib/registers.v \
+        $::env(DESIGN_DIR)/../../verilog/rtl/lib/reset_sync.sv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/lib/clk_skew_adjust.gv \
+        $::env(DESIGN_DIR)/../../verilog/rtl/lib/ctech_cells.sv \
+	"
+
+set ::env(SYNTH_DEFINES) [list SYNTHESIS ]
+set ::env(SYNTH_READ_BLACKBOX_LIB) 1
+set ::env(SDC_FILE) $::env(DESIGN_DIR)/base.sdc
+set ::env(BASE_SDC_FILE) $::env(DESIGN_DIR)/base.sdc
+
+set ::env(LEC_ENABLE) 0
+
+set ::env(VDD_PIN) [list {vccd1}]
+set ::env(GND_PIN) [list {vssd1}]
+
+
+# Floorplanning
+# -------------
+
+set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+
+set ::env(FP_SIZING) absolute
+set ::env(DIE_AREA) "0 0 850 650"
+
+set ::env(GRT_ADJUSTMENT) 0.2
+
+
+set ::env(PL_TIME_DRIVEN) 1
+set ::env(PL_TARGET_DENSITY) "0.42"
+
+# If you're going to use multiple power domains, then keep this disabled.
+set ::env(RUN_CVC) 0
+
+
+
+# helps in anteena fix
+set ::env(USE_ARC_ANTENNA_CHECK) "0"
+
+#set ::env(FP_IO_VEXTEND) 4
+#set ::env(FP_IO_HEXTEND) 4
+
+set ::env(FP_PDN_VPITCH) 100
+set ::env(FP_PDN_HPITCH) 100
+set ::env(FP_PDN_VWIDTH) 6.2
+set ::env(FP_PDN_HWIDTH) 6.2
+
+#set ::env(GLB_RT_MAXLAYER) 5
+set ::env(RT_MAX_LAYER) {met4}
+
+#Lef 
+set ::env(MAGIC_GENERATE_LEF) {1}
+set ::env(MAGIC_WRITE_FULL_LEF) {0}
+
+#set ::env(GLB_RT_MAX_DIODE_INS_ITERS) 10
+set ::env(DIODE_INSERTION_STRATEGY) 4
+
+
+#LVS Issue - DEF Base looks to having issue
+set ::env(MAGIC_EXT_USE_GDS) {1}
+
+set ::env(GLB_RESIZER_MAX_SLEW_MARGIN) {1.5}
+set ::env(PL_RESIZER_MAX_SLEW_MARGIN) {1.5}
+
+set ::env(GLB_RESIZER_MAX_CAP_MARGIN) {0.25}
+set ::env(PL_RESIZER_MAX_CAP_MARGIN) {0.25}
+
+set ::env(GLB_RESIZER_MAX_WIRE_LENGTH) {500}
+set ::env(PL_RESIZER_MAX_WIRE_LENGTH) {500}
+
+set ::env(QUIT_ON_TIMING_VIOLATIONS) "0"
+set ::env(QUIT_ON_MAGIC_DRC) "1"
+set ::env(QUIT_ON_LVS_ERROR) "1"
+set ::env(QUIT_ON_SLEW_VIOLATIONS) "0"
diff --git a/openlane/aes_top/pin_order.cfg b/openlane/aes_top/pin_order.cfg
new file mode 100644
index 0000000..d3bacc9
--- /dev/null
+++ b/openlane/aes_top/pin_order.cfg
@@ -0,0 +1,93 @@
+#BUS_SORT
+
+#MANUAL_PLACE
+
+
+#S
+rst_n          550 0 2
+mclk               
+wbd_clk_out
+cfg_cska\[3\]
+cfg_cska\[2\]
+cfg_cska\[1\]
+cfg_cska\[0\]
+
+wbd_clk_int     590 0 2
+dmem_req_ack    
+dmem_req         
+dmem_cmd  
+dmem_width\[1\]
+dmem_width\[0\]
+dmem_addr\[6\]     
+dmem_addr\[5\]     
+dmem_addr\[4\]     
+dmem_addr\[3\]     
+dmem_addr\[2\]     
+dmem_addr\[1\]     
+dmem_addr\[0\]   
+dmem_wdata\[31\]
+dmem_wdata\[30\]
+dmem_wdata\[29\]
+dmem_wdata\[28\]
+dmem_wdata\[27\]
+dmem_wdata\[26\]
+dmem_wdata\[25\]
+dmem_wdata\[24\]
+dmem_wdata\[23\]
+dmem_wdata\[22\]
+dmem_wdata\[21\]
+dmem_wdata\[20\]
+dmem_wdata\[19\]
+dmem_wdata\[18\]
+dmem_wdata\[17\]
+dmem_wdata\[16\]
+dmem_wdata\[15\]
+dmem_wdata\[14\]
+dmem_wdata\[13\]
+dmem_wdata\[12\]
+dmem_wdata\[11\]
+dmem_wdata\[10\]
+dmem_wdata\[9\]
+dmem_wdata\[8\]
+dmem_wdata\[7\]
+dmem_wdata\[6\]
+dmem_wdata\[5\]
+dmem_wdata\[4\]
+dmem_wdata\[3\]
+dmem_wdata\[2\]
+dmem_wdata\[1\]
+dmem_wdata\[0\]
+dmem_rdata\[31\]
+dmem_rdata\[30\]
+dmem_rdata\[29\]
+dmem_rdata\[28\]
+dmem_rdata\[27\]
+dmem_rdata\[26\]
+dmem_rdata\[25\]
+dmem_rdata\[24\]
+dmem_rdata\[23\]
+dmem_rdata\[22\]
+dmem_rdata\[21\]
+dmem_rdata\[20\]
+dmem_rdata\[19\]
+dmem_rdata\[18\]
+dmem_rdata\[17\]
+dmem_rdata\[16\]
+dmem_rdata\[15\]
+dmem_rdata\[14\]
+dmem_rdata\[13\]
+dmem_rdata\[12\]
+dmem_rdata\[11\]
+dmem_rdata\[10\]
+dmem_rdata\[9\]
+dmem_rdata\[8\]
+dmem_rdata\[7\]
+dmem_rdata\[6\]
+dmem_rdata\[5\]
+dmem_rdata\[4\]
+dmem_rdata\[3\]
+dmem_rdata\[2\]
+dmem_rdata\[1\]
+dmem_rdata\[0\]
+dmem_resp\[1\]
+dmem_resp\[0\]
diff --git a/openlane/peri_top/config.tcl b/openlane/peri_top/config.tcl
index 0b3f35f..9ba7843 100755
--- a/openlane/peri_top/config.tcl
+++ b/openlane/peri_top/config.tcl
@@ -52,6 +52,17 @@
      $::env(DESIGN_DIR)/../../verilog/rtl/lib/reset_sync.sv     \
      $::env(DESIGN_DIR)/../../verilog/rtl/lib/async_reg_bus.sv \
      $::env(DESIGN_DIR)/../../verilog/rtl/lib/registers.v \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_rx.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_frame_decoder.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_event_catcher.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_regs.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_div8.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_tx.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/nec_ir/src/nec_ir_top.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/lib/sync_fifo_occ.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/lib/prescaler.v \
+     $::env(DESIGN_DIR)/../../verilog/rtl/lib/metastability_filter.sv \
+     $::env(DESIGN_DIR)/../../verilog/rtl/lib/pulse_filter.sv \
      "
 
 set ::env(VERILOG_INCLUDE_DIRS) [glob $::env(DESIGN_DIR)/../../verilog/rtl/ ]
@@ -71,9 +82,10 @@
 # -------------
 
 set ::env(FP_PIN_ORDER_CFG) $::env(DESIGN_DIR)/pin_order.cfg
+#set ::env(MACRO_PLACEMENT_CFG) $::env(DESIGN_DIR)/macro.cfg
 
 set ::env(FP_SIZING) absolute
-set ::env(DIE_AREA) "0 0 400 200"
+set ::env(DIE_AREA) "0 0 400 400"
 
 
 # If you're going to use multiple power domains, then keep this disabled.
@@ -83,7 +95,7 @@
 
 
 set ::env(PL_TIME_DRIVEN) 1
-set ::env(PL_TARGET_DENSITY) "0.35"
+set ::env(PL_TARGET_DENSITY) "0.42"
 set ::env(CELL_PAD) "8"
 #set ::env(GRT_ADJUSTMENT) {0.2}
 
@@ -119,6 +131,8 @@
 
 set ::env(DIODE_INSERTION_STRATEGY) 4
 
+set ::env(PL_RESIZER_BUFFER_INPUT_PORTS) {0}
+set ::env(PL_RESIZER_BUFFER_OUTPUT_PORTS) {1}
 
 #LVS Issue - DEF Base looks to having issue
 set ::env(MAGIC_EXT_USE_GDS) {1}
diff --git a/openlane/peri_top/pin_order.cfg b/openlane/peri_top/pin_order.cfg
index 2f23b77..59c656b 100644
--- a/openlane/peri_top/pin_order.cfg
+++ b/openlane/peri_top/pin_order.cfg
@@ -53,6 +53,9 @@
 rtc_intr
 inc_date_d
 inc_time_s
+ir_rx
+ir_tx
+ir_intr
 
 
 reg_cs            250 0  2
diff --git a/openlane/pinmux_top/config.tcl b/openlane/pinmux_top/config.tcl
index b52bc4e..a60c4f4 100755
--- a/openlane/pinmux_top/config.tcl
+++ b/openlane/pinmux_top/config.tcl
@@ -46,6 +46,7 @@
      $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pinmux_top.sv     \
      $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pinmux.sv     \
      $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/glbl_reg.sv  \
+     $::env(DESIGN_DIR)/../../verilog/rtl/pinmux/src/pseudorandom.sv \
      $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_top.sv  \
      $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_reg.sv  \
      $::env(DESIGN_DIR)/../../verilog/rtl/gpio/src/gpio_intr.sv \
diff --git a/openlane/pinmux_top/pin_order.cfg b/openlane/pinmux_top/pin_order.cfg
index bcdbeb5..f7ea26f 100644
--- a/openlane/pinmux_top/pin_order.cfg
+++ b/openlane/pinmux_top/pin_order.cfg
@@ -353,6 +353,9 @@
 
 rtc_clk               150 0 2
 rtc_intr              
+ir_rx
+ir_tx
+ir_intr
 
 reg_peri_cs            200 0  2
 reg_peri_wr           
diff --git a/openlane/user_project_wrapper/interactive.tcl b/openlane/user_project_wrapper/interactive.tcl
index c464041..1f6639d 100755
--- a/openlane/user_project_wrapper/interactive.tcl
+++ b/openlane/user_project_wrapper/interactive.tcl
@@ -258,7 +258,7 @@
     set steps [dict create \
         "synthesis" "run_synthesis" \
         "floorplan" "run_floorplan" \
-        "placement" "run_placement_step"\
+        "placement" "run_placement_step" \
         "cts" "run_cts_step" \
         "routing" "run_routing_step" \
         "parasitics_sta" "run_parasitics_sta_step" \
diff --git a/openlane/wb_interconnect/interactive.tcl b/openlane/wb_interconnect/interactive.tcl
new file mode 100755
index 0000000..a96ddb6
--- /dev/null
+++ b/openlane/wb_interconnect/interactive.tcl
@@ -0,0 +1,355 @@
+#!/usr/bin/env tclsh
+# Copyright 2020-2022 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.
+package require openlane; # provides the utils as well
+
+proc run_placement_step {args} {
+    if { ! [ info exists ::env(PLACEMENT_CURRENT_DEF) ] } {
+        set ::env(PLACEMENT_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PLACEMENT_CURRENT_DEF)
+    }
+
+    run_placement
+}
+
+proc run_cts_step {args} {
+    if { ! [ info exists ::env(CTS_CURRENT_DEF) ] } {
+        set ::env(CTS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(CTS_CURRENT_DEF)
+    }
+
+    run_cts
+    run_resizer_timing
+}
+
+proc run_routing_step {args} {
+    if { ! [ info exists ::env(ROUTING_CURRENT_DEF) ] } {
+        set ::env(ROUTING_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ROUTING_CURRENT_DEF)
+    }
+    if { $::env(ECO_ENABLE) == 0 } {
+        run_routing
+    }
+}
+
+proc run_parasitics_sta_step {args} {
+    if { ! [ info exists ::env(PARSITICS_CURRENT_DEF) ] } {
+        set ::env(PARSITICS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(PARSITICS_CURRENT_DEF)
+    }
+
+    if { $::env(RUN_SPEF_EXTRACTION) && ($::env(ECO_ENABLE) == 0)} {
+        run_parasitics_sta
+    }
+}
+
+proc run_diode_insertion_2_5_step {args} {
+    if { ! [ info exists ::env(DIODE_INSERTION_CURRENT_DEF) ] } {
+        set ::env(DIODE_INSERTION_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DIODE_INSERTION_CURRENT_DEF)
+    }
+    if { ($::env(DIODE_INSERTION_STRATEGY) == 2) || ($::env(DIODE_INSERTION_STRATEGY) == 5) } {
+        run_antenna_check
+        heal_antenna_violators; # modifies the routed DEF
+    }
+
+}
+
+proc run_irdrop_report_step {args} {
+    if { $::env(RUN_IRDROP_REPORT) } {
+        run_irdrop_report
+    }
+}
+
+proc run_lvs_step {{ lvs_enabled 1 }} {
+    if { ! [ info exists ::env(LVS_CURRENT_DEF) ] } {
+        set ::env(LVS_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(LVS_CURRENT_DEF)
+    }
+
+    if { $lvs_enabled && $::env(RUN_LVS) } {
+        run_magic_spice_export;
+        run_lvs; # requires run_magic_spice_export
+    }
+
+}
+
+proc run_drc_step {{ drc_enabled 1 }} {
+    if { ! [ info exists ::env(DRC_CURRENT_DEF) ] } {
+        set ::env(DRC_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(DRC_CURRENT_DEF)
+    }
+    if { $drc_enabled } {
+        if { $::env(RUN_MAGIC_DRC) } {
+            run_magic_drc
+        }
+        if {$::env(RUN_KLAYOUT_DRC)} {
+            run_klayout_drc
+        }
+    }
+}
+
+proc run_antenna_check_step {{ antenna_check_enabled 1 }} {
+    if { ! [ info exists ::env(ANTENNA_CHECK_CURRENT_DEF) ] } {
+        set ::env(ANTENNA_CHECK_CURRENT_DEF) $::env(CURRENT_DEF)
+    } else {
+        set ::env(CURRENT_DEF) $::env(ANTENNA_CHECK_CURRENT_DEF)
+    }
+    if { $antenna_check_enabled } {
+        run_antenna_check
+    }
+}
+
+proc run_eco_step {args} {
+    if { $::env(ECO_ENABLE) == 1 } {
+        run_eco_flow
+    }
+}
+
+proc run_magic_step {args} {
+    if {$::env(RUN_MAGIC)} {
+        run_magic
+    }
+}
+
+proc run_klayout_step {args} {
+    if {$::env(RUN_KLAYOUT)} {
+        run_klayout
+    }
+    if {$::env(RUN_KLAYOUT_XOR)} {
+        run_klayout_gds_xor
+    }
+}
+
+proc run_post_run_hooks {} {
+    if { [file exists $::env(DESIGN_DIR)/hooks/post_run.py]} {
+        puts_info "Running post run hook"
+        set result [exec $::env(OPENROAD_BIN) -python $::env(DESIGN_DIR)/hooks/post_run.py]
+        puts_info "$result"
+    } else {
+        puts_info "hooks/post_run.py not found, skipping"
+    }
+}
+
+proc run_magic_drc_batch {args} {
+    set options {
+        {-magicrc optional}
+        {-tech optional}
+        {-report required}
+        {-design required}
+        {-gds required}
+    }
+    set flags {}
+    parse_key_args "run_magic_drc_batch" args arg_values $options flags_mag $flags
+    if { [info exists arg_values(-magicrc)] } {
+        set magicrc [file normalize $arg_values(-magicrc)]
+    }
+    if { [info exists arg_values(-tech)] } {
+        set ::env(TECH) [file normalize $arg_values(-tech)]
+    }
+    set ::env(GDS_INPUT) [file normalize $arg_values(-gds)]
+    set ::env(REPORT_OUTPUT) [file normalize $arg_values(-report)]
+    set ::env(DESIGN_NAME) $arg_values(-design)
+
+    if { [info exists magicrc] } {
+        exec magic \
+            -noconsole \
+            -dnull \
+            -rcfile $magicrc \
+            $::env(OPENLANE_ROOT)/scripts/magic/drc_batch.tcl \
+            </dev/null |& tee /dev/tty
+    } else {
+        exec magic \
+            -noconsole \
+            -dnull \
+            $::env(OPENLANE_ROOT)/scripts/magic/drc_batch.tcl \
+            </dev/null |& tee /dev/tty
+    }
+}
+
+proc run_lvs_batch {args} {
+    # runs device level lvs on -gds/CURRENT_GDS and -net/CURRENT_NETLIST
+    # extracts gds only if EXT_NETLIST does not exist
+    set options {
+        {-design required}
+        {-gds optional}
+        {-net optional}
+    }
+    set flags {}
+    parse_key_args "run_lvs_batch" args arg_values $options flags_lvs $flags -no_consume
+
+    prep {*}$args
+
+    if { [info exists arg_values(-gds)] } {
+        set ::env(CURRENT_GDS) [file normalize $arg_values(-gds)]
+    } else {
+        set ::env(CURRENT_GDS) $::env(signoff_results)/$::env(DESIGN_NAME).gds
+    }
+    if { [info exists arg_values(-net)] } {
+        set ::env(CURRENT_NETLIST) [file normalize $arg_values(-net)]
+    }
+
+    assert_files_exist "$::env(CURRENT_GDS) $::env(CURRENT_NETLIST)"
+
+    set ::env(MAGIC_EXT_USE_GDS) 1
+    set ::env(EXT_NETLIST) $::env(signoff_results)/$::env(DESIGN_NAME).gds.spice
+    if { [file exists $::env(EXT_NETLIST)] } {
+        puts_warn "The file $::env(EXT_NETLIST) will be used. If you would like the file re-exported, please delete it."
+    } else {
+        run_magic_spice_export
+    }
+
+    run_lvs
+}
+
+
+proc run_file {args} {
+    set ::env(TCLLIBPATH) $::auto_path
+    exec tclsh {*}$args >&@stdout
+}
+
+
+
+proc run_flow {args} {
+    set options {
+        {-design optional}
+        {-from optional}
+        {-to optional}
+        {-save_path optional}
+        {-override_env optional}
+    }
+    set flags {-save -run_hooks -no_lvs -no_drc -no_antennacheck -gui}
+    parse_key_args "run_non_interactive_mode" args arg_values $options flags_map $flags -no_consume
+
+    prep {*}$args
+    # signal trap SIGINT save_state;
+
+    if { [info exists flags_map(-gui)] } {
+        or_gui
+        return
+    }
+    if { [info exists arg_values(-override_env)] } {
+        load_overrides $arg_values(-override_env)
+    }
+
+    set LVS_ENABLED 1
+    set DRC_ENABLED 1
+
+    set ANTENNACHECK_ENABLED [expr ![info exists flags_map(-no_antennacheck)] ]
+
+    set steps [dict create \
+        "synthesis" "run_synthesis" \
+        "floorplan" "run_floorplan" \
+        "placement" "run_placement_step" \
+        "cts" "run_cts_step" \
+        "routing" "run_routing_step" \
+        "parasitics_sta" "run_parasitics_sta_step" \
+        "eco" "run_eco_step" \
+        "diode_insertion" "run_diode_insertion_2_5_step" \
+        "irdrop" "run_irdrop_report_step" \
+        "gds_magic" "run_magic_step" \
+        "gds_klayout" "run_klayout_step" \
+        "lvs" "run_lvs_step $LVS_ENABLED " \
+        "drc" "run_drc_step $DRC_ENABLED " \
+        "antenna_check" "run_antenna_check_step $ANTENNACHECK_ENABLED " \
+        "cvc" "run_lef_cvc"
+    ]
+
+    if { [info exists arg_values(-from) ]} {
+        puts_info "Starting flow at $arg_values(-from)..."
+        set ::env(CURRENT_STEP) $arg_values(-from)
+    } elseif {  [info exists ::env(CURRENT_STEP) ] } {
+        puts_info "Resuming flow from $::env(CURRENT_STEP)..."
+    } else {
+        set ::env(CURRENT_STEP) "synthesis"
+    }
+    #Dinesh-A: Addition for LAST_STEP
+    if { [info exists arg_values(-to) ]} {
+        puts_info "Last flow Will be at $arg_values(-to)..."
+        set ::env(LAST_STEP) $arg_values(-to)
+    } elseif {  [info exists ::env(LAST_STEP) ] } {
+        puts_info "Last flow Will be at $::env(LAST_STEP)..."
+    } else {
+        set ::env(LAST_STEP) "cvc"
+    }
+
+    set_if_unset arg_values(-from) $::env(CURRENT_STEP)
+    set_if_unset arg_values(-to)   $::env(LAST_STEP)
+
+    set exe 0;
+    dict for {step_name step_exe} $steps {
+        if { [ string equal $arg_values(-from) $step_name ] } {
+            set exe 1;
+        }
+
+        if { $exe } {
+            # For when it fails
+            set ::env(CURRENT_STEP) $step_name
+            [lindex $step_exe 0] [lindex $step_exe 1] ;
+        }
+
+        if { [ string equal $arg_values(-to) $step_name ] } {
+            set exe 0:
+            break;
+        }
+
+    }
+
+    # for when it resumes
+    set steps_as_list [dict keys $steps]
+    set next_idx [expr [lsearch $steps_as_list $::env(CURRENT_STEP)] + 1]
+    set ::env(CURRENT_STEP) [lindex $steps_as_list $next_idx]
+
+    # Saves to <RUN_DIR>/results/final
+    save_final_views
+
+    # Saves to design directory or custom
+    if {  [info exists flags_map(-save) ] } {
+        if { ! [info exists arg_values(-save_path)] } {
+            set arg_values(-save_path) $::env(DESIGN_DIR)
+        }
+        save_final_views\
+            -save_path $arg_values(-save_path)\
+            -tag $::env(RUN_TAG)
+    }
+    calc_total_runtime
+    save_state
+    generate_final_summary_report
+
+    check_timing_violations
+
+    if { [info exists arg_values(-save_path)]\
+        && $arg_values(-save_path) != "" } {
+        set ::env(HOOK_OUTPUT_PATH) "[file normalize $arg_values(-save_path)]"
+    } else {
+        set ::env(HOOK_OUTPUT_PATH) $::env(RESULTS_DIR)/final
+    }
+
+    if {[info exists flags_map(-run_hooks)]} {
+        run_post_run_hooks
+    }
+
+    puts_success "Flow complete."
+
+    show_warnings "Note that the following warnings have been generated:"
+}
+
+run_flow {*}$argv
diff --git a/sdc/caravel.sdc b/sdc/caravel.sdc
index 9ddeee6..c5eec94 100644
--- a/sdc/caravel.sdc
+++ b/sdc/caravel.sdc
@@ -17,7 +17,7 @@
 create_clock -name int_pll_clock -period 5.0000  [get_pins {mprj/u_pinmux/int_pll_clock}]
 
 create_clock -name wbs_ref_clk -period 5.0000   [get_pins {mprj/u_wb_host/u_reg.u_wbs_ref_clkbuf.u_buf/X}]
-create_clock -name wbs_clk_i   -period 26.0000  [get_pins {mprj/u_wb_host/wbs_clk_out}]
+create_clock -name wbs_clk_i   -period 30.0000  [get_pins {mprj/u_wb_host/wbs_clk_out}]
 
 create_clock -name cpu_ref_clk -period 5.0000   [get_pins {mprj/u_wb_host/u_reg.u_cpu_ref_clkbuf.u_buf/X}]
 create_clock -name cpu_clk     -period 40.0000  [get_pins {mprj/u_wb_host/cpu_clk}]
diff --git a/sdc/peri_top.sdc b/sdc/peri_top.sdc
index 9c549e3..1bd167c 100644
--- a/sdc/peri_top.sdc
+++ b/sdc/peri_top.sdc
@@ -1,6 +1,6 @@
 ###############################################################################
 # Created by write_sdc
-# Sat Dec 10 10:44:09 2022
+# Tue Dec 13 05:43:33 2022
 ###############################################################################
 current_design peri_top
 ###############################################################################
diff --git a/sdc/pinmux_top.sdc b/sdc/pinmux_top.sdc
index 4d80b95..b5428aa 100644
--- a/sdc/pinmux_top.sdc
+++ b/sdc/pinmux_top.sdc
@@ -1,6 +1,6 @@
 ###############################################################################
 # Created by write_sdc
-# Sat Dec 10 06:19:01 2022
+# Tue Dec 13 05:44:43 2022
 ###############################################################################
 current_design pinmux_top
 ###############################################################################
@@ -235,6 +235,7 @@
 set_load -pin_load 0.0334 [get_ports {i2cm_clk_i}]
 set_load -pin_load 0.0334 [get_ports {i2cm_data_i}]
 set_load -pin_load 0.0334 [get_ports {i2cm_rst_n}]
+set_load -pin_load 0.0334 [get_ports {ir_rx}]
 set_load -pin_load 0.0334 [get_ports {pll_ref_clk}]
 set_load -pin_load 0.0334 [get_ports {pulse1m_mclk}]
 set_load -pin_load 0.0334 [get_ports {qspim_rst_n}]
@@ -579,6 +580,8 @@
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {i2cm_data_oen}]
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {i2cm_intr}]
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {int_pll_clock}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {ir_intr}]
+set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {ir_tx}]
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {mclk}]
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {p_reset_n}]
 set_driving_cell -lib_cell sky130_fd_sc_hd__inv_8 -pin {Y} -input_transition_rise 0.0000 -input_transition_fall 0.0000 [get_ports {reg_cs}]
diff --git a/sdc/user_project_wrapper.sdc b/sdc/user_project_wrapper.sdc
index b2b6e86..79e509a 100644
--- a/sdc/user_project_wrapper.sdc
+++ b/sdc/user_project_wrapper.sdc
@@ -1,6 +1,6 @@
 ###############################################################################
 # Created by write_sdc
-# Sat Dec 10 15:27:39 2022
+# Tue Dec 13 07:55:31 2022
 ###############################################################################
 current_design user_project_wrapper
 ###############################################################################
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
index 5441c46..e210734 100644
--- a/verilog/dv/Makefile
+++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@
 .SUFFIXES:
 .SILENT: clean all
 
-PATTERNS = user_uart user_uart1 user_risc_boot user_qspi user_sspi user_i2cm user_usb user_gpio user_basic user_spi_isp user_timer user_uart_master  user_sram_exec user_cache_bypass user_pwm user_sema risc_boot uart_master_test1 uart_master_test2 wb_port arduino_arrays arduino_digital_port_control arduino_i2c_scaner arduino_risc_boot arduino_timer_intr arduino_ascii_table arduino_gpio_intr arduino_i2c_wr_rd arduino_string arduino_ws281x arduino_character_analysis arduino_hello_world arduino_multi_serial arduino_switchCase2 user_mcore_test1 user_mcore_test2 user_aes_core user_fpu_core user_aes user_rtc
+PATTERNS = user_random user_uart user_uart1 user_risc_boot user_qspi user_sspi user_i2cm user_usb user_gpio user_basic user_spi_isp user_timer user_uart_master  user_sram_exec user_cache_bypass user_pwm user_sema risc_boot uart_master_test1 uart_master_test2 wb_port arduino_arrays arduino_digital_port_control arduino_i2c_scaner arduino_risc_boot arduino_timer_intr arduino_ascii_table arduino_gpio_intr arduino_i2c_wr_rd arduino_string arduino_ws281x arduino_character_analysis arduino_hello_world arduino_multi_serial arduino_switchCase2 user_aes_core user_fpu_core user_aes user_rtc user_ir_tx user_ir_rx user_mcore_test1 user_mcore_test2
 
 all:  ${PATTERNS}
 	echo "################# RTL Test case Summary #####################" > regression.rpt
diff --git a/verilog/dv/arduino_arrays/arduino_arrays_tb.v b/verilog/dv/arduino_arrays/arduino_arrays_tb.v
index f7f4808..a5bbcde 100644
--- a/verilog/dv/arduino_arrays/arduino_arrays_tb.v
+++ b/verilog/dv/arduino_arrays/arduino_arrays_tb.v
@@ -145,14 +145,14 @@
       *   Pin-13       7         PD7/A1N1                  digital_io[15]/analog_io[3]
       *   ********************************************************/
 
-     wire [7:0]  port_d_in = {  io_out[15],
-		                        io_out[14],
-		                        io_out[13],
-		                        io_out[10],
-			                    io_out[9],
-			                    io_out[8],
-		                        io_out[7],
-		                        io_out[6]
+     wire [7:0]  port_d_in = {  (io_oeb[15] == 1'b0)? io_out[15]: 1'b0 ,
+		                        (io_oeb[14] == 1'b0)? io_out[14]: 1'b0 ,
+		                        (io_oeb[13] == 1'b0)? io_out[13]: 1'b0 ,
+		                        (io_oeb[10] == 1'b0)? io_out[10]: 1'b0 ,
+			                    (io_oeb[9]  == 1'b0)? io_out[9] : 1'b0 ,
+			                    (io_oeb[8]  == 1'b0)? io_out[8] : 1'b0 ,
+		                        (io_oeb[7]  == 1'b0)? io_out[7] : 1'b0 ,
+		                        (io_oeb[6]  == 1'b0)? io_out[6] : 1'b0 
 			                };
        
 
@@ -270,8 +270,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -282,10 +282,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -304,7 +304,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
diff --git a/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v b/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v
index 368b494..8df7f5c 100644
--- a/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v
+++ b/verilog/dv/arduino_ascii_table/arduino_ascii_table_tb.v
@@ -236,8 +236,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -248,10 +248,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -270,7 +270,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -289,8 +289,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0 ;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v b/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v
index 7cce107..f85e347 100644
--- a/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v
+++ b/verilog/dv/arduino_character_analysis/arduino_character_analysis_tb.v
@@ -286,22 +286,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -320,7 +320,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -339,8 +339,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_digital_port_control/arduino_digital_port_control_tb.v b/verilog/dv/arduino_digital_port_control/arduino_digital_port_control_tb.v
index eaf97d5..1a90746 100644
--- a/verilog/dv/arduino_digital_port_control/arduino_digital_port_control_tb.v
+++ b/verilog/dv/arduino_digital_port_control/arduino_digital_port_control_tb.v
@@ -232,9 +232,9 @@
 //  Integrate the Serial SPI to ad5204/5206 (4-/6-Channel Digital Potentiometers)
 //  https://www.analog.com/media/en/technical-documentation/data-sheets/ad5204_5206.pdf
 //  -----------------------------------------------------------------------------------
-   wire sspi_sck = io_out[21];
-   wire sspi_sdi = io_out[20];
-   wire sspi_ssn = io_out[18];
+   wire sspi_sck = (io_oeb[21] == 1'b0) ? io_out[21] : 1'b0;
+   wire sspi_sdi = (io_oeb[20] == 1'b0) ? io_out[20] : 1'b0;
+   wire sspi_ssn = (io_oeb[18] == 1'b0) ? io_out[18] : 1'b0;
 
    wire [2:0]      p_channel; // potentiometer channel
    wire [7:0]      p_position; // potentiometer position
@@ -260,22 +260,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -294,7 +294,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
diff --git a/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v b/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v
index 30797d1..e2d9b91 100644
--- a/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v
+++ b/verilog/dv/arduino_gpio_intr/arduino_gpio_intr_tb.v
@@ -163,28 +163,28 @@
 reg [21:2] arduino_din;
 assign  {  
            //io_in[0], - Exclude RESET
-           io_in[12],
-           io_in[11],
-           io_in[27],
-           io_in[26],
-           io_in[25],
-           io_in[24],
-           io_in[23],
-           io_in[22],
-           io_in[21],
-           io_in[20],
-           io_in[19],
-           io_in[18],
-           io_in[17],
-           io_in[16],
-           io_in[15],
-           io_in[14],
-           io_in[13],
-           io_in[10],
-           io_in[9],
-           io_in[8]
+           io_in[12] ,
+           io_in[11] ,
+           io_in[27] ,
+           io_in[26] ,
+           io_in[25] ,
+           io_in[24] ,
+           io_in[23] ,
+           io_in[22] ,
+           io_in[21] ,
+           io_in[20] ,
+           io_in[19] ,
+           io_in[18] ,
+           io_in[17] ,
+           io_in[16] ,
+           io_in[15] ,
+           io_in[14] ,
+           io_in[13] ,
+           io_in[10] ,
+           io_in[9]  ,
+           io_in[8]  
            // Uart pins io_in[2], io_in[1] are excluded
-          } = (u_top.p_reset_n == 0) ? 23'hZZ_ZZZZ: arduino_din; // Tri-state untill Strap pull completed
+          } = (u_top.p_reset_n == 0) ? 23'hZZ_ZZZZ: (&io_oeb[27:8]) ? arduino_din: 'h0; // Tri-state untill Strap pull completed
                     
     reg[7:0] pinmap[0:22]; //ardiono to gpio pinmaping
 
@@ -359,8 +359,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -371,10 +371,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -393,7 +393,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -412,8 +412,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v b/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v
index 6f91eae..0f1e173 100644
--- a/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v
+++ b/verilog/dv/arduino_hello_world/arduino_hello_world_tb.v
@@ -238,8 +238,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -250,10 +250,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -272,7 +272,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -291,8 +291,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0 ;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v b/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v
index 1ae2309..9df55f9 100644
--- a/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v
+++ b/verilog/dv/arduino_i2c_scaner/arduino_i2c_scaner_tb.v
@@ -239,8 +239,8 @@
 // --------------------------
 tri scl,sda;
 
-assign sda  =  (io_oeb[26] == 1'b0) ? io_out[26] : 1'bz;
-assign scl   = (io_oeb[27] == 1'b0) ? io_out[27]: 1'bz;
+assign sda        = (io_oeb[26] == 1'b0) ? io_out[26] : 1'bz;
+assign scl        = (io_oeb[27] == 1'b0) ? io_out[27]: 1'bz;
 assign io_in[26]  =  sda;
 assign io_in[27]  =  scl;
 
@@ -285,8 +285,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -297,10 +297,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -319,7 +319,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -338,8 +338,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v b/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v
index 882a549..a7b1e87 100644
--- a/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v
+++ b/verilog/dv/arduino_i2c_wr_rd/arduino_i2c_wr_rd_tb.v
@@ -266,8 +266,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -278,10 +278,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -300,7 +300,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -319,8 +319,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v b/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v
index 45fe601..330f568 100644
--- a/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v
+++ b/verilog/dv/arduino_multi_serial/arduino_multi_serial_tb.v
@@ -258,8 +258,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -270,10 +270,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -292,7 +292,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -310,8 +310,8 @@
 // --------------------------
 wire uart0_txd,uart0_rxd;
 
-assign uart0_txd   = io_out[7];
-assign io_in[6]  = uart0_rxd ;
+assign uart0_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]    = (io_oeb[6] == 1'b1) ? uart0_rxd : 1'b0;
  
 uart_agent tb_uart0(
 	.mclk                (clock              ),
@@ -324,8 +324,8 @@
 // --------------------------
 wire uart1_txd,uart1_rxd;
 
-assign uart1_txd   = io_out[10];
-assign io_in[8]  = uart1_rxd ;
+assign uart1_txd   = (io_oeb[10] == 1'b0) ? io_out[10] : 1'b0;
+assign io_in[8]    = (io_oeb[8]  == 1'b1) ? uart1_rxd  : 1'b0;
  
 uart_agent tb_uart1(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v b/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v
index 46e8d54..f2d4f91 100644
--- a/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v
+++ b/verilog/dv/arduino_risc_boot/arduino_risc_boot_tb.v
@@ -172,22 +172,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -206,7 +206,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
diff --git a/verilog/dv/arduino_string/arduino_string_tb.v b/verilog/dv/arduino_string/arduino_string_tb.v
index 567a67c..b52d2d6 100644
--- a/verilog/dv/arduino_string/arduino_string_tb.v
+++ b/verilog/dv/arduino_string/arduino_string_tb.v
@@ -231,8 +231,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -243,10 +243,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -265,7 +265,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -284,8 +284,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0 ;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v b/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v
index 8493415..527f790 100644
--- a/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v
+++ b/verilog/dv/arduino_switchCase2/arduino_switchCase2_tb.v
@@ -294,8 +294,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -306,10 +306,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -328,7 +328,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -346,8 +346,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0 ;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v b/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v
index f3f29e1..77a1f7f 100644
--- a/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v
+++ b/verilog/dv/arduino_timer_intr/arduino_timer_intr_tb.v
@@ -245,8 +245,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -257,10 +257,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -279,7 +279,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -297,8 +297,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0 ;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/arduino_ws281x/arduino_ws281x_tb.v b/verilog/dv/arduino_ws281x/arduino_ws281x_tb.v
index 43929a1..67c4996 100644
--- a/verilog/dv/arduino_ws281x/arduino_ws281x_tb.v
+++ b/verilog/dv/arduino_ws281x/arduino_ws281x_tb.v
@@ -270,8 +270,8 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
    wire #1 io_oeb_33 = io_oeb[33];
    wire #1 io_oeb_34 = io_oeb[34];
@@ -282,10 +282,10 @@
    tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
    tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -304,7 +304,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31] == 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("none"))
 	u_sram (
@@ -321,7 +321,7 @@
 //-----------------------------------------------
 // WS281X BFM integration
 //----------------------------------------------
-assign ws281x_port[0] = io_out[8];
+assign ws281x_port[0] = (io_oeb[8] == 1'b0) ? io_out[8] : 1'b0;
 
 bfm_ws281x #(
               .PORT_ID(0),
@@ -335,7 +335,7 @@
 //-----------------------------------------------
 // WS281X BFM integration
 //----------------------------------------------
-assign ws281x_port[1] = io_out[9];
+assign ws281x_port[1] = (io_oeb[9] == 1'b0 ) ? io_out[9] : 1'b0;
 
 bfm_ws281x #(
               .PORT_ID(1),
@@ -349,7 +349,7 @@
 //-----------------------------------------------
 // WS281X BFM integration
 //----------------------------------------------
-assign ws281x_port[2] = io_out[13];
+assign ws281x_port[2] = (io_oeb[13] == 1'b0) ? io_out[13] : 1'b0 ;
 
 bfm_ws281x #(
               .PORT_ID(2),
@@ -363,7 +363,7 @@
 //-----------------------------------------------
 // WS281X BFM integration
 //----------------------------------------------
-assign ws281x_port[3] = io_out[17];
+assign ws281x_port[3] = (io_oeb[17] == 1'b0) ? io_out[17] : 1'b0 ;
 
 bfm_ws281x #(
               .PORT_ID(3),
diff --git a/verilog/dv/common/agents/user_tasks.sv b/verilog/dv/common/agents/user_tasks.sv
index c9ba9f1..b8e1f5f 100644
--- a/verilog/dv/common/agents/user_tasks.sv
+++ b/verilog/dv/common/agents/user_tasks.sv
@@ -90,7 +90,11 @@
 begin
    // Run in Fast Sim Mode
    `ifdef GL
+       // Note During wb_host resynth this FF is changes,
+       // Keep cross-check during Gate Sim
        force u_top.u_wb_host._10258_.Q= 1'b1; 
+       //force u_top.u_wb_host.u_reg.u_fastsim_buf.u_buf.X = 1'b1; 
+       //force u_top.u_wb_host.u_reg.cfg_fast_sim = 1'b1; 
    `else
        force u_top.u_wb_host.u_reg.u_fastsim_buf.X = 1'b1; 
     `endif
diff --git a/verilog/dv/common/bfm/bfm_ir.v b/verilog/dv/common/bfm/bfm_ir.v
new file mode 100644
index 0000000..8de85a1
--- /dev/null
+++ b/verilog/dv/common/bfm/bfm_ir.v
@@ -0,0 +1,136 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , Julien OURY                       

+// 

+// 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 Julien OURY <julien.oury@outlook.fr>

+//

+////////////////////////////////////////////////////////////////////////////

+`timescale 1ns/1ps

+

+module bfm_ir (

+  output reg       ir_signal

+);

+

+  reg     p_polarity;

+  integer p_period;

+  integer i;

+  integer state;

+

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  // TASK : init

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  task init(

+    input         polarity,

+    input integer tick_period_ns

+  );

+  begin

+    $display("simetime = %g : Init IR interface with", $time);

+    $display("simetime = %g :  - polarity = %b", $time, polarity);

+    $display("simetime = %g :  - period to %d ns", $time, tick_period_ns); 

+    

+    // Parameters

+    p_polarity = polarity;

+    p_period = tick_period_ns;

+    

+    // Init output signals

+    ir_signal = ~p_polarity;

+

+  end

+  endtask

+  

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  // TASK : write

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  task send_nec(

+    input [7:0] addr,

+    input [7:0] data

+  );

+  begin

+    $display("simetime = %g : Send IR NEC trame (0x%h -> 0x%h)", $time, addr, data);

+

+    state = 0;

+    send_start();

+    

+    state = 1;

+    // Send address

+    for (i=0 ; i<8 ; i=i+1) begin

+      send_bit(addr[i]);

+    end

+    

+    state = 2;

+    // Send address (complement)

+    for (i=0 ; i<8 ; i=i+1) begin

+      send_bit(~addr[i]);

+    end

+    

+    state = 3;

+    // Send data

+    for (i=0 ; i<8 ; i=i+1) begin

+      send_bit(data[i]);

+    end

+    

+    state = 4;

+    // Send data (complement)

+    for (i=0 ; i<8 ; i=i+1) begin

+      send_bit(~data[i]);

+    end

+    

+    state = 5;

+    // Send stop

+    send_stop();

+    state = 6;

+    

+

+  end

+  endtask

+

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  // TASK : send_start

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  task send_start;

+  begin

+    ir_signal = p_polarity;

+    #(p_period*16) ir_signal = ~p_polarity;

+    #(p_period*8)  ir_signal =  p_polarity;

+  end 

+  endtask

+  

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  // TASK : send_bit

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  task send_bit(

+    input reg value

+  );

+  begin

+    ir_signal = p_polarity;

+    #(p_period)  ir_signal = ~p_polarity;

+    if (value == 1'b1) begin

+      #(p_period*3)  ir_signal = p_polarity;

+    end else begin

+      #(p_period)  ir_signal = p_polarity;

+    end

+  end 

+  endtask

+  

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  // TASK : send_stop

+  /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+  task send_stop;

+  begin

+    ir_signal = p_polarity;

+    #(p_period) ir_signal = ~p_polarity;

+  end 

+  endtask

+  

+endmodule

diff --git a/verilog/dv/user_aes/user_aes_tb.v b/verilog/dv/user_aes/user_aes_tb.v
index 55aba10..f2055fc 100644
--- a/verilog/dv/user_aes/user_aes_tb.v
+++ b/verilog/dv/user_aes/user_aes_tb.v
@@ -106,14 +106,14 @@
      *   Pin-10       PB7/XTAL2/TOSC2           digital_io[12]
      *   ********************************************************/
 
-     wire [7:0]  port_b_in = {   io_out[12],
-		                         io_out[11],
-		                         io_out[21],
-		                         io_out[20],
-			                     io_out[19],
-			                     io_out[18],
-		                         io_out[17],
-		                         io_out[16]
+     wire [7:0]  port_b_in = {  (io_oeb[12]== 1'b0) ? io_out[12] : 1'b0,
+		                 (io_oeb[11]== 1'b0) ? io_out[11] : 1'b0,
+		                 (io_oeb[21]== 1'b0) ? io_out[21] : 1'b0,
+		                 (io_oeb[20]== 1'b0) ? io_out[20] : 1'b0,
+			         (io_oeb[19]== 1'b0) ? io_out[19] : 1'b0,
+			         (io_oeb[18]== 1'b0) ? io_out[18] : 1'b0,
+		                 (io_oeb[17]== 1'b0) ? io_out[17] : 1'b0,
+		                 (io_oeb[16]== 1'b0) ? io_out[16] : 1'b0
 			     };
 	initial begin
 		test_fail = 0;
@@ -237,22 +237,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name("user_aes.hex"),
@@ -277,8 +277,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/user_aes_core/user_aes_core_tb.v b/verilog/dv/user_aes_core/user_aes_core_tb.v
index fbb54f7..c052771 100644
--- a/verilog/dv/user_aes_core/user_aes_core_tb.v
+++ b/verilog/dv/user_aes_core/user_aes_core_tb.v
@@ -106,14 +106,14 @@
      *   Pin-10       PB7/XTAL2/TOSC2           digital_io[12]
      *   ********************************************************/
 
-     wire [7:0]  port_b_in = {   io_out[12],
-		                         io_out[11],
-		                         io_out[21],
-		                         io_out[20],
-			                     io_out[19],
-			                     io_out[18],
-		                         io_out[17],
-		                         io_out[16]
+     wire [7:0]  port_b_in = {  (io_oeb[12]== 1'b0) ? io_out[12] : 1'b0,
+		                 (io_oeb[11]== 1'b0) ? io_out[11] : 1'b0,
+		                 (io_oeb[21]== 1'b0) ? io_out[21] : 1'b0,
+		                 (io_oeb[20]== 1'b0) ? io_out[20] : 1'b0,
+			         (io_oeb[19]== 1'b0) ? io_out[19] : 1'b0,
+			         (io_oeb[18]== 1'b0) ? io_out[18] : 1'b0,
+		                 (io_oeb[17]== 1'b0) ? io_out[17] : 1'b0,
+		                 (io_oeb[16]== 1'b0) ? io_out[16] : 1'b0
 			     };
 	initial begin
 		test_fail = 0;
@@ -238,22 +238,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name("user_aes_core.hex"),
@@ -278,8 +278,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/user_basic/user_basic_tb.v b/verilog/dv/user_basic/user_basic_tb.v
index 826a0ef..c570118 100644
--- a/verilog/dv/user_basic/user_basic_tb.v
+++ b/verilog/dv/user_basic/user_basic_tb.v
@@ -196,11 +196,12 @@
 	   	$dumpfile("simx.vcd");
 	   	$dumpvars(1, `TB_TOP);
 	   	$dumpvars(1, `TB_TOP.u_top);
-	   	$dumpvars(0, `TB_TOP.u_top.u_pll);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_pll);
 	   	$dumpvars(0, `TB_TOP.u_top.u_wb_host);
 	   	//$dumpvars(0, `TB_TOP.u_top.u_intercon);
 	   	//$dumpvars(1, `TB_TOP.u_top.u_intercon);
 	   	$dumpvars(0, `TB_TOP.u_top.u_pinmux);
+	   	$dumpvars(0, `TB_TOP.u_top.u_rp_south);
 	   end
        `endif
 
@@ -561,7 +562,7 @@
 //  UART Agent integration
 // --------------------------
 
-assign uart_txd   = io_out[7];
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
 //assign io_in[6]  = uart_rxd ; // Assigned at top-level
  
 uart_agent tb_master_uart(
@@ -677,7 +678,7 @@
 endtask
 
 
-wire dbg_clk_mon = io_out[37];
+wire dbg_clk_mon = (io_oeb[37] == 1'b0) ? io_out[37]: 1'b0;
 
 //assign dbg_clk_ref  =    (cfg_mon_sel == 4'b000) ? user_clock1    :
 //	                       (cfg_mon_sel == 4'b001) ? user_clock2    :
diff --git a/verilog/dv/user_cache_bypass/user_cache_bypass_tb.v b/verilog/dv/user_cache_bypass/user_cache_bypass_tb.v
index b8909fa..c287d2a 100644
--- a/verilog/dv/user_cache_bypass/user_cache_bypass_tb.v
+++ b/verilog/dv/user_cache_bypass/user_cache_bypass_tb.v
@@ -155,22 +155,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name("user_cache_bypass.hex"),
diff --git a/verilog/dv/user_fpu_core/user_fpu_core_tb.v b/verilog/dv/user_fpu_core/user_fpu_core_tb.v
index e79506e..e0e95be 100644
--- a/verilog/dv/user_fpu_core/user_fpu_core_tb.v
+++ b/verilog/dv/user_fpu_core/user_fpu_core_tb.v
@@ -241,22 +241,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -281,8 +281,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7]: 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/user_gpio/user_gpio_tb.v b/verilog/dv/user_gpio/user_gpio_tb.v
index 1e313c4..317e45f 100644
--- a/verilog/dv/user_gpio/user_gpio_tb.v
+++ b/verilog/dv/user_gpio/user_gpio_tb.v
@@ -99,11 +99,11 @@
 
      reg  [7:0]  port_a_out;
      wire [7:0]  port_a_in = {   3'b0,
-		                         io_out[4],
-			                     io_out[3],
-			                     io_out[2],
-		                         io_out[1],
-		                         io_out[0]
+		                         (io_oeb[4] == 1'b0) ? io_out[4]: 1'b0,
+			                     (io_oeb[3] == 1'b0) ? io_out[3]: 1'b0,
+			                     (io_oeb[2] == 1'b0) ? io_out[2]: 1'b0,
+		                         (io_oeb[1] == 1'b0) ? io_out[1]: 1'b0,
+		                         (io_oeb[0] == 1'b0) ? io_out[0]: 1'b0
 			                 };
 
 
@@ -112,7 +112,7 @@
 		        io_in[2],
 		        io_in[1],
 		        io_in[0]
-		} = (test_start) ? port_a_out[4:0]: 5'hZ;
+		} = (test_start) ? ((&io_oeb[4:0]) ? port_a_out[4:0]: 5'hZ) :  5'hZ;
 
 
      /************* Port-B Mapping **********************************
@@ -127,14 +127,14 @@
      *   ********************************************************/
 
      reg  [7:0]  port_b_out;
-     wire [7:0]  port_b_in = {   io_out[12],
-		                         io_out[11],
-		                         io_out[21],
-		                         io_out[20],
-			                     io_out[19],
-			                     io_out[18],
-		                         io_out[17],
-		                         io_out[16]
+     wire [7:0]  port_b_in = {  (io_oeb[12]== 1'b0)? io_out[12] : 1'b0,
+		                        (io_oeb[11]== 1'b0)? io_out[11] : 1'b0,
+		                        (io_oeb[21]== 1'b0)? io_out[21] : 1'b0,
+		                        (io_oeb[20]== 1'b0)? io_out[20] : 1'b0,
+			                    (io_oeb[19]== 1'b0)? io_out[19] : 1'b0,
+			                    (io_oeb[18]== 1'b0)? io_out[18] : 1'b0,
+		                        (io_oeb[17]== 1'b0)? io_out[17] : 1'b0,
+		                        (io_oeb[16]== 1'b0)? io_out[16] : 1'b0
 			     };
      
      assign {   io_in[12],
@@ -159,13 +159,13 @@
 
      reg  [7:0]  port_c_out;
      wire [7:0]  port_c_in = {   1'b0,
-		             io_out[5],
-		             io_out[27],
-		             io_out[26],
-			         io_out[25],
-			         io_out[24],
-		             io_out[23],
-		             io_out[22]
+		             (io_oeb[5]  == 1'b0) ? io_out[5]  : 1'b0,
+		             (io_oeb[27] == 1'b0) ? io_out[27] : 1'b0,
+		             (io_oeb[26] == 1'b0) ? io_out[26] : 1'b0,
+			         (io_oeb[25] == 1'b0) ? io_out[25] : 1'b0,
+			         (io_oeb[24] == 1'b0) ? io_out[24] : 1'b0,
+		             (io_oeb[23] == 1'b0) ? io_out[23] : 1'b0,
+		             (io_oeb[22] == 1'b0) ? io_out[22] : 1'b0
 			     };
       assign {  io_in[5],
 	            io_in[27],
@@ -189,14 +189,14 @@
       *   ********************************************************/
 
      reg  [7:0]  port_d_out;
-     wire [7:0]  port_d_in = {  io_out[15],
-		                        io_out[14],
-		                        io_out[13],
-		                        io_out[10],
-			                    io_out[9],
-			                    io_out[8],
-		                        io_out[7],
-		                        io_out[6]
+     wire [7:0]  port_d_in = { (io_oeb[15]== 1'b0) ? io_out[15] : 1'b0,
+		                       (io_oeb[14]== 1'b0) ? io_out[14] : 1'b0,
+		                       (io_oeb[13]== 1'b0) ? io_out[13] : 1'b0,
+		                       (io_oeb[10]== 1'b0) ? io_out[10] : 1'b0,
+			                   (io_oeb[9] == 1'b0) ? io_out[9]  : 1'b0,
+			                   (io_oeb[8] == 1'b0) ? io_out[8]  : 1'b0,
+		                       (io_oeb[7] == 1'b0) ? io_out[7]  : 1'b0,
+		                       (io_oeb[6] == 1'b0) ? io_out[6]  : 1'b0
 			        };
 
 	assign {  io_in[15],
diff --git a/verilog/dv/user_ir_rx/Makefile b/verilog/dv/user_ir_rx/Makefile
new file mode 100644
index 0000000..32755e0
--- /dev/null
+++ b/verilog/dv/user_ir_rx/Makefile
@@ -0,0 +1,84 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+
+# ---- Include Partitioned Makefiles ----
+
+CONFIG = caravel_user_project
+ 
+#######################################################################
+## Caravel Verilog for Integration Tests
+#######################################################################
+
+DESIGNS?=../../..
+
+export USER_PROJECT_VERILOG ?=  $(DESIGNS)/verilog
+
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+### To Enable IVERILOG FST DUMP
+export IVERILOG_DUMPER = fst
+
+
+.SUFFIXES:
+
+PATTERN = user_ir_rx
+
+all:  ${PATTERN:=.vcd}
+
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+   endif
+else  
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+   endif
+endif
+
+%.vcd: %.vvp
+	vvp $< 
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_ir_rx/user_ir_rx_tb.v b/verilog/dv/user_ir_rx/user_ir_rx_tb.v
new file mode 100644
index 0000000..d04053f
--- /dev/null
+++ b/verilog/dv/user_ir_rx/user_ir_rx_tb.v
@@ -0,0 +1,160 @@
+////////////////////////////////////////////////////////////////////////////
+// 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 IR Receiver  validation Test bench           
+
+     Author(s):                                                  
+        - Dinesh Annayya, dinesh.annayya@gmail.com                
+     Revision :                                                  
+        - 0.1 - 16th Feb 2021, Dinesh A                           
+*********************************************************************/
+
+`default_nettype wire
+
+`timescale 1 ns/1 ps
+
+`include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+`include "uart_agent.v"
+`include "user_params.svh"
+`include "bfm_ir.v"
+
+`define TB_TOP user_ir_rx_tb
+
+module `TB_TOP;
+parameter real CLK1_PERIOD  = 25; // 40Mhz
+parameter real CLK2_PERIOD = 2.5;
+parameter real IPLL_PERIOD = 5.008;
+parameter real XTAL_PERIOD = 6;
+
+integer  i;
+reg [7:0]  cmd_addr;
+reg [7:0]  cmd_data;
+
+
+`include "user_tasks.sv"
+
+
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("simx.vcd");
+	   	$dumpvars(1, `TB_TOP);
+	   	$dumpvars(1, `TB_TOP.u_top);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_pll);
+	   	$dumpvars(0, `TB_TOP.u_top.u_wb_host);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_intercon);
+	   	//$dumpvars(1, `TB_TOP.u_top.u_intercon);
+	   	$dumpvars(0, `TB_TOP.u_top.u_pinmux);
+	   	$dumpvars(0, `TB_TOP.u_top.u_peri);
+	   	$dumpvars(0, `TB_TOP.u_bfm_ir);
+	   end
+       `endif
+
+initial
+begin
+
+   init();
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("Monitor: Standalone User Basic Test Started");
+   
+   repeat (2) @(posedge clock);
+
+   test_fail=0;
+   // Normal tick period: 562.5µs = 562500ns
+   //Protocol tick period divided by 10 for simulation speed-up, 10x slow Tick Period = 56250ns
+   //Protocol tick period divided by 100 for simulation speed-up, 100x slow Tick Period = 5625ns
+
+   u_bfm_ir.init(0, 5625); //Protocol tick period divided by 100 for simulation speed-up
+
+  // Configuration of IR receiver
+  // Typical Oversampling is 8 time of Tick period = 562500/8 = 70312.5ns
+
+  // Protocol tick period divided by 10 for simulation speed-up
+  // with 10x slow speed up = 56250/8= 7031.25ns
+  // With 25ns clock period , Tick  = (Clock Period * Divider) / Multiplier  
+  //  Tick = 25ns * 0x6DDD / 0x64 = 25ns * 28125 / 100 = 7031.25ns
+  
+  // Protocol tick period divided by 100 for simulation speed-up
+  // with 100x slow speed up = 5625/8= 703.125ns
+  // With 25ns clock period , Tick  = (Clock Period * Divider) / Multiplier  
+  //  Tick = 25ns * 0x6DDD / 0x3E8 = 25ns * 28125 / 1000 = 703.125ns
+
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_MULTIPLIER,32'h000003E8);
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_DIVIDER,32'h00006DDD);
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_CMD,32'hA5000000);
+
+
+   repeat (100) @(posedge clock);
+   fork
+   begin
+       for(i =0; i < 2; i = i+1) begin
+          cmd_addr = $random%256;
+          cmd_data = $random%256;
+          u_bfm_ir.send_nec(cmd_addr, cmd_data);
+          read_data = 0;
+          while(read_data[3:0] == 'h0) begin
+             wb_user_core_read(`ADDR_SPACE_IR+`IR_CFG_CMD,read_data);
+          end
+          wb_user_core_read(`ADDR_SPACE_IR+`IR_CFG_RX_DATA,read_data);
+          if(read_data[15:8] != cmd_addr && read_data[7:0] != cmd_data)
+          begin
+             $display("ERROR : Exp: [%x] -> [%x] Rxd [%x] -> [%x]",cmd_addr,cmd_data,read_data[15:8],read_data[7:0]);
+             test_fail = 1;
+          end 
+       end
+   end
+   begin
+      repeat (1000000) @(posedge clock);
+      test_fail = 1;
+   end
+   join_any
+   disable fork; //disable pending fork activity
+
+   repeat (100) @(posedge clock);
+   
+      $display("###################################################");
+      if(test_fail == 0) begin
+         `ifdef GL
+             $display("Monitor: %m (GL) Passed");
+         `else
+             $display("Monitor: %m (RTL) Passed");
+         `endif
+      end else begin
+          `ifdef GL
+              $display("Monitor: %m (GL) Failed");
+          `else
+              $display("Monitor: %m (RTL) Failed");
+          `endif
+       end
+      $display("###################################################");
+      #100
+      $finish;
+end
+
+wire ir_rx;
+
+assign io_in[12] = (io_oeb[12] == 1'b1) ? ir_rx : 1'b0;
+
+  bfm_ir u_bfm_ir(
+    .ir_signal(ir_rx)
+  );
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_ir_tx/Makefile b/verilog/dv/user_ir_tx/Makefile
new file mode 100644
index 0000000..0406adc
--- /dev/null
+++ b/verilog/dv/user_ir_tx/Makefile
@@ -0,0 +1,84 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+
+# ---- Include Partitioned Makefiles ----
+
+CONFIG = caravel_user_project
+ 
+#######################################################################
+## Caravel Verilog for Integration Tests
+#######################################################################
+
+DESIGNS?=../../..
+
+export USER_PROJECT_VERILOG ?=  $(DESIGNS)/verilog
+
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+### To Enable IVERILOG FST DUMP
+export IVERILOG_DUMPER = fst
+
+
+.SUFFIXES:
+
+PATTERN = user_ir_tx
+
+all:  ${PATTERN:=.vcd}
+
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+   endif
+else  
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+   endif
+endif
+
+%.vcd: %.vvp
+	vvp $< 
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_ir_tx/user_ir_tx_tb.v b/verilog/dv/user_ir_tx/user_ir_tx_tb.v
new file mode 100644
index 0000000..ce0c5a5
--- /dev/null
+++ b/verilog/dv/user_ir_tx/user_ir_tx_tb.v
@@ -0,0 +1,166 @@
+////////////////////////////////////////////////////////////////////////////
+// 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 IR Receiver  validation Test bench           
+
+     Test case:  IR Transmitter io_out[15] is loop back to IO Reciver io_in[12]
+
+     Author(s):                                                  
+        - Dinesh Annayya, dinesh.annayya@gmail.com                
+     Revision :                                                  
+        - 0.1 - 13 Dec 2022, Dinesh A                           
+*********************************************************************/
+
+`default_nettype wire
+
+`timescale 1 ns/1 ps
+
+`include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+`include "user_params.svh"
+
+`define TB_TOP user_ir_tx_tb
+
+module `TB_TOP;
+parameter real CLK1_PERIOD  = 25; // 40Mhz
+parameter real CLK2_PERIOD = 2.5;
+parameter real IPLL_PERIOD = 5.008;
+parameter real XTAL_PERIOD = 6;
+
+integer  i;
+reg [7:0]  cmd_addr;
+reg [7:0]  cmd_data;
+
+
+`include "user_tasks.sv"
+
+
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("simx.vcd");
+	   	$dumpvars(1, `TB_TOP);
+	   	$dumpvars(1, `TB_TOP.u_top);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_pll);
+	   	$dumpvars(0, `TB_TOP.u_top.u_wb_host);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_intercon);
+	   	//$dumpvars(1, `TB_TOP.u_top.u_intercon);
+	   	$dumpvars(0, `TB_TOP.u_top.u_pinmux);
+	   	$dumpvars(0, `TB_TOP.u_top.u_peri);
+	   end
+       `endif
+
+initial
+begin
+
+   init();
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("Monitor: Standalone User Basic Test Started");
+   
+   repeat (2) @(posedge clock);
+
+   test_fail=0;
+
+   // Normal tick period: 562.5µs = 562500ns
+   //Protocol tick period divided by 10 for simulation speed-up, 10x slow Tick Period = 56250ns
+   //Protocol tick period divided by 100 for simulation speed-up, 100x slow Tick Period = 5625ns
+
+
+  // Configuration of IR receiver
+  // Typical Oversampling is 8 time of Tick period = 562500/8 = 70312.5ns
+
+  // Protocol tick period divided by 10 for simulation speed-up
+  // with 10x slow speed up = 56250/8= 7031.25ns
+  // With 25ns clock period , Tick  = (Clock Period * Divider) / Multiplier  
+  //  Tick = 25ns * 0x6DDD / 0x64 = 25ns * 28125 / 100 = 7031.25ns
+  
+  // Protocol tick period divided by 100 for simulation speed-up
+  // with 100x slow speed up = 5625/8= 703.125ns
+  // With 25ns clock period , Tick  = (Clock Period * Divider) / Multiplier  
+  //  Tick = 25ns * 0x6DDD / 0x3E8 = 25ns * 28125 / 1000 = 703.125ns
+
+  wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_MUTI_FUNC,'h100);
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_MULTIPLIER,32'h000003E8);
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_DIVIDER,32'h00006DDD);
+  wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_CMD,32'hE4100000); // Enable Both Tx/RX Enable
+
+   // Enable GPIO IR TX at bit [15]
+   wb_user_core_write(`ADDR_SPACE_GLBL+`GLBL_CFG_MUTI_FUNC,'h2_0000);
+
+   repeat (100) @(posedge clock);
+   fork
+   begin
+       for(i =0; i < 2; i = i+1) begin
+          // Setp-1: Check the TX FIFO is not full
+          read_data[7:4] = 4'h8;
+          while(read_data[7:4] == 'h8) begin
+             wb_user_core_read(`ADDR_SPACE_IR+`IR_CFG_CMD,read_data);
+          end
+          cmd_addr = $random%256;
+          cmd_data = $random%256;
+          wb_user_core_write(`ADDR_SPACE_IR+`IR_CFG_TX_DATA,{16'h0,cmd_addr[7:0],cmd_data[7:0]}); 
+
+          // Setp-2: Check the RX FIFO is not empty
+          read_data = 0;
+          while(read_data[3:0] == 'h0) begin
+             wb_user_core_read(`ADDR_SPACE_IR+`IR_CFG_CMD,read_data);
+          end
+          wb_user_core_read(`ADDR_SPACE_IR+`IR_CFG_RX_DATA,read_data);
+          if(read_data[15:8] != cmd_addr && read_data[7:0] != cmd_data)
+          begin
+             $display("ERROR : Exp: [%x] -> [%x] Rxd [%x] -> [%x]",cmd_addr,cmd_data,read_data[15:8],read_data[7:0]);
+             test_fail = 1;
+          end 
+       end
+   end
+   begin
+      repeat (1000000) @(posedge clock);
+      test_fail = 1;
+   end
+   join_any
+   disable fork; //disable pending fork activity
+
+   repeat (100) @(posedge clock);
+   
+      $display("###################################################");
+      if(test_fail == 0) begin
+         `ifdef GL
+             $display("Monitor: %m (GL) Passed");
+         `else
+             $display("Monitor: %m (RTL) Passed");
+         `endif
+      end else begin
+          `ifdef GL
+              $display("Monitor: %m (GL) Failed");
+          `else
+              $display("Monitor: %m (RTL) Failed");
+          `endif
+       end
+      $display("###################################################");
+      #100
+      $finish;
+end
+
+// Look back the IR Tx from Port [15] to PORT[12]
+wire   ir_tx     = (io_oeb[15] == 1'b0) ? io_out[15] : 1'b0;;
+assign io_in[12] = (io_oeb[12] == 1'b1) ? ir_tx : 1'b0;
+
+
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_pwm/user_pwm_tb.v b/verilog/dv/user_pwm/user_pwm_tb.v
index 3c425ce..a5297b0 100644
--- a/verilog/dv/user_pwm/user_pwm_tb.v
+++ b/verilog/dv/user_pwm/user_pwm_tb.v
@@ -765,12 +765,12 @@
 	        $finish;
 	end
 
-wire [5:0] pwm_wfm = {io_out[19],
-                      io_out[18],
-                      io_out[17],
-                      io_out[14],
-                      io_out[13],
-                      io_out[9]};
+wire [5:0] pwm_wfm = {(io_oeb[19] == 1'b0) ? io_out[19]: 1'b0 ,
+                      (io_oeb[18] == 1'b0) ? io_out[18]: 1'b0 ,
+                      (io_oeb[17] == 1'b0) ? io_out[17]: 1'b0 ,
+                      (io_oeb[14] == 1'b0) ? io_out[14]: 1'b0 ,
+                      (io_oeb[13] == 1'b0) ? io_out[13]: 1'b0 ,
+                      (io_oeb[9]  == 1'b0) ? io_out[9] : 1'b0  };
 
 wire pwm0 = pwm_wfm[0];
 wire pwm1 = pwm_wfm[1];
diff --git a/verilog/dv/user_qspi/user_qspi_tb.v b/verilog/dv/user_qspi/user_qspi_tb.v
index 9801bdd..66369a2 100644
--- a/verilog/dv/user_qspi/user_qspi_tb.v
+++ b/verilog/dv/user_qspi/user_qspi_tb.v
@@ -1141,22 +1141,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
 
    // Quad flash
@@ -1176,7 +1176,7 @@
 
        );
 
-   wire spiram_csb = io_out[31];
+   wire spiram_csb = (io_oeb[31]== 1'b0) ? io_out[31] : 1'b0;
 
    is62wvs1288 #(.mem_file_name("flash1.hex"))
 	u_sfram (
diff --git a/verilog/dv/user_random/Makefile b/verilog/dv/user_random/Makefile
new file mode 100644
index 0000000..f96b0fe
--- /dev/null
+++ b/verilog/dv/user_random/Makefile
@@ -0,0 +1,84 @@
+# SPDX-FileCopyrightText: 2020 Efabless Corporation
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# SPDX-License-Identifier: Apache-2.0
+
+
+# ---- Include Partitioned Makefiles ----
+
+CONFIG = caravel_user_project
+ 
+#######################################################################
+## Caravel Verilog for Integration Tests
+#######################################################################
+
+DESIGNS?=../../..
+
+export USER_PROJECT_VERILOG ?=  $(DESIGNS)/verilog
+
+
+## Simulation mode: RTL/GL
+SIM?=RTL
+DUMP?=OFF
+
+### To Enable IVERILOG FST DUMP
+export IVERILOG_DUMPER = fst
+
+
+.SUFFIXES:
+
+PATTERN = user_random
+
+all:  ${PATTERN:=.vcd}
+
+
+vvp:  ${PATTERN:=.vvp}
+
+%.vvp: %_tb.v
+ifeq ($(SIM),RTL)
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DSIM -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.rtl.lib  \
+	$< -o $@ 
+   endif
+else  
+   ifeq ($(DUMP),OFF)
+	iverilog -g2012 -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+    else  
+	iverilog -g2012 -DWFDUMP -DFUNCTIONAL -DUSE_POWER_PINS -DGL -I $(PDK_PATH) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.$(CONFIG) \
+	-f$(USER_PROJECT_VERILOG)/includes/includes.gl.lib \
+	$< -o $@ 
+   endif
+endif
+
+%.vcd: %.vvp
+	vvp $< 
+
+
+# ---- Clean ----
+
+clean:
+	rm -f *.elf *.hex *.bin *.vvp *.vcd *.log *.dump
+
+.PHONY: clean hex all
diff --git a/verilog/dv/user_random/user_random_tb.v b/verilog/dv/user_random/user_random_tb.v
new file mode 100644
index 0000000..665526a
--- /dev/null
+++ b/verilog/dv/user_random/user_random_tb.v
@@ -0,0 +1,126 @@
+////////////////////////////////////////////////////////////////////////////
+// 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 Random Generator validation Test bench           
+PseudoRandom generator Test:
+    - Read 32 randoms values
+	- Check that each value is non-equal to 0x00000000
+	- Check that each value is non-equal to 0xFFFFFFFF
+	- Check that each value is non-equal to the previous value
+
+     Author(s):                                                  
+        - Dinesh Annayya, dinesh.annayya@gmail.com                
+     Revision :                                                  
+        - 0.1 - 16th Feb 2021, Dinesh A                           
+*********************************************************************/
+
+`default_nettype wire
+
+`timescale 1 ns/1 ps
+
+`include "sram_macros/sky130_sram_2kbyte_1rw1r_32x512_8.v"
+`include "uart_agent.v"
+`include "user_params.svh"
+
+`define TB_TOP user_random_tb
+
+module `TB_TOP;
+parameter real CLK1_PERIOD  = 20; // 50Mhz
+parameter real CLK2_PERIOD = 2.5;
+parameter real IPLL_PERIOD = 5.008;
+parameter real XTAL_PERIOD = 6;
+
+integer  i;
+reg [31:0] pre_random;
+
+`include "user_tasks.sv"
+
+
+
+	`ifdef WFDUMP
+	   initial begin
+	   	$dumpfile("simx.vcd");
+	   	$dumpvars(1, `TB_TOP);
+	   	$dumpvars(1, `TB_TOP.u_top);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_pll);
+	   	$dumpvars(0, `TB_TOP.u_top.u_wb_host);
+	   	//$dumpvars(0, `TB_TOP.u_top.u_intercon);
+	   	//$dumpvars(1, `TB_TOP.u_top.u_intercon);
+	   	$dumpvars(0, `TB_TOP.u_top.u_pinmux);
+	   	$dumpvars(0, `TB_TOP.u_top.u_rp_south);
+	   end
+       `endif
+
+initial
+begin
+
+   init();
+
+   #200; // Wait for reset removal
+   repeat (10) @(posedge clock);
+   $display("Monitor: Standalone User Basic Test Started");
+   
+   repeat (2) @(posedge clock);
+
+   test_fail=0;
+   pre_random = 0;
+   fork
+   begin
+       for(i =0; i < 100; i = i+1) begin
+          wb_user_core_read(`ADDR_SPACE_GLBL+`GLBL_CFG_RANDOM_NO,read_data);
+          if(read_data == 32'h0) begin
+             test_fail = 1;
+             $display("ERROR: RANDOM Number Is Zero");
+          end else if(read_data == 32'hFFFF_FFFF) begin
+             test_fail = 1;
+             $display("ERROR: RANDOM Number Is All One");
+          end else if(read_data == pre_random) begin
+             test_fail = 1;
+             $display("ERROR: RANDOM Number is same as previous one");
+          end
+          pre_random = read_data;
+       end
+   end
+   begin
+      repeat (50000) @(posedge clock);
+      test_fail = 1;
+   end
+   join_any
+   disable fork; //disable pending fork activity
+
+   
+      $display("###################################################");
+      if(test_fail == 0) begin
+         `ifdef GL
+             $display("Monitor: %m (GL) Passed");
+         `else
+             $display("Monitor: %m (RTL) Passed");
+         `endif
+      end else begin
+          `ifdef GL
+              $display("Monitor: %m (GL) Failed");
+          `else
+              $display("Monitor: %m (RTL) Failed");
+          `endif
+       end
+      $display("###################################################");
+      #100
+      $finish;
+end
+endmodule
+`default_nettype wire
diff --git a/verilog/dv/user_spi_isp/user_spi_isp_tb.v b/verilog/dv/user_spi_isp/user_spi_isp_tb.v
index bc6a80c..7d6e287 100644
--- a/verilog/dv/user_spi_isp/user_spi_isp_tb.v
+++ b/verilog/dv/user_spi_isp/user_spi_isp_tb.v
@@ -151,10 +151,10 @@
 end
 
 
-assign io_in[5]  = 1'b0;
-assign io_in[21] = sclk;
-assign io_in[20] = sdi;
-assign sdo       = io_out[19];
+assign io_in[5]  = (io_oeb[5]  == 1'b1) ? 1'b0 : 1'b0;
+assign io_in[21] = (io_oeb[21] == 1'b1) ? sclk : 1'b0;
+assign io_in[20] = (io_oeb[20] == 1'b1) ? sdi  : 1'b0;
+assign sdo       = (io_oeb[19] == 1'b0) ? io_out[19] : 1'b0;
 
 bfm_spim  u_spim (
           // SPI
diff --git a/verilog/dv/user_sram_exec/user_sram_exec_tb.v b/verilog/dv/user_sram_exec/user_sram_exec_tb.v
index 6e2bcf4..a3c05ad 100644
--- a/verilog/dv/user_sram_exec/user_sram_exec_tb.v
+++ b/verilog/dv/user_sram_exec/user_sram_exec_tb.v
@@ -168,22 +168,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
diff --git a/verilog/dv/user_sspi/user_sspi_tb.v b/verilog/dv/user_sspi/user_sspi_tb.v
index 1650d50..2977fa7 100644
--- a/verilog/dv/user_sspi/user_sspi_tb.v
+++ b/verilog/dv/user_sspi/user_sspi_tb.v
@@ -383,15 +383,15 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
    wire flash_io1;
-   wire flash_clk = io_out[21];
-   tri  #1 flash_io0 = io_out[20];
-   assign io_in[19] = flash_io1;
+   wire flash_clk    = (io_oeb[21] == 1'b0) ? io_out[21] : 1'b0;
+   tri  #1 flash_io0 = (io_oeb[20] == 1'b0) ? io_out[20] : 1'b0;
+   assign io_in[19]  = (io_oeb[19] == 1'b1) ? flash_io1  : 1'b0;
 
    tri  #1 flash_io2 = 1'b1;
    tri  #1 flash_io3 = 1'b1;
 
 
-   wire spiram_csb0 = io_out[18];
+   wire spiram_csb0 = (io_oeb[18] == 1'b0) ? io_out[18] : 1'b0;
    is62wvs1288 #(.mem_file_name("flash0.hex"))
 	u_sfram_0 (
          // Data Inputs/Outputs
@@ -404,7 +404,7 @@
            .io3    (flash_io3)
     );
 
-   wire spiram_csb1 = io_out[17];
+   wire spiram_csb1 = (io_oeb[17] == 1'b0) ? io_out[17] : 1'b0;
    is62wvs1288 #(.mem_file_name("flash1.hex"))
 	u_sfram_1 (
          // Data Inputs/Outputs
@@ -417,7 +417,7 @@
            .io3    (flash_io3)
     );
 
-   wire spiram_csb2 = io_out[14];
+   wire spiram_csb2 = (io_oeb[14] == 1'b0) ? io_out[14] : 1'b0;
 is62wvs1288 #(.mem_file_name("flash2.hex"))
      u_sfram_2 (
       // Data Inputs/Outputs
@@ -430,7 +430,7 @@
 	.io3    (flash_io3)
  );
 
-   wire spiram_csb3 = io_out[13];
+   wire spiram_csb3 = (io_oeb[13] == 1'b0) ? io_out[13] : 1'b0;
 is62wvs1288 #(.mem_file_name("flash3.hex"))
      u_sfram_3 (
       // Data Inputs/Outputs
diff --git a/verilog/dv/user_uart/user_uart_tb.v b/verilog/dv/user_uart/user_uart_tb.v
index 935aa9e..77f5197 100644
--- a/verilog/dv/user_uart/user_uart_tb.v
+++ b/verilog/dv/user_uart/user_uart_tb.v
@@ -246,23 +246,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
-
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -288,8 +287,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/user_uart1/user_uart1_tb.v b/verilog/dv/user_uart1/user_uart1_tb.v
index 2d1c2b2..bbcb183 100644
--- a/verilog/dv/user_uart1/user_uart1_tb.v
+++ b/verilog/dv/user_uart1/user_uart1_tb.v
@@ -247,23 +247,22 @@
 //  user core using the gpio pads
 //  ----------------------------------------------------
 
-   wire flash_clk = io_out[28];
-   wire flash_csb = io_out[29];
+   wire flash_clk = (io_oeb[28] == 1'b0) ? io_out[28]: 1'b0;
+   wire flash_csb = (io_oeb[29] == 1'b0) ? io_out[29]: 1'b0;
    // Creating Pad Delay
-   wire #1 io_oeb_29 = io_oeb[33];
-   wire #1 io_oeb_30 = io_oeb[34];
-   wire #1 io_oeb_31 = io_oeb[35];
-   wire #1 io_oeb_32 = io_oeb[36];
-   tri  #1 flash_io0 = (io_oeb_29== 1'b0) ? io_out[33] : 1'bz;
-   tri  #1 flash_io1 = (io_oeb_30== 1'b0) ? io_out[34] : 1'bz;
-   tri  #1 flash_io2 = (io_oeb_31== 1'b0) ? io_out[35] : 1'bz;
-   tri  #1 flash_io3 = (io_oeb_32== 1'b0) ? io_out[36] : 1'bz;
+   wire #1 io_oeb_33 = io_oeb[33];
+   wire #1 io_oeb_34 = io_oeb[34];
+   wire #1 io_oeb_35 = io_oeb[35];
+   wire #1 io_oeb_36 = io_oeb[36];
+   tri  #1 flash_io0 = (io_oeb_33== 1'b0) ? io_out[33] : 1'bz;
+   tri  #1 flash_io1 = (io_oeb_34== 1'b0) ? io_out[34] : 1'bz;
+   tri  #1 flash_io2 = (io_oeb_35== 1'b0) ? io_out[35] : 1'bz;
+   tri  #1 flash_io3 = (io_oeb_36== 1'b0) ? io_out[36] : 1'bz;
 
-   assign io_in[33] = flash_io0;
-   assign io_in[34] = flash_io1;
-   assign io_in[35] = flash_io2;
-   assign io_in[36] = flash_io3;
-
+   assign io_in[33] = (io_oeb[33] == 1'b1) ? flash_io0: 1'b0;
+   assign io_in[34] = (io_oeb[34] == 1'b1) ? flash_io1: 1'b0;
+   assign io_in[35] = (io_oeb[35] == 1'b1) ? flash_io2: 1'b0;
+   assign io_in[36] = (io_oeb[36] == 1'b1) ? flash_io3: 1'b0;
 
    // Quard flash
      s25fl256s #(.mem_file_name(`TB_HEX),
@@ -289,8 +288,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[10];
-assign io_in[8]  = uart_rxd ;
+assign uart_txd   = (io_oeb[10] == 1'b0) ? io_out[10]: 1'b0;
+assign io_in[8]   = (io_oeb[8] == 1'b1)  ? uart_rxd  : 1'b0;
  
 uart_agent tb_uart(
 	.mclk                (clock              ),
diff --git a/verilog/dv/user_uart_master/user_uart_master_tb.v b/verilog/dv/user_uart_master/user_uart_master_tb.v
index 57d6802..b6134c0 100644
--- a/verilog/dv/user_uart_master/user_uart_master_tb.v
+++ b/verilog/dv/user_uart_master/user_uart_master_tb.v
@@ -210,8 +210,8 @@
 // --------------------------
 wire uart_txd,uart_rxd;
 
-assign uart_txd   = io_out[7];
-assign io_in[6]  = uart_rxd ;
+assign uart_txd   = (io_oeb[7] == 1'b0) ? io_out[7] : 1'b0;
+assign io_in[6]   = (io_oeb[6] == 1'b1) ? uart_rxd  : 1'b0;
  
 uart_agent tb_master_uart(
 	.mclk                (clock              ),
diff --git a/verilog/includes/includes.rtl.caravel_user_project b/verilog/includes/includes.rtl.caravel_user_project
index 4c5f2f6..ea8cb5d 100644
--- a/verilog/includes/includes.rtl.caravel_user_project
+++ b/verilog/includes/includes.rtl.caravel_user_project
@@ -14,6 +14,7 @@
 -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/semaphore_reg.sv
 -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/strap_ctrl.sv
 -v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/glbl_rst_reg.sv
+-v $(USER_PROJECT_VERILOG)/rtl/pinmux/src/pseudorandom.sv
 -v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_top.sv
 -v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_dglicth.sv
 -v $(USER_PROJECT_VERILOG)/rtl/gpio/src/gpio_intr.sv
@@ -178,3 +179,15 @@
 $(USER_PROJECT_VERILOG)/rtl/rtc/verilog/rtl/core/rtc_core.sv
 $(USER_PROJECT_VERILOG)/rtl/rtc/verilog/rtl/core/rtc_reg.sv
 
+-v $(USER_PROJECT_VERILOG)/rtl/lib/sync_fifo_occ.sv
+-v $(USER_PROJECT_VERILOG)/rtl/lib/prescaler.v
+-v $(USER_PROJECT_VERILOG)/rtl/lib/metastability_filter.sv
+-v $(USER_PROJECT_VERILOG)/rtl/lib/pulse_filter.sv
+
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_rx.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_frame_decoder.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_event_catcher.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_regs.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_div8.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_tx.sv
+$(USER_PROJECT_VERILOG)/rtl/nec_ir/src/nec_ir_top.sv
diff --git a/verilog/rtl/lib/clk_skew_adjust.gv b/verilog/rtl/lib/clk_skew_adjust.gv
index fc811c0..40655c9 100644
--- a/verilog/rtl/lib/clk_skew_adjust.gv
+++ b/verilog/rtl/lib/clk_skew_adjust.gv
@@ -157,24 +157,25 @@
   ctech_delay_clkbuf clkbuf_15 (.A(clk_d14),   .X(clk_d15));
 
 
-  // Tap point selection
-  assign in0  = clk_in;
-  assign in1  = clk_d1;
-  assign in2  = clk_d2;
-  assign in3  = clk_d3;
-  assign in4  = clk_d4;
-  assign in5  = clk_d5;
-  assign in6  = clk_d6;
-  assign in7  = clk_d7;
-  assign in8  = clk_d8;
-  assign in9  = clk_d9;
-  assign in10 = clk_d10;
-  assign in11 = clk_d11;
-  assign in12 = clk_d12;
-  assign in13 = clk_d13;
-  assign in14 = clk_d14;
-  assign in15 = clk_d15;
+   
 
+  // Tap point selection
+  ctech_clk_buf u_tap_0  (.A(clk_in),  .X(in0));
+  ctech_clk_buf u_tap_1  (.A(clk_d1),  .X(in1));
+  ctech_clk_buf u_tap_2  (.A(clk_d2),  .X(in2));
+  ctech_clk_buf u_tap_3  (.A(clk_d3),  .X(in3));
+  ctech_clk_buf u_tap_4  (.A(clk_d4),  .X(in4));
+  ctech_clk_buf u_tap_5  (.A(clk_d5),  .X(in5));
+  ctech_clk_buf u_tap_6  (.A(clk_d6),  .X(in6));
+  ctech_clk_buf u_tap_7  (.A(clk_d7),  .X(in7));
+  ctech_clk_buf u_tap_8  (.A(clk_d8),  .X(in8));
+  ctech_clk_buf u_tap_9  (.A(clk_d9),  .X(in9));
+  ctech_clk_buf u_tap_10 (.A(clk_d10), .X(in10));
+  ctech_clk_buf u_tap_11 (.A(clk_d11), .X(in11));
+  ctech_clk_buf u_tap_12 (.A(clk_d12), .X(in12));
+  ctech_clk_buf u_tap_13 (.A(clk_d13), .X(in13));
+  ctech_clk_buf u_tap_14 (.A(clk_d14), .X(in14));
+  ctech_clk_buf u_tap_15 (.A(clk_d15), .X(in15));
 
   // first level mux - 8
   ctech_mux2x1_2 u_mux_level_00 ( .X (d00) , .A0 (in0),  .A1(in1),  .S(sel[0]));
diff --git a/verilog/rtl/lib/metastability_filter.sv b/verilog/rtl/lib/metastability_filter.sv
new file mode 100644
index 0000000..ede8339
--- /dev/null
+++ b/verilog/rtl/lib/metastability_filter.sv
@@ -0,0 +1,44 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2022 , Julien OURY
+//
+// 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 Julien OURY <julien.oury@outlook.fr>
+//
+////////////////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Metastability filter
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+module metastability_filter #(
+  parameter NB_STAGES = 3
+)(
+  input  wire  rst_n      , // Asynchronous reset (active low)
+  input  wire  clk        , // Clock (rising edge)
+
+  input  wire  i_raw      , // Raw input
+  output wire  o_filtered   // Filtered output
+);
+
+  reg [NB_STAGES-1:0]  meta_i;
+
+  always @(negedge rst_n or posedge clk) begin
+    if (rst_n == 1'b0) begin
+      meta_i <= 'b0;
+    end else begin
+      meta_i <= {meta_i[NB_STAGES-2: 0],i_raw};
+    end
+  end
+  assign o_filtered = meta_i[NB_STAGES-1];
+
+endmodule
diff --git a/verilog/rtl/lib/prescaler.v b/verilog/rtl/lib/prescaler.v
new file mode 100644
index 0000000..860cbe0
--- /dev/null
+++ b/verilog/rtl/lib/prescaler.v
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2022 , Julien OURY
+//
+// 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 Julien OURY <julien.oury@outlook.fr>
+//
+////////////////////////////////////////////////////////////////////////////
+
+module prescaler #(
+  parameter BITS = 32
+)(
+  input  wire            rst_n      , // Asynchronous reset (active low)
+  input  wire            clk        , // Clock (rising edge)
+  input  wire            clear_n    , // Synchronous reset (active low)
+
+  input  wire [BITS-1:0] multiplier , // frequency multiplier
+  input  wire [BITS-1:0] divider    , // frequency divider
+
+  output reg             tick         // output clock [Ftick=Fclk*(multiplier/divider)] with multiplier <= divider
+
+);
+
+  reg [BITS-1:0] div;
+  reg [BITS-1:0] mul;
+  reg [BITS-1:0] div_m_mul;
+  reg [BITS-1:0] mul_m_div;
+  reg [BITS-1:0] counter;
+
+  always @(negedge rst_n or posedge clk) begin
+    if (rst_n == 1'b0) begin
+	  mul       <= {(BITS){1'b0}};
+      div       <= {(BITS){1'b0}};
+	  div_m_mul <= {(BITS){1'b0}};
+      mul_m_div <= {(BITS){1'b0}};
+      counter   <= {(BITS){1'b0}};
+      tick      <= 1'b0;
+    end else begin
+      if (clear_n == 1'b0) begin
+        counter   <= {(BITS){1'b0}};
+        tick      <= 1'b0;
+      end else begin
+        if (counter > div_m_mul) begin
+          counter <= counter + mul_m_div;
+          tick    <= 1'b1;
+        end else begin
+          counter <= counter + mul;
+          tick    <= 1'b0;
+        end
+      end
+	  mul       <= multiplier;
+      div       <= divider   ;
+	  div_m_mul <= div - mul ;
+      mul_m_div <= mul - div ;
+    end
+  end
+
+endmodule
diff --git a/verilog/rtl/lib/pulse_filter.sv b/verilog/rtl/lib/pulse_filter.sv
new file mode 100644
index 0000000..f5f251d
--- /dev/null
+++ b/verilog/rtl/lib/pulse_filter.sv
@@ -0,0 +1,60 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2022 , Julien OURY
+//
+// 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 Julien OURY <julien.oury@outlook.fr>
+//
+////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+// Pulse filter
+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+module pulse_filter (
+  input  wire  rst_n      , // Asynchronous reset (active low)
+  input  wire  clk        , // Clock (rising edge)
+  input  wire  clear_n  , // Synchronous reset (active low)
+
+  input  wire  i_value    , // Input value
+  input  wire  i_valid    , // Input valid strobe
+
+  output wire  o_value    , // Output value
+  output reg   o_valid      // Output valid strobe
+);
+
+  reg [2:0]  filter_reg;
+
+  always @(negedge rst_n or posedge clk) begin
+    if (rst_n == 1'b0) begin
+      filter_reg <= 'b0;
+      o_valid    <= 1'b0;
+    end else begin
+      if (clear_n == 1'b0) begin
+          filter_reg <= 'b0;
+          o_valid    <= 1'b0;
+      end else begin
+        if (i_valid == 1'b1) begin
+          filter_reg[2] <= i_value;
+          filter_reg[1] <= filter_reg[2];
+          filter_reg[0] <= filter_reg[1];
+          o_valid       <= 1'b1;
+        end else begin
+          o_valid       <= 1'b0;
+        end
+      end
+    end
+  end
+
+  assign o_value = (filter_reg[0] & filter_reg[1]) |
+                   (filter_reg[1] & filter_reg[2]) |
+                   (filter_reg[2] & filter_reg[0]) ;
+endmodule
diff --git a/verilog/rtl/lib/simple_fifo.v b/verilog/rtl/lib/simple_fifo.v
new file mode 100644
index 0000000..9440924
--- /dev/null
+++ b/verilog/rtl/lib/simple_fifo.v
@@ -0,0 +1,86 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , Julien OURY

+//

+// 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 Julien OURY <julien.oury@outlook.fr>

+//

+////////////////////////////////////////////////////////////////////////////

+module simple_fifo #(

+  parameter ASIZE =  5 , // FIFO size (FIFO_size=(2**ASIZE)-1)

+  parameter DSIZE = 32   // Number of bits of data

+)(

+  input  wire             rst_n   , // Asynchronous reset (active low)

+  input  wire             clk     , // Clock (rising edge)

+  input  wire             clear_n , // Synchronous clear (active low)

+

+  // Write port

+  input  wire [DSIZE-1:0] wr_data ,

+  input  wire             wr_valid,

+  output wire             wr_ready, // Ready flag (0: FIFO full, 1: FIFO not full)

+

+  // Read port

+  output wire [DSIZE-1:0] rd_data ,

+  output wire             rd_valid,

+  input  wire             rd_ready  // Ready flag (0: FIFO empty, 1: FIFO not empty)

+);

+

+  wire [ASIZE-1:0]    rd_ptr_next         ;

+  wire [ASIZE-1:0]    wr_ptr_next         ;

+  reg  [ASIZE-1:0]    rd_ptr              ;

+  reg  [ASIZE-1:0]    wr_ptr              ;

+  reg  [DSIZE-1:0]    memory[2**ASIZE-1:0];

+

+  assign wr_ptr_next = wr_ptr + 1'b1;

+  assign rd_ptr_next = rd_ptr + 1'b1;

+

+  assign wr_ready = (wr_ptr_next != rd_ptr);

+  assign rd_valid = (rd_ptr != wr_ptr);

+

+  // Write pointer update

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      wr_ptr <= 'b0;

+    end else begin

+      if (clear_n == 1'b0) begin

+        wr_ptr <= 'b0;

+      end else if (wr_valid && wr_ready) begin

+        wr_ptr <= wr_ptr_next;

+      end

+    end

+  end

+

+  // Write operation

+  always @(posedge clk) begin

+    if (wr_valid && wr_ready) begin

+      memory[wr_ptr] <= wr_data;

+    end

+  end

+

+  // Read pointer update

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      rd_ptr <= 'b0;

+    end else begin

+      if (clear_n == 1'b0) begin

+        rd_ptr <= 'b0;

+      end else if (rd_valid && rd_ready) begin

+        rd_ptr <= rd_ptr_next;

+      end

+    end

+  end

+

+  // Read operation

+  assign rd_data = memory[rd_ptr];

+

+endmodule

diff --git a/verilog/rtl/lib/sync_fifo_occ.sv b/verilog/rtl/lib/sync_fifo_occ.sv
new file mode 100755
index 0000000..e842e91
--- /dev/null
+++ b/verilog/rtl/lib/sync_fifo_occ.sv
@@ -0,0 +1,161 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+/*********************************************************************
+                                                              
+  Description: SYNC FIFO with Occupancy
+  Parameters:
+      WD : Width (integer)
+      DP : Depth (integer, power of 2, 4 to 256)
+                                                              
+  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 sync_fifo_occ  #(parameter WD = 8,parameter DP = 4,
+                        parameter AW = (DP == 2)   ? 1 :
+	                                   (DP == 4)   ? 2 :
+		                               (DP == 8)   ? 3 :
+		                               (DP == 16)  ? 4 :
+		                               (DP == 32)  ? 5 :
+		                               (DP == 64)  ? 6 :
+		                               (DP == 128) ? 7 :
+		                               (DP == 256) ? 8 : 0) (
+
+       input  logic          clk          , // Clock
+	   input  logic          reset_n      , // Reset
+       input  logic          sreset_n     , // Synchronous Reset
+	   input  logic	         wr_en        , // FIFO Write enable
+	   input  logic [WD-1:0] wr_data      , // FIFO Write Data
+	   output logic 	     full         , // FIFO Full
+       output logic	         empty        , // FIFO Empty
+	   input  logic	         rd_en        , // FIFO Read enable
+	   output logic [WD-1:0] rd_data      , // FIFO Read Data
+       output logic [AW:0]   occupancy      // Show the current FIFO occpancy
+                     );
+
+
+   
+
+   // synopsys translate_off
+
+   initial begin
+      if (AW == 0) begin
+	 $display ("%m : ERROR!!! Fifo depth %d not in range 4 to 256", DP);
+      end // if (AW == 0)
+   end // initial begin
+
+   // synopsys translate_on
+
+
+   reg [WD-1 : 0]   mem[DP-1 : 0];
+   reg [AW-1 : 0]   rd_ptr, wr_ptr;
+
+
+   assign empty =  (occupancy == 0);  
+   assign full  =  (occupancy == DP);  
+
+   // occpuancy computation
+   always @ (posedge clk or negedge reset_n) 
+      if (reset_n == 1'b0) begin
+         occupancy <= 'h0;
+      end else if(sreset_n == 1'b0) begin
+         occupancy <= 'h0;
+      end else begin
+         if ((wr_en & !full) && (rd_en == 1'b0 )) begin // Write Only
+            occupancy <= occupancy + 1'b1 ;
+         end else if ((rd_en & !empty) && (wr_en == 1'b0 )) begin // Read Only
+            occupancy <= occupancy - 1'b1 ;
+         end
+      end
+
+   
+   always @ (posedge clk or negedge reset_n) 
+      if (reset_n == 1'b0) begin
+         wr_ptr <= {AW{1'b0}} ;
+      end else if(sreset_n == 1'b0) begin
+         wr_ptr <= {AW{1'b0}} ;
+      end else begin 
+         if (wr_en & !full) begin
+            wr_ptr <= wr_ptr + 1'b1 ;
+         end
+      end
+
+   always @ (posedge clk or negedge reset_n) 
+      if (reset_n == 1'b0) begin
+         rd_ptr <= {AW{1'b0}} ;
+      end else if(sreset_n == 1'b0) begin
+         rd_ptr <= {AW{1'b0}} ;
+      end else begin
+         if (rd_en & !empty) begin
+            rd_ptr <= rd_ptr + 1'b1 ;
+         end
+      end
+
+   always @ (posedge clk) 
+      if (wr_en)
+	       mem[wr_ptr] <= wr_data;
+
+assign  rd_data = mem[rd_ptr];
+
+
+// synopsys translate_off
+   always @(posedge clk) begin
+      if (wr_en && full) begin
+         $display("%m : Error! sfifo overflow!");
+      end
+   end
+
+   always @(posedge clk) begin
+      if (rd_en && empty) begin
+         $display("%m : error! sfifo underflow!");
+      end
+   end
+
+// synopsys translate_on
+//---------------------------------------
+
+endmodule
+
+
diff --git a/verilog/rtl/nec_ir/src/nec_div8.sv b/verilog/rtl/nec_ir/src/nec_div8.sv
new file mode 100644
index 0000000..a4c2fe8
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_div8.sv
@@ -0,0 +1,46 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+// tick div8 block
+//////////////////////////////////////////////////////////////////////
+
+module nec_div8 (
+       input  logic   rst_n        , // Asynchronous reset (active low)
+       input  logic   clk          , // Clock (rising edge)
+       input  logic   tick         ,
+       output logic   tick_div8     
+
+    );
+
+
+  logic [2:0] cnt;
+  always @(negedge rst_n or posedge clk) begin
+    if (rst_n == 1'b0) begin
+      cnt       <= '0;
+      tick_div8 <= 'b0;
+    end else begin
+       if(tick) cnt <= cnt + 1;
+       if(cnt == 7 && tick) tick_div8 <= 1'b1;
+       else tick_div8 <= 1'b0;
+
+    end
+  end
+    
+
+
+endmodule   
diff --git a/verilog/rtl/nec_ir/src/nec_ir_event_catcher.sv b/verilog/rtl/nec_ir/src/nec_ir_event_catcher.sv
new file mode 100644
index 0000000..46d5201
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_event_catcher.sv
@@ -0,0 +1,99 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , Julien OURY

+//

+// 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 Julien OURY <julien.oury@outlook.fr>

+//

+////////////////////////////////////////////////////////////////////////////

+

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+// Event catcher

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+module nec_ir_event_catcher #(

+  parameter DBITS = 32 // Number of bits of delay counter

+)(

+  input  wire             rst_n         , // Asynchronous reset (active low)

+  input  wire             clk           , // Clock (rising edge)

+  input  wire             clear_n       , // Synchronous reset (active low)

+  input  wire [DBITS-1:0] reload_offset , // Delay counter reload offset

+

+  input  wire             i_value       , // Input value

+  input  wire             i_valid       , // Input valid strobe

+

+  output reg              event_new     ,

+  output reg              event_type    ,

+  output reg  [DBITS-1:0] event_delay   ,

+  output reg              event_timeout

+);

+

+  wire detect_event;

+  wire [DBITS-1:0] next_cnt;

+  wire full_cnt;

+

+  reg last_value;

+  reg [DBITS-1:0] cnt;

+

+  assign detect_event = (i_value != last_value);

+  assign next_cnt     = cnt + 1'b1;

+  assign full_cnt     = (cnt == {DBITS{1'b1}});

+

+  // Event catcher

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      last_value    <= 1'b0;

+      cnt           <= {DBITS{1'b1}};

+      event_new     <= 1'b0;

+      event_type    <= 1'b0;

+      event_delay   <= {DBITS{1'b0}};

+      event_timeout <= 1'b0;

+    end else begin

+

+    if (clear_n == 1'b0) begin

+        last_value    <= 1'b0;

+        cnt           <= {DBITS{1'b1}};

+        event_new     <= 1'b0;

+        event_type    <= 1'b0;

+        event_delay   <= {DBITS{1'b0}};

+        event_timeout <= 1'b0;

+    end else begin

+

+        if (i_valid == 1'b1) begin

+

+          //event detect

+          last_value <= i_value;

+

+          //counter update

+          if (detect_event == 1'b1) begin

+            cnt <= reload_offset;

+          end else if (!full_cnt) begin

+            cnt <= next_cnt;

+          end

+        end

+

+        //report event

+        if ((i_valid == 1'b1) && (detect_event == 1'b1)) begin

+          event_new     <= 1'b1;

+          event_type    <= i_value; // 1: rising_edge, 0: falling_edge

+          event_delay   <= next_cnt;

+          event_timeout <= full_cnt;

+        end else begin

+          event_new     <= 1'b0;

+        end

+

+    end

+

+    end

+  end

+

+endmodule

diff --git a/verilog/rtl/nec_ir/src/nec_ir_frame_decoder.sv b/verilog/rtl/nec_ir/src/nec_ir_frame_decoder.sv
new file mode 100644
index 0000000..129f816
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_frame_decoder.sv
@@ -0,0 +1,176 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , Julien OURY

+//

+// 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 Julien OURY <julien.oury@outlook.fr>

+//

+////////////////////////////////////////////////////////////////////////////

+

+

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+// Frame decoder

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+module nec_ir_frame_decoder #(

+  parameter DBITS = 32 // Number of bits of delay counter

+)(

+  input  wire  rst_n                    , // Asynchronous reset (active low)

+  input  wire  clk                      , // Clock (rising edge)

+

+  input  wire             receiver_en   , // Receiver enable

+  input  wire             repeat_en     , // Repeat enable

+  input  wire [DBITS-1:0] delay_mask    , // Mask delay

+

+  // Input event interface

+  input  wire             event_new     , // New event strobe

+  input  wire             event_type    , // Type of event (0:rising, 1:falling)

+  input  wire [DBITS-1:0] event_delay   , // Delay from last event

+  input  wire             event_timeout , // Timeout flag

+

+  // Output frame interface

+  output reg  [7:0]       frame_addr    , // Frame address

+  output reg  [7:0]       frame_data    , // Frame data

+  output reg              frame_repeat  , // Frame repeat flag

+  output reg              frame_write     // Frame write strobe

+);

+

+  localparam

+    idle_state        = 3'b000,

+    start_state       = 3'b001,

+    data_prefix_state = 3'b010,

+    data_latch_state  = 3'b011,

+    stop_state        = 3'b100,

+    idle_a_state      = 3'b101,

+    idle_b_state      = 3'b110,

+    idle_c_state      = 3'b111;

+

+  reg [2:0] frame_state_reg ;

+  wire is_valid_start_a     ;

+  wire is_valid_start_b     ;

+  wire is_valid_repeat      ;

+  wire is_valid_bit_prefix  ;

+  wire is_valid_bit_zero    ;

+  wire is_valid_bit_one     ;

+  wire is_valid_bit         ;

+  wire is_valid_stop        ;

+  wire is_valid_addr        ;

+  wire is_valid_data        ;

+

+  reg [31:0] frame_shift    ;

+  reg        initial_timeout;

+

+  assign is_valid_start_a    = ((event_timeout == 1'b0) && (event_type == 1'b0) && ((event_delay & delay_mask) == 128)); // 9.00ms pulse to 1'b1

+  assign is_valid_start_b    = ((event_timeout == 1'b0) && (event_type == 1'b1) && ((event_delay & delay_mask) ==  64)); // 4.50ms pulse to 1'b0

+  assign is_valid_repeat     = ((event_timeout == 1'b0) && (event_type == 1'b1) && ((event_delay & delay_mask) ==  32) && (initial_timeout == 0)); // 2.25ms pulse to 1'b0

+  assign is_valid_bit_prefix = ((event_timeout == 1'b0) && (event_type == 1'b0) && ((event_delay & delay_mask) ==   8));

+  assign is_valid_bit_zero   = ((event_timeout == 1'b0) && (event_type == 1'b1) && ((event_delay & delay_mask) ==   8));

+  assign is_valid_bit_one    = ((event_timeout == 1'b0) && (event_type == 1'b1) && ((event_delay & delay_mask) ==  24));

+  assign is_valid_bit        = (is_valid_bit_zero || is_valid_bit_one);

+  assign is_valid_stop       = ((event_timeout == 1'b0) && (event_type == 1'b0) && ((event_delay & delay_mask) ==   8));

+  assign is_valid_addr       = ((frame_shift[7:0] == ~frame_shift[15:8]));

+  assign is_valid_data       = ((frame_shift[23:16] == ~frame_shift[31:24]));

+

+  // Frame decoder

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      frame_state_reg  <= idle_state;

+      frame_shift      <= 32'h80000000;

+      frame_repeat     <= 1'b0;

+      frame_write      <= 1'b0;

+      frame_addr       <= 8'h00;

+      frame_data       <= 8'h00;

+    end else begin

+

+      if (receiver_en == 1'b0) begin

+        frame_state_reg <= idle_state;

+        initial_timeout <= 1'b1;

+        frame_shift     <= 32'h80000000;

+        frame_repeat    <= 1'b0;

+      end else begin

+        if (event_new == 1'b1) begin

+          case(frame_state_reg)

+            idle_state,

+            idle_a_state,

+            idle_b_state,

+            idle_c_state:

+              if(is_valid_start_a) begin

+                frame_state_reg <= start_state;

+              end

+            start_state:

+              if (is_valid_start_b) begin

+                frame_state_reg <= data_prefix_state;

+              end else if (repeat_en && is_valid_repeat) begin

+                frame_state_reg <= stop_state;

+              end else begin

+                frame_state_reg <= idle_state;

+              end

+            data_prefix_state:

+              if (is_valid_bit_prefix) begin

+                frame_state_reg <= data_latch_state;

+              end else begin

+                frame_state_reg <= idle_state;

+              end

+            data_latch_state:

+              if (is_valid_bit) begin

+                if (frame_shift[0] == 1'b1) begin

+                  frame_state_reg <= stop_state;

+                end else begin

+                  frame_state_reg <= data_prefix_state;

+                end

+              end else begin

+                frame_state_reg <= idle_state;

+              end

+            stop_state:

+              frame_state_reg <= idle_state;

+            default:

+              frame_state_reg <= idle_state;

+            endcase

+

+          if ((frame_state_reg == idle_state) && (event_timeout == 1'b1)) begin

+            initial_timeout <= 1'b1;

+          end else if ((frame_state_reg == stop_state) && is_valid_stop && is_valid_addr && is_valid_data && (frame_repeat == 0)) begin

+            initial_timeout <= 1'b0;

+          end

+

+          if ((frame_state_reg == start_state) && is_valid_start_b) begin

+            frame_shift <= 32'h80000000;

+          end else if (frame_state_reg == data_latch_state) begin

+            if (is_valid_bit_zero) begin

+              frame_shift <= {1'b0, frame_shift[31:1]};

+            end else begin

+              frame_shift <= {1'b1, frame_shift[31:1]};

+            end

+          end

+

+          if (frame_state_reg == start_state) begin

+            if (repeat_en && is_valid_repeat) begin

+              frame_repeat <= 1'b1;

+            end else begin

+              frame_repeat <= 1'b0;

+            end

+          end

+

+        end

+

+        if ((receiver_en == 1'b1) && (event_new == 1'b1) && (frame_state_reg == stop_state) && is_valid_stop && is_valid_addr && is_valid_data) begin

+          frame_write <= 1'b1;

+          frame_addr  <= frame_shift[7:0];

+          frame_data  <= frame_shift[23:16];

+        end else begin

+          frame_write <= 1'b0;

+        end

+      end

+    end

+  end

+

+endmodule

diff --git a/verilog/rtl/nec_ir/src/nec_ir_regs.sv b/verilog/rtl/nec_ir/src/nec_ir_regs.sv
new file mode 100644
index 0000000..dff5ca9
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_regs.sv
@@ -0,0 +1,246 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , <Julien OURY/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 Julien OURY <julien.oury@outlook.fr>

+// and Dinesh Annayya <dinesh.annayya@gmail.com>

+//

+////////////////////////////////////////////////////////////////////////////

+/**********************************************************************

+                                                              

+          NEC IR Register

+                                                                      

+          This file is part of the riscduino cores project            

+          https://github.com/dineshannayya/riscduino.git              

+                                                                      

+                                                                      

+          To Do:                                                      

+            nothing                                                   

+                                                                      

+          Author(s): 

+              - Julien OURY <julien.oury@outlook.fr>                                                 

+              - Dinesh Annayya <dinesh.annayya@gmail.com>

+                                                                      

+          Revision :                                                  

+            0.1 - 11 Dec 2022, Dinesh A                               

+                  initial version picked from 

+                  https://github.com/JulienOury/ChristmasTreeController                                    

+            0.2 - 13 Dec 2022, Dinesh A

+                  A. Bug fix, Read access clearing the register content

+                  B. FIFO Occpancy added

+                  C. Support for IR Transmitter

+                     

+***************************************************************************/

+

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+// Registers

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+module nec_ir_regs #(

+  parameter PSIZE = 32 , // Size of prescaler counter(bits)

+  parameter DSIZE = 32 , // Size of delay counter (bits)

+  parameter ASIZE = 3    // MEMORY ADDRESS POINTER SIZE

+)(

+

+  input logic               rst_n             , // Asynchronous reset (active low)

+  input logic               clk               , // Clock (rising edge)

+

+  // Configuration

+  output logic              cfg_ir_en         , // IR Global Enable

+  output logic              cfg_ir_tx_en      , // Transmitter enable

+  output logic              cfg_ir_rx_en      , // Receiver enable

+  output logic              cfg_repeat_en     , // Repeat enable

+  output logic              cfg_tx_polarity   , // Polarity (value of idle state)

+  output logic              cfg_rx_polarity   , // Polarity (value of idle state)

+  output logic  [PSIZE-1:0] cfg_multiplier    , // frequency multiplier

+  output logic  [PSIZE-1:0] cfg_divider       , // frequency divider

+  output logic  [DSIZE-1:0] reload_offset     , // Delay counter reload offset

+  output logic  [DSIZE-1:0] delay_mask        , // Mask delay

+

+  // Wishbone bus

+  input  logic              wbs_cyc_i         , // Wishbone strobe/request

+  input  logic              wbs_stb_i         , // Wishbone strobe/request

+  input  logic [4:0]        wbs_adr_i         , // Wishbone address

+  input  logic              wbs_we_i          , // Wishbone write (1:write, 0:read)

+  input  logic [31:0]       wbs_dat_i         , // Wishbone data output

+  input  logic [ 3:0]       wbs_sel_i         , // Wishbone byte enable

+  output logic  [31:0]      wbs_dat_o         , // Wishbone data input

+  output logic              wbs_ack_o         , // Wishbone acknowlegement

+

+  // Input frame interface

+  // <IR RECEIVER> => <RX FIFO> => WB

+  input  logic             rx_frame_new       , // New frame received

+  input  logic             fifo_rx_full       , // RX FIFO full

+  input  logic [16:0]      fifo_rx_rdata      , // RX FIFO Read Data

+  output logic             fifo_rx_read       , // RX FIFO Read

+  input  logic [ASIZE:0]   fifo_rx_occ        , // RX FIFO Occupancy

+

+  // <WB> => <TX FIFO> =>  <IR Transmitter>

+  input  logic             fifo_tx_full       , // Tx FIFO full

+  output logic [15:0]      fifo_tx_wdata      , // TX FIFO Wdata

+  output logic             fifo_tx_write      , // TX FIFO Write

+  input  logic [ASIZE:0]   fifo_tx_occ        , // FIFO TX Occpancy

+

+  // Interrupt

+  output reg              irq               // Interrupt

+

+ );

+

+  localparam

+    IR_CFG_CMD          = 3'b000,

+    IR_CFG_MULTIPLIER   = 3'b001,

+    IR_CFG_DIVIDER      = 3'b010,

+    IR_CFG_RX_DATA      = 3'b011,

+    IR_CFG_TX_DATA      = 3'b100;

+

+

+  logic        valid;

+  logic        rstrb;

+  logic [2:0]  addr;

+

+  logic  [1:0]  cfg_tolerance;

+  logic         cfg_irq_en;

+  logic         frame_lost;

+  logic         ready;

+

+

+  assign valid     = wbs_cyc_i && wbs_stb_i;

+  assign rstrb     = ~wbs_we_i;

+  assign addr      = wbs_adr_i[4:2];

+  assign wbs_ack_o = ready;

+

+  wire [7:0] rx_frame_data   = fifo_rx_rdata[7:0];

+  wire [7:0] rx_frame_addr   = fifo_rx_rdata[15:8];

+  wire       rx_frame_repeat = fifo_rx_rdata[16];

+  wire       fifo_rx_available = (fifo_rx_occ > 0);

+

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      ready       <= 1'b0;

+      wbs_dat_o   <= 'h0;

+      cfg_tolerance   <= 2'b01;

+      cfg_multiplier  <= {PSIZE{1'b0}};

+      cfg_divider     <= {PSIZE{1'b0}};

+      cfg_ir_en       <= 1'b0;

+      cfg_ir_tx_en    <= 1'b0;

+      cfg_ir_rx_en    <= 1'b0;

+      cfg_repeat_en   <= 1'b0;

+      cfg_irq_en      <= 1'b0;

+      cfg_tx_polarity <= 1'b0;

+      cfg_rx_polarity <= 1'b0;

+      frame_lost      <= 1'b0;

+      irq             <= 1'b0;

+      fifo_tx_write   <= 1'b0;

+      fifo_rx_read    <= 1'b0;

+    end else begin

+

+      if (valid && !ready) begin

+

+        //Write

+        case (addr)

+          IR_CFG_CMD : begin

+            wbs_dat_o[31]   <= cfg_ir_en        ; if (wbs_sel_i[3] && wbs_we_i) cfg_ir_en       <= wbs_dat_i[31];

+            wbs_dat_o[30]   <= cfg_ir_tx_en     ; if (wbs_sel_i[3] && wbs_we_i) cfg_ir_tx_en    <= wbs_dat_i[30];

+            wbs_dat_o[29]   <= cfg_ir_rx_en     ; if (wbs_sel_i[3] && wbs_we_i) cfg_ir_rx_en    <= wbs_dat_i[29];

+            wbs_dat_o[28]   <= cfg_repeat_en    ; if (wbs_sel_i[3] && wbs_we_i) cfg_repeat_en   <= wbs_dat_i[28];

+            wbs_dat_o[27]   <= cfg_irq_en       ; if (wbs_sel_i[3] && wbs_we_i) cfg_irq_en      <= wbs_dat_i[27];

+            wbs_dat_o[26]   <= cfg_rx_polarity  ; if (wbs_sel_i[3] && wbs_we_i) cfg_rx_polarity <= wbs_dat_i[26];

+            wbs_dat_o[25]   <= cfg_tx_polarity  ; if (wbs_sel_i[3] && wbs_we_i) cfg_tx_polarity <= wbs_dat_i[25];

+            wbs_dat_o[24]   <= cfg_tolerance[1] ; if (wbs_sel_i[3] && wbs_we_i) cfg_tolerance[1]<= wbs_dat_i[24];

+            wbs_dat_o[23]   <= cfg_tolerance[0] ; if (wbs_sel_i[2] && wbs_we_i) cfg_tolerance[0]<= wbs_dat_i[23];

+            wbs_dat_o[22:8] <= 'b0;

+            wbs_dat_o[7:4]  <= fifo_tx_occ;

+            wbs_dat_o[3:0]  <= fifo_rx_occ;

+          end

+          IR_CFG_MULTIPLIER : begin

+             wbs_dat_o    <= cfg_multiplier;

+            if(wbs_sel_i[0] && wbs_we_i) cfg_multiplier[7:0]   <= wbs_dat_i[7:0];

+            if(wbs_sel_i[1] && wbs_we_i) cfg_multiplier[15:8]  <= wbs_dat_i[15:8];

+            if(wbs_sel_i[2] && wbs_we_i) cfg_multiplier[23:16] <= wbs_dat_i[23:16];

+            if(wbs_sel_i[3] && wbs_we_i) cfg_multiplier[31:24] <= wbs_dat_i[31:24];

+          end

+          IR_CFG_DIVIDER : begin

+            wbs_dat_o <= cfg_divider;

+            if(wbs_sel_i[0] && wbs_we_i) cfg_divider[7:0]   <= wbs_dat_i[7:0];

+            if(wbs_sel_i[1] && wbs_we_i) cfg_divider[15:8]  <= wbs_dat_i[15:8];

+            if(wbs_sel_i[2] && wbs_we_i) cfg_divider[23:16] <= wbs_dat_i[23:16];

+            if(wbs_sel_i[3] && wbs_we_i) cfg_divider[31:24] <= wbs_dat_i[31:24];

+          end

+          IR_CFG_RX_DATA : begin

+             if (fifo_rx_available == 1'b1 && !wbs_we_i) begin

+               wbs_dat_o[31]    <= 1'b1;

+               wbs_dat_o[30]    <= rx_frame_repeat;

+               wbs_dat_o[29]    <= frame_lost;

+               wbs_dat_o[28:16] <= 13'b0;

+               wbs_dat_o[15:8]  <= rx_frame_addr;

+               wbs_dat_o[7:0]   <= rx_frame_data;

+               fifo_rx_read     <= 1'b0;

+             end else begin

+               wbs_dat_o[31:0]  <= 'b0;

+             end

+          end

+          IR_CFG_TX_DATA : begin

+             if (fifo_tx_full == 1'b0 && wbs_we_i) begin

+                fifo_tx_wdata <= wbs_dat_i[15:0];

+                fifo_tx_write <= 1'b1;

+             end 

+          end

+          default:  wbs_dat_o[31:0]  <= 'b0;

+        endcase

+

+        ready <= 1'b1;

+      end else begin

+        fifo_tx_write <= 1'b0;

+        fifo_rx_read  <= 1'b0;

+        ready <= 1'b0;

+      end

+

+      if ((rx_frame_new == 1'b1) && (fifo_rx_full == 1'b1)) begin

+         frame_lost <= 1'b1;

+      end else if (valid && !ready && rstrb && (addr == IR_CFG_RX_DATA)) begin

+         frame_lost <= 1'b0;

+      end

+

+      if (valid && !ready && rstrb && (addr == IR_CFG_RX_DATA) && fifo_rx_available) begin

+         fifo_rx_read <= 1'b1;

+      end else begin

+         fifo_rx_read <= 1'b0;

+      end

+

+      if ((cfg_irq_en == 1'b1) && (rx_frame_new == 1'b1)) begin

+         irq <= 1'b1;

+      end else begin

+         irq <= 1'b0;

+      end

+

+    end

+  end

+

+  always @(*) begin

+    case (cfg_tolerance)

+      2'b00 : begin

+        reload_offset = {{(DSIZE-3){1'b0}}, 3'b001};

+        delay_mask    = {{(DSIZE-3){1'b1}}, 3'b110};

+      end

+      2'b01 : begin

+        reload_offset = {{(DSIZE-3){1'b0}}, 3'b010};

+        delay_mask    = {{(DSIZE-3){1'b1}}, 3'b100};

+      end

+      default : begin

+        reload_offset = {{(DSIZE-3){1'b0}}, 3'b100};

+        delay_mask    = {{(DSIZE-3){1'b1}}, 3'b000};

+      end

+    endcase

+  end

+

+endmodule

diff --git a/verilog/rtl/nec_ir/src/nec_ir_rx.sv b/verilog/rtl/nec_ir/src/nec_ir_rx.sv
new file mode 100644
index 0000000..0444ef8
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_rx.sv
@@ -0,0 +1,144 @@
+////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2022 , <Julien OURY/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 Julien OURY <julien.oury@outlook.fr>
+// and Dinesh Annayya <dinesh.annayya@gmail.com>
+//
+////////////////////////////////////////////////////////////////////////////
+/**********************************************************************
+                                                              
+          NEC IR RX                                                  
+                                                                      
+          This file is part of the riscduino cores project            
+          https://github.com/dineshannayya/riscduino.git              
+                                                                      
+          Description:                                                 
+              This block integrate
+                A. metastability_filter
+                B. pulse_filter
+                C. nec_ir_event_catcher
+                                                                      
+          To Do:                                                      
+            nothing                                                   
+                                                                      
+          Author(s): 
+              - Julien OURY <julien.oury@outlook.fr>                                                 
+              - Dinesh Annayya <dinesh.annayya@gmail.com>
+                                                                      
+          Revision :                                                  
+            0.1 - 11 Dec 2022, Dinesh A                               
+                  initial version picked from 
+                  https://github.com/JulienOury/ChristmasTreeController                                    
+***************************************************************************/
+
+module nec_ir_rx #(
+  parameter NB_STAGES =  3          , // Number of metastability filter stages
+  parameter PSIZE     = 32          , // Size of prescaler counter(bits)
+  parameter DSIZE     = 32          , // Size of delay counter (bits)
+  parameter ASIZE     =  3            // FIFO size (FIFO_size=(2**ASIZE)-1)
+)(
+
+  input  logic             rst_n         , // Asynchronous reset (active low)
+  input  logic             clk           , // Clock (rising edge)
+
+  input  logic             ir_rx         ,
+  input  logic             tick8         ,
+  input  logic             cfg_receiver_en   ,
+  input  logic             cfg_polarity  , 
+  input  logic             cfg_repeat_en     ,
+  input  logic [DSIZE-1:0] reload_offset ,
+  input  logic [DSIZE-1:0] delay_mask    ,
+ 
+  output logic[16:0]       fifo_rx_wdata    ,
+  output logic             fifo_rx_write    
+
+);
+
+  logic [DSIZE-1:0] event_delay    ;
+  wire             ir_meta_f       ;
+  wire             ir_meta         ;
+  wire             value           ;
+  wire             new_sample      ;
+  wire             event_new       ;
+  wire             event_type      ;
+  wire             event_timeout   ;
+  wire [7:0]       frame_addr      ;
+  wire [7:0]       frame_data      ;
+  wire             frame_repeat    ;
+
+  metastability_filter #(
+    .NB_STAGES(NB_STAGES)
+  ) i_metastability_filter (
+    .rst_n      (rst_n      ),
+    .clk        (clk        ),
+    .i_raw      (ir_rx      ),
+    .o_filtered (ir_meta_f  )
+  );
+
+  // Invert polarity if needed
+  assign ir_meta = (cfg_polarity==0) ? ir_meta_f : ~ir_meta_f;
+
+  pulse_filter i_pulse_filter (
+    .rst_n   (rst_n      ),
+    .clk     (clk        ),
+    .clear_n (cfg_receiver_en),
+    .i_value (ir_meta    ),
+    .i_valid (tick8      ),
+    .o_value (value      ),
+    .o_valid (new_sample )
+  );
+
+  nec_ir_event_catcher #(
+    .DBITS(DSIZE)
+  ) i_event_catcher (
+    .rst_n         (rst_n        ),
+    .clk           (clk          ),
+    .clear_n       (cfg_receiver_en  ),
+    .reload_offset (reload_offset),
+    .i_value       (value        ),
+    .i_valid       (new_sample   ),
+    .event_new     (event_new    ),
+    .event_type    (event_type   ),
+    .event_delay   (event_delay  ),
+    .event_timeout (event_timeout)
+  );
+
+  nec_ir_frame_decoder #(
+    .DBITS(DSIZE)
+  ) i_frame_decoder (
+    .rst_n         (rst_n        ),
+    .clk           (clk          ),
+
+    .receiver_en   (cfg_receiver_en  ),
+    .repeat_en     (cfg_repeat_en    ),
+    .delay_mask    (delay_mask   ),
+
+    // Input event interface
+    .event_new     (event_new    ),
+    .event_type    (event_type   ),
+    .event_delay   (event_delay  ),
+    .event_timeout (event_timeout),
+
+    // Output frame interface
+    .frame_addr    (frame_addr   ),
+    .frame_data    (frame_data   ),
+    .frame_repeat  (frame_repeat ),
+    .frame_write   (fifo_rx_write  )
+  );
+
+  assign       fifo_rx_wdata = {frame_repeat, frame_addr, frame_data};
+
+
+endmodule
diff --git a/verilog/rtl/nec_ir/src/nec_ir_top.sv b/verilog/rtl/nec_ir/src/nec_ir_top.sv
new file mode 100644
index 0000000..badae10
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_top.sv
@@ -0,0 +1,312 @@
+

+//////////////////////////////////////////////////////////////////////////////

+// 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>

+//

+//////////////////////////////////////////////////////////////////////

+/**********************************************************************

+                                                              

+          NEC IR Top                                                  

+                                                                      

+          This file is part of the riscduino cores project            

+          https://github.com/dineshannayya/riscduino.git              

+                                                                      

+          Description:                                                 

+              This block integrate

+                A. NEC IR Transmitter

+                B. NEC IR Reciver

+                C. Prescalar

+                D. Register Block

+                E. FIFO Block

+                                                                      

+          To Do:                                                      

+            nothing                                                   

+                                                                      

+          Author(s):                                                  

+              - Dinesh Annayya, dinesh.annayya@gmail.com                 

+                                                                      

+          Revision :                                                  

+            0.1 - 11 Dec 2022, Dinesh A                               

+                  initial version                                     

+            0.2 - 13 Dec 2022, Dinesh A

+                  A. Bug fix, Read access clearing the register content

+                  B. FIFO Occpancy added

+                  C. Support for IR Transmitter

+***************************************************************************/

+/*************************************************************************************

+Documentation Collection by Dinesh-A - dinesh.annayya@gmail.com

+Reference: https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol

+

+The NEC IR transmission protocol uses pulse distance encoding of the message bits. Each pulse burst (mark – RC transmitter ON) is 

+562.5µs in length, at a carrier frequency of 38kHz (26.3µs). Logical bits are transmitted as follows:

+    Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms

+    Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms

+

+

+When a key is pressed on the remote controller, the message transmitted consists of the following, in order:

+

+    * 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)

+    * 4.5ms space

+    * the 8-bit address for the receiving device

+    * the 8-bit logical inverse of the address

+    * the 8-bit command

+    * the 8-bit logical inverse of the command

+    * final 562.5µs pulse burst to signify the end of message transmission.

+

+Repeat Codes

+

+If the key on the remote controller is kept depressed, a repeat code will be issued, typically around 40ms after 

+the pulse burst that signified the end of the message. A repeat code will continue to be sent out at 108ms intervals, 

+until the key is finally released. The repeat code consists of the following, in order:

+

+    * 9ms leading pulse burst

+    * 2.25ms space

+    * 562.5µs pulse burst to mark the end of the space (and hence end of the transmitted repeat code).

+

+

+

+*************************************************************************************/

+

+module nec_ir_top #(

+  parameter NB_STAGES =  3     , // Number of metastability filter stages

+  parameter PSIZE     = 32     , // Size of prescaler counter(bits)

+  parameter DSIZE     = 32     , // Size of delay counter (bits)

+  parameter ASIZE     =  3     , // FIFO size (FIFO_size=(2**ASIZE)-1)

+  parameter DP        =  8       // FIFO DEPTH = 2**SIZE

+)(

+

+  input  logic        rst_n     , // Asynchronous reset (active low)

+  input  logic        clk       , // Clock (rising edge)

+

+  // Wishbone bus

+  input  logic        wbs_cyc_i , // Wishbone strobe/request

+  input  logic        wbs_stb_i , // Wishbone strobe/request

+  input  logic [4:0]  wbs_adr_i , // Wishbone address

+  input  logic        wbs_we_i  , // Wishbone write (1:write, 0:read)

+  input  logic [31:0] wbs_dat_i , // Wishbone data output

+  input  logic [3:0]  wbs_sel_i , // Wishbone byte enable

+  output logic [31:0] wbs_dat_o , // Wishbone data input

+  output logic        wbs_ack_o , // Wishbone acknowlegement

+

+  input  logic        ir_rx     ,

+  output logic       ir_tx     ,

+

+  output logic        irq         // Interrupt

+

+);

+

+//-----------------------------------------------

+// Reg Interface

+//------------------------------------------------

+  logic             cfg_ir_en          ;

+  logic             cfg_ir_tx_en       ;

+  logic             cfg_ir_rx_en       ;

+  logic             cfg_repeat_en      ;

+  logic             cfg_tx_polarity       ;

+  logic             cfg_rx_polarity       ;

+  logic [PSIZE-1:0] cfg_multiplier     ;

+  logic [PSIZE-1:0] cfg_divider        ;

+  logic [DSIZE-1:0] reload_offset      ;

+  logic [DSIZE-1:0] delay_mask         ;

+

+//---------------------------------------------

+// Prescal Output

+//----------------------------------------------

+  logic             tick8              ; // 562.5µs/8 Pulse

+  logic             tick1              ; // 562.5µs pulse

+

+//---------------------------------------------

+// FIFO RX I/F

+// <IR RECEIVER> => <RX FIFO> => WB

+//----------------------------------------------

+  logic             fifo_rx_full       ;

+  logic             fifo_rx_empty      ;

+  logic             fifo_rx_write      ;

+  logic [16:0]      fifo_rx_wdata      ;

+  logic [16:0]      fifo_rx_rdata      ;

+  logic             fifo_rx_read       ;

+  logic [ASIZE:0]   fifo_rx_occ        ;

+

+//---------------------------------------------

+// FIFO TX I/F

+// <WB> => <TX FIFO> =>  <IR Transmitter>

+//----------------------------------------------

+  logic             fifo_tx_full       ;

+  logic             fifo_tx_empty      ;

+  logic             fifo_tx_write      ;

+  logic [15:0]      fifo_tx_wdata      ;

+  logic [15:0]      fifo_tx_rdata      ;

+  logic             fifo_tx_read       ;

+  logic [ASIZE:0]   fifo_tx_occ        ;

+

+// ---   Prescaler   ---

+  prescaler #(

+    .BITS(PSIZE)

+  ) i_prescaler (

+    .rst_n           (rst_n                 ),

+    .clk             (clk                   ),

+    .clear_n         (cfg_ir_en             ),

+    .multiplier      (cfg_multiplier        ),

+    .divider         (cfg_divider           ),

+    .tick            (tick8                 )

+  );

+

+// ---   Register   ---

+

+  nec_ir_regs #(

+    .PSIZE(PSIZE),

+    .DSIZE(DSIZE),

+    .ASIZE(ASIZE)

+  ) i_ir_regs (

+    .rst_n             (rst_n              ),

+    .clk               (clk                ),

+

+   // Configuration

+    .cfg_ir_en         (cfg_ir_en          ),

+    .cfg_ir_tx_en      (cfg_ir_tx_en       ),

+    .cfg_ir_rx_en      (cfg_ir_rx_en       ),

+    .cfg_repeat_en     (cfg_repeat_en      ),

+    .cfg_tx_polarity   (cfg_tx_polarity    ),

+    .cfg_rx_polarity   (cfg_rx_polarity    ),

+    .cfg_multiplier    (cfg_multiplier     ),

+    .cfg_divider       (cfg_divider        ),

+    .reload_offset     (reload_offset      ),

+    .delay_mask        (delay_mask         ),

+

+    // Wishbone bus

+    .wbs_cyc_i         (wbs_cyc_i          ),

+    .wbs_stb_i         (wbs_stb_i          ),

+    .wbs_adr_i         (wbs_adr_i          ),

+    .wbs_we_i          (wbs_we_i           ),

+    .wbs_dat_i         (wbs_dat_i          ),

+    .wbs_sel_i         (wbs_sel_i          ),

+    .wbs_dat_o         (wbs_dat_o          ),

+    .wbs_ack_o         (wbs_ack_o          ),

+

+   // <IR RECEIVER> => <RX FIFO> => WB

+    .rx_frame_new      (fifo_rx_write      ),

+    .fifo_rx_full      (fifo_rx_full       ),

+    .fifo_rx_rdata     (fifo_rx_rdata      ),

+    .fifo_rx_read      (fifo_rx_read       ),

+    .fifo_rx_occ       (fifo_rx_occ        ),

+

+  // <WB> => <TX FIFO> =>  <IR Transmitter>

+    .fifo_tx_full      (fifo_tx_full       ),

+    .fifo_tx_wdata     (fifo_tx_wdata      ),

+    .fifo_tx_write     (fifo_tx_write      ),

+    .fifo_tx_occ       (fifo_tx_occ        ),

+

+    // Interrupt

+    .irq               (irq               )

+

+  );

+

+

+// ---  RX FIFO   ---

+

+  sync_fifo_occ #(

+    .DP(DP),

+    .WD(17),

+    .AW(ASIZE)

+  ) i_rx_fifo (

+    .reset_n     (rst_n                ),

+    .clk         (clk                  ),

+    .sreset_n    (cfg_ir_en            ),

+    .wr_data     (fifo_rx_wdata        ),

+    .wr_en       (fifo_rx_write        ),

+    .full        (fifo_rx_full         ),

+    .empty       (fifo_rx_empty        ),

+    .rd_data     (fifo_rx_rdata        ),

+    .rd_en       (fifo_rx_read         ),

+    .occupancy   (fifo_rx_occ          )

+  );

+

+

+// ---   IR Receiver  ---

+

+nec_ir_rx #(

+      .NB_STAGES (NB_STAGES), // Number of metastability filter stages

+      .PSIZE     (PSIZE    ), // Size of prescaler counter(bits)

+      .DSIZE     (DSIZE    ), // Size of delay counter (bits)

+      .ASIZE     (ASIZE    )  // FIFO size (FIFO_size=(2**ASIZE)-1)

+) u_ir_rx (

+

+  .rst_n             (rst_n                ), // Asynchronous reset (active low)

+  .clk               (clk                  ), // Clock (rising edge)

+                                  

+  .ir_rx             (ir_rx                ),

+  .tick8             (tick8                ),

+  .cfg_receiver_en   (cfg_ir_rx_en         ),

+  .cfg_polarity      (cfg_rx_polarity      ), 

+  .cfg_repeat_en     (cfg_repeat_en        ),

+  .reload_offset     (reload_offset        ),

+  .delay_mask        (delay_mask           ),

+  .fifo_rx_wdata     (fifo_rx_wdata        ),

+  .fifo_rx_write     (fifo_rx_write        ) 

+

+);

+

+// ---  IR Transmitter ----

+

+// Div8 module

+nec_div8 u_div8 (

+       .rst_n         (rst_n                ), // Asynchronous reset (active low)

+       .clk           (clk                  ), // Clock (rising edge)

+       .tick          (tick8                ),

+       .tick_div8     (tick1                )

+    );

+

+

+nec_ir_tx u_ir_tx(

+  .rst_n         (rst_n                ), // Asynchronous reset (active low)

+  .clk           (clk                  ), // Clock (rising edge)

+

+  // Configuration Input

+  .tx_en         (cfg_ir_tx_en         ), // Transmitter enable

+  .tx_event      (tick1                ), // Transmit event at every 562.5µs 

+  .p_polarity    (cfg_tx_polarity      ),

+

+  // FIFO Interface

+  .fifo_valid    (!fifo_tx_empty       ),  

+  .fifo_tx_rdata (fifo_tx_rdata        ),

+  .fifo_read     (fifo_tx_read         ),

+

+  // To Pad

+  .ir_tx          (ir_tx               )     

+

+);

+

+// ---  TX FIFO   ---

+

+  sync_fifo_occ #(

+    .DP(DP),

+    .WD(16),

+    .AW(ASIZE)

+  ) i_tx_fifo (

+    .reset_n     (rst_n                ),

+    .clk         (clk                  ),

+    .sreset_n    (cfg_ir_en            ),

+    .wr_data     (fifo_tx_wdata        ),

+    .wr_en       (fifo_tx_write        ),

+    .full        (fifo_tx_full         ),

+    .empty       (fifo_tx_empty        ),

+    .rd_data     (fifo_tx_rdata        ),

+    .rd_en       (fifo_tx_read         ),

+    .occupancy   (fifo_tx_occ          )

+  );

+

+

+endmodule

diff --git a/verilog/rtl/nec_ir/src/nec_ir_tx.sv b/verilog/rtl/nec_ir/src/nec_ir_tx.sv
new file mode 100644
index 0000000..077e6e3
--- /dev/null
+++ b/verilog/rtl/nec_ir/src/nec_ir_tx.sv
@@ -0,0 +1,212 @@
+
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya                          
+// 
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//      http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+/**********************************************************************
+                                                              
+          NEC IR Transmitter                                                  
+                                                                      
+          This file is part of the riscduino cores project            
+          https://github.com/dineshannayya/riscduino.git              
+                                                                      
+          To Do:                                                      
+            nothing                                                   
+                                                                      
+          Author(s):                                                  
+              - Dinesh Annayya, dinesh.annayya@gmail.com                 
+                                                                      
+          Revision :                                                  
+            0.1 - 12 Dec 2022, Dinesh A                               
+                  initial version                                     
+***************************************************************************/
+
+/************************************************
+https://techdocs.altium.com/display/FPGA/NEC+Infrared+Transmission+Protocol
+The NEC IR transmission protocol uses pulse distance encoding of the message bits. Each pulse burst (mark – RC transmitter ON) is 562.5µs in length, 
+at a carrier frequency of 38kHz (26.3µs). Logical bits are transmitted as follows:
+
+    Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
+    Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
+
+When a key is pressed on the remote controller, the message transmitted consists of the following, in order:
+
+    * 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
+    * 4.5ms space
+    * the 8-bit address for the receiving device
+    * the 8-bit logical inverse of the address
+    * the 8-bit command
+    * the 8-bit logical inverse of the command
+    * final 562.5µs pulse burst to signify the end of message transmission.
+
+*************************************************************************************************************/
+
+
+module nec_ir_tx (
+  input  logic         rst_n          , // Asynchronous reset (active low)
+  input  logic         clk            , // Clock (rising edge)
+
+  // Configuration Input
+  input  logic         tx_en          , // Transmitter enable
+  input  logic         tx_event       , // Transmit event at every 562.5µs 
+  input  logic         p_polarity     ,
+
+  // FIFO Interface
+  input  logic         fifo_valid     ,  
+  input  logic  [15:0] fifo_tx_rdata  , // Frame address
+  output logic         fifo_read      ,
+
+  // To Pad
+  output logic         ir_tx      
+
+);
+
+
+// FSM STATE
+parameter S_IDLE            = 3'b000;
+parameter S_START_BURST     = 3'b001;
+parameter S_START_SPACE     = 3'b010;
+parameter S_DATA_BURST      = 3'b011;
+parameter S_DATA_SPACE      = 3'b100;
+parameter S_STOP            = 3'b101;
+
+// Data Phase
+parameter P_TX_ADDR     = 2'b00;
+parameter P_TX_INV_ADDR = 2'b01;
+parameter P_TX_DATA     = 2'b10;
+parameter P_TX_INV_DATA = 2'b11;
+
+logic [7:0] tx_data;
+logic [2:0] s_state;
+logic [1:0] s_data_phase;
+logic [3:0] tick_cnt;
+logic [2:0] bit_cnt;
+
+wire [7:0] addr_cmd = fifo_tx_rdata[15:8];
+wire [7:0] data_cmd = fifo_tx_rdata[7:0];
+
+
+assign tx_data = (s_data_phase ==  P_TX_ADDR)     ? addr_cmd  :     // Transmit Address
+                 (s_data_phase ==  P_TX_INV_ADDR) ? ~addr_cmd :     // logical inverse of the address
+                 (s_data_phase ==  P_TX_DATA)     ? data_cmd  :     // Transmit Data 
+                 (s_data_phase ==  P_TX_INV_DATA) ? ~data_cmd :     // logical inverse of the data
+                 'h0;
+
+
+always @(negedge rst_n or posedge clk) begin
+   if (rst_n == 1'b0) begin
+      ir_tx       <= 0;
+      tick_cnt    <= 0;
+      bit_cnt     <= 0;
+      fifo_read   <= 0;
+      s_data_phase <= P_TX_ADDR;
+      s_state     <= S_IDLE;
+   end else begin
+      if (tx_en == 1'b0) begin
+        s_state   <= S_IDLE;
+        ir_tx     <= ~p_polarity;
+        tick_cnt  <= 0;
+        bit_cnt   <= 0;
+        fifo_read <= 0;
+      end else if (tx_event == 1'b1) begin
+         case(s_state        )
+            S_IDLE: begin
+               if(fifo_valid == 1'b1) begin
+                  s_state         <= S_START_BURST;
+                  ir_tx           <= p_polarity;
+                  tick_cnt        <= 0;
+               end else begin
+                  ir_tx           <= ~p_polarity;
+               end
+            end
+            // 9ms leading pulse burst (16 times the pulse burst length used for a logical data bit)
+            S_START_BURST: begin
+               if(tick_cnt == 15) begin
+                  ir_tx           <= ~p_polarity;
+                  s_state         <= S_START_SPACE;
+                  tick_cnt        <= 0;
+               end else begin
+                  tick_cnt <= tick_cnt + 1;
+               end
+            end
+            // 4.5ms space
+            S_START_SPACE: begin
+               if(tick_cnt == 7) begin
+                  ir_tx           <= p_polarity;
+                  s_state         <= S_DATA_BURST;
+                  tick_cnt        <= 0;
+                  bit_cnt         <= 0;
+                  s_data_phase    <= P_TX_ADDR;
+               end else begin
+                  tick_cnt <= tick_cnt + 1;
+               end
+            end
+            S_DATA_BURST: begin
+               ir_tx           <=  ~p_polarity;
+               s_state         <=  S_DATA_SPACE;
+               tick_cnt       <= 0;
+            end
+            S_DATA_SPACE: begin
+                  //Logical '0' – a 562.5µs pulse burst followed by a 562.5µs space, with a total transmit time of 1.125ms
+                  //Logical '1' – a 562.5µs pulse burst followed by a 1.6875ms space, with a total transmit time of 2.25ms
+                  if(tx_data[bit_cnt] == 1'b1 && tick_cnt == 2) begin
+                     ir_tx     <= p_polarity;
+                     if(bit_cnt == 7) begin
+                         case(s_data_phase)
+                         P_TX_ADDR:     begin s_data_phase <= P_TX_INV_ADDR; s_state <= S_DATA_BURST; end
+                         P_TX_INV_ADDR: begin s_data_phase <= P_TX_DATA;     s_state <= S_DATA_BURST; end
+                         P_TX_DATA:     begin s_data_phase <= P_TX_INV_DATA; s_state <= S_DATA_BURST; end
+                         P_TX_INV_DATA: begin fifo_read    <= 1;             s_state <= S_STOP;       end
+                         endcase
+                         bit_cnt  <= 0;
+                     end else begin
+                        bit_cnt   <= bit_cnt+1;
+                        s_state   <=  S_DATA_BURST;
+                     end
+                  end else if(tx_data[bit_cnt] == 1'b0 && tick_cnt == 0) begin
+                     ir_tx     <= p_polarity;
+                     if(bit_cnt == 7) begin
+                         case(s_data_phase)
+                         P_TX_ADDR:     begin s_data_phase <= P_TX_INV_ADDR; s_state  <= S_DATA_BURST; end
+                         P_TX_INV_ADDR: begin s_data_phase <= P_TX_DATA;     s_state  <= S_DATA_BURST; end
+                         P_TX_DATA:     begin s_data_phase <= P_TX_INV_DATA; s_state  <= S_DATA_BURST; end
+                         P_TX_INV_DATA: begin fifo_read    <= 1;             s_state  <= S_STOP;       end
+                         endcase
+                         bit_cnt  <= 0;
+                     end else begin
+                        bit_cnt   <= bit_cnt+1;
+                        s_state    <=  S_DATA_BURST;
+                     end
+                  end else begin
+                      tick_cnt <= tick_cnt+1;
+                  end
+            end
+            S_STOP: begin
+               ir_tx           <=  ~p_polarity;
+               fifo_read       <=  0;
+               s_state         <=  S_IDLE;
+            end
+            default : s_state         <=  S_IDLE;
+         endcase
+      end else begin
+         fifo_read       <=  0;
+      end
+   end
+end
+
+
+endmodule
diff --git a/verilog/rtl/peripheral/src/peri_top.sv b/verilog/rtl/peripheral/src/peri_top.sv
index 352d0b4..8fadc5d 100755
--- a/verilog/rtl/peripheral/src/peri_top.sv
+++ b/verilog/rtl/peripheral/src/peri_top.sv
@@ -71,6 +71,11 @@
 
                        output logic            inc_time_s,
                        output logic            inc_date_d,
+
+                       // IR Receiver I/F
+                       input  logic            ir_rx,
+                       output logic            ir_tx,
+                       output logic            ir_intr,
                
                       // DAC Config
                        output logic [7:0]      cfg_dac0_mux_sel,
@@ -97,14 +102,21 @@
 logic         reg_rtc_ack;
 logic         reg_rtc_cs;
 
+logic [31:0]  reg_ir_rdata;
+logic         reg_ir_ack;
+logic         reg_ir_cs;
+
 assign reg_rdata  = (reg_addr[10:7] == `SEL_D2A) ? reg_d2a_rdata :
                     (reg_addr[10:7] == `SEL_RTC) ? reg_rtc_rdata :
+                    (reg_addr[10:7] == `SEL_IR)  ? reg_ir_rdata :
                      'h0;
 assign reg_ack    = (reg_addr[10:7] == `SEL_D2A) ? reg_d2a_ack   :
                     (reg_addr[10:7] == `SEL_RTC) ? reg_rtc_ack   :
+                    (reg_addr[10:7] == `SEL_IR)  ? reg_ir_ack   :
                     1'b0;
 assign reg_d2a_cs = (reg_addr[10:7] == `SEL_D2A)  ? reg_cs : 1'b0;
 assign reg_rtc_cs = (reg_addr[10:7] == `SEL_RTC)  ? reg_cs : 1'b0;
+assign reg_ir_cs  = (reg_addr[10:7] == `SEL_IR)  ? reg_cs : 1'b0;
 
 
 // peri clock skew control
@@ -181,6 +193,32 @@
 
          );
 
+//--------------------------------------------------------------------------
+// IR Receiver
+//--------------------------------------------------------------------------
+
+nec_ir_top i_ir (
+
+              .rst_n                    (s_reset_ssn                ), 
+              .clk                      (mclk                       ), 
+
+              // Wishbone bus
+              .wbs_cyc_i                (reg_ir_cs                  ), 
+              .wbs_stb_i                (reg_ir_cs                  ), 
+              .wbs_adr_i                (reg_addr[4:0]              ),
+              .wbs_we_i                 (reg_wr                     ),
+              .wbs_dat_i                (reg_wdata                  ),
+              .wbs_sel_i                (reg_be                     ),
+              .wbs_dat_o                (reg_ir_rdata               ),
+              .wbs_ack_o                (reg_ir_ack                 ),
+
+              .ir_rx                    (ir_rx                      ),
+              .ir_tx                    (ir_tx                      ),
+
+              .irq                      (ir_intr                    )  
+
+);
+
 endmodule 
 
 
diff --git a/verilog/rtl/pinmux/src/glbl_reg.sv b/verilog/rtl/pinmux/src/glbl_reg.sv
index 28c315c..91a4140 100644
--- a/verilog/rtl/pinmux/src/glbl_reg.sv
+++ b/verilog/rtl/pinmux/src/glbl_reg.sv
@@ -95,6 +95,7 @@
 		               input  logic            i2cm_intr              ,
 		               input  logic            pwm_intr              ,
 		               input  logic            rtc_intr              ,
+		               input  logic            ir_intr                ,
 
 		               output logic [15:0]     cfg_riscv_ctrl         ,
                        output  logic [31:0]    cfg_multi_func_sel     ,// multifunction pins
@@ -137,6 +138,7 @@
 logic [31:0]   reg_6;  // 
 logic [31:0]   reg_7;  // 
 logic [31:0]   reg_8;  // 
+logic [31:0]   reg_9;  // Random Number
 logic [31:0]   reg_12; // Latched Strap 
 logic [31:0]   reg_13; // Strap Sticky
 logic [31:0]   reg_14; // System Strap
@@ -372,16 +374,19 @@
 logic usb_intr_s,usb_intr_ss;   // Usb Interrupt Double Sync
 logic i2cm_intr_s,i2cm_intr_ss; // I2C Interrupt Double Sync
 logic rtc_intr_s,rtc_intr_ss;
+logic ir_intr_s,ir_intr_ss;
 
 always @ (posedge mclk or negedge s_reset_n)
 begin  
    if (s_reset_n == 1'b0) begin
-     usb_intr_s   <= 'h0;
-     usb_intr_ss  <= 'h0;
-     i2cm_intr_s  <= 'h0;
-     i2cm_intr_ss <= 'h0;
-     rtc_intr_s  <= 'h0;
-     rtc_intr_ss <= 'h0;
+     usb_intr_s       <= 'h0;
+     usb_intr_ss      <= 'h0;
+     i2cm_intr_s      <= 'h0;
+     i2cm_intr_ss     <= 'h0;
+     rtc_intr_s       <= 'h0;
+     rtc_intr_ss      <= 'h0;
+     ir_intr_s        <= 'h0;
+     ir_intr_ss       <= 'h0;
    end else begin
      usb_intr_s   <= usb_intr;
      usb_intr_ss  <= usb_intr_s;
@@ -389,10 +394,13 @@
      i2cm_intr_ss <= i2cm_intr_s;
      rtc_intr_s   <= rtc_intr;
      rtc_intr_ss  <= rtc_intr_s;
+
+     ir_intr_s   <= ir_intr;
+     ir_intr_ss  <= ir_intr_s;
    end
 end
 
-wire [31:0] hware_intr_req = {gpio_intr[31:8], 1'b0,rtc_intr_ss,pwm_intr,usb_intr_ss, i2cm_intr_ss,timer_intr[2:0]};
+wire [31:0] hware_intr_req = {gpio_intr[31:8], ir_intr_ss,rtc_intr_ss,pwm_intr,usb_intr_ss, i2cm_intr_ss,timer_intr[2:0]};
 
 generic_intr_stat_reg #(.WD(32),
 	                .RESET_DEFAULT(0)) u_reg4 (
@@ -493,6 +501,16 @@
 assign    cfg_dc_trim      = reg_8[25:0];
 
 
+//------------------------------------------
+// reg_9: Random Number Generator
+//------------------------------------------
+pseudorandom u_random (
+  .rst_n     ( s_reset_n     ), 
+  .clk       ( mclk          ), 
+  .next      ( reg_ack       ), 
+  .random    ( reg_9         )  
+);
+
 
 //-------------------------------------------------
 // Strap control
@@ -674,7 +692,7 @@
     5'b00110 : reg_out [31:0] = reg_6  ;    
     5'b00111 : reg_out [31:0] = reg_7  ;    
     5'b01000 : reg_out [31:0] = reg_8  ;    
-    5'b01001 : reg_out [31:0] = 'h0  ;    
+    5'b01001 : reg_out [31:0] = reg_9  ;    
     5'b01010 : reg_out [31:0] = 'h0 ;   
     5'b01011 : reg_out [31:0] = 'h0 ;   
     5'b01100 : reg_out [31:0] = reg_12 ;   
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
index cfb0312..20342b5 100755
--- a/verilog/rtl/pinmux/src/pinmux.sv
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -52,12 +52,12 @@
 *   Pin-7                       VCC                  -
 *   Pin-8                       GND                  -
 *   Pin-9         20            PB6/WS[1]/XTAL1/TOSC1                       digital_io[11]
-*   Pin-10        21            PB7/WS[1]/XTAL2/TOSC2                       digital_io[12]
+*   Pin-10        21            PB7/WS[1]/XTAL2/TOSC2/IR-RX                 digital_io[12]
 *   Pin-11        5             PD5/WS[2]/SS[3]/OC0B(PWM1)/T1   strap[0]    digital_io[13]
 *   Pin-12        6             PD6/WS[2]/SS[2]/OC0A(PWM2)/AIN0 strap[1]    digital_io[14]/analog_io[2]
-*   Pin-13        7             PD7/WS[2]/A1N1                  strap[2]    digital_io[15]/analog_io[3]
+*   Pin-13        7             PD7/WS[2]/A1N1/IR-TX            strap[2]    digital_io[15]/analog_io[3]
 *   Pin-14        8             PB0/WS[2]/CLKO/ICP1             strap[3]    digital_io[16]
-*   Pin-15        9             PB1/WS[3]/SS[1]OC1A(PWM3)       strap[4]    digital_io[17]
+*   Pin-15        9             PB1/WS[3]/SS[1]/OC1A(PWM3)      strap[4]    digital_io[17]
 *   Pin-16        10            PB2/WS[3]/SS[0]/OC1B(PWM4)      strap[5]    digital_io[18]
 *   Pin-17        11            PB3/WS[3]/MOSI/OC2A(PWM5)       strap[6]    digital_io[19]
 *   Pin-18        12            PB4/WS[3]/MISO                  strap[7]    digital_io[20]
@@ -65,8 +65,8 @@
 *   Pin-20                      AVCC                -
 *   Pin-21                      AREF                                        analog_io[10]
 *   Pin-22                      GND                 -
-*   Pin-23        14            PC0/ADC0                          digital_io[22]/analog_io[11]
-*   Pin-24        15            PC1/ADC1                          digital_io[23]/analog_io[12]
+*   Pin-23        14            PC0/ADC0                                    digital_io[22]/analog_io[11]
+*   Pin-24        15            PC1/ADC1                                    digital_io[23]/analog_io[12]
 *   Pin-25        16            PC2/usb_dp/ADC2                             digital_io[24]/analog_io[13]
 *   Pin-26        17            PC3/usb_dn/ADC3                             digital_io[25]/analog_io[14]
 *   Pin-27        18            PC4/ADC4/SDA                                digital_io[26]/analog_io[15]
@@ -168,7 +168,11 @@
                // WS_281X TXD Port
                input logic [3:0]        ws_txd,
 
-		       input   logic           dbg_clk_mon
+		       input   logic           dbg_clk_mon,
+             
+               // IR Receiver
+               output  logic           ir_rx,
+               input   logic           ir_tx
 
    ); 
 
@@ -189,7 +193,6 @@
 //--------------------------------------------------
 assign pad_strap_in = {digital_io_in[36:29],digital_io_in[20:13] };
 
-assign xtal_clk  = digital_io_in[11];
 
 // GPIO to PORT Mapping
 assign      pad_gpio_in[7:0]     = port_a_in;
@@ -210,6 +213,7 @@
 wire [3:0]  cfg_spim_cs_enb      = cfg_multi_func_sel[14:11];
 wire        cfg_i2cm_enb         = cfg_multi_func_sel[15];
 wire        cfg_usb_enb          = cfg_multi_func_sel[16];
+wire        cfg_ir_tx_enb        = cfg_multi_func_sel[17]; // NEC IR TX Enable
 wire        cfg_muart_enb        = cfg_multi_func_sel[31]; // 1 - uart master enable, 
 
 wire [7:0]  cfg_port_a_dir_sel   = cfg_gpio_dir_sel[7:0];
@@ -242,6 +246,8 @@
      i2cm_data_i= 'h0;
      i2cm_clk_i = 'h0;
      uartm_rxd  = 'b1;
+     xtal_clk   = 'b0;
+     ir_rx      = 'b0;
 
      //Pin-1        PC6/RESET*          digital_io[5]
      port_c_in[6] = digital_io_in[5];
@@ -270,9 +276,11 @@
 
      //Pin-9        PB6/XTAL1/TOSC1     digital_io[11]
      port_b_in[6] = digital_io_in[11];
+     xtal_clk     = digital_io_in[11];
 
-     // Pin-10       PB7/XTAL2/TOSC2     digital_io[12]
+     // Pin-10       PB7/XTAL2/TOSC2/IR-RX  digital_io[12]
      port_b_in[7] = digital_io_in[12];
+     ir_rx        = digital_io_in[12];
 
      //Pin-11       PD5/OC0B(PWM1)/T1   digital_io[13]
      port_d_in[5] = digital_io_in[13];
@@ -280,7 +288,7 @@
      //Pin-12       PD6/OC0A(PWM2)/AIN0 digital_io[14] /analog_io[2]
      port_d_in[6] = digital_io_in[14];
 
-     //Pin-13       PD7/A1N1            digital_io[15]/analog_io[3]
+     //Pin-13       PD7/A1N1/IR-RX      digital_io[15]/analog_io[3]
      port_d_in[7] = digital_io_in[15];
      
      //Pin-14       PB0/CLKO/ICP1       digital_io[16]
@@ -393,8 +401,9 @@
      else if(cfg_port_d_dir_sel[6])  digital_io_out[14]   = port_d_out[6];
 
 
-     //Pin-13       PD7/A1N1/WS[2]            digital_io[15]/analog_io[3]
-     if(cfg_port_d_port_type[7])     digital_io_out[15]  = ws_txd[2];
+     //Pin-13       PD7/A1N1/WS[2]/IR-TX    digital_io[15]/analog_io[3]
+     if(cfg_ir_tx_enb)               digital_io_out[15]  = ir_tx;
+     else if(cfg_port_d_port_type[7])digital_io_out[15]  = ws_txd[2];
      else if(cfg_port_d_dir_sel[7])  digital_io_out[15]  = port_d_out[7];
      
      //Pin-14       PB0/CLKO/WS[2]/ICP1       digital_io[16]
@@ -404,7 +413,7 @@
      //Pin-15       PB1/SS[1]/WS[3]/OC1A(PWM3)      digital_io[17]
      if(cfg_pwm_enb[3])              digital_io_out[17]    = pwm_wfm[3];
      else if(cfg_spim_cs_enb[1])     digital_io_out[17]    = spim_ssn[1];
-     else if(cfg_port_b_port_type[1])digital_io_out[17]  = ws_txd[3];
+     else if(cfg_port_b_port_type[1])digital_io_out[17]    = ws_txd[3];
      else if(cfg_port_b_dir_sel[1])  digital_io_out[17]    = port_b_out[1];
 
      //Pin-16       PB2/SS[0]/WS[3]/OC1B(PWM4)   digital_io[18]
@@ -476,95 +485,96 @@
      digital_io_oen = 38'h3F_FFFF_FFFF;
 
      //Pin-1        PC6/WS[0]/RESET*          digital_io[5]
-     if(cfg_port_c_port_type[6])       digital_io_oen[5]   = 1'b1;
+     if(cfg_port_c_port_type[6])       digital_io_oen[5]   = 1'b0;
      else if(cfg_port_c_dir_sel[6])    digital_io_oen[5]   = 1'b0;
 
      //Pin-2        PD0/WS[0]/MRXD/RXD[0]          digital_io[6]
      if     (cfg_muart_enb)          digital_io_oen[6]   = 1'b1;
      else if(cfg_uart_enb[0])        digital_io_oen[6]   = 1'b1;
-     else if(cfg_port_d_port_type[0])digital_io_oen[6]   = 1'b1;
+     else if(cfg_port_d_port_type[0])digital_io_oen[6]   = 1'b0;
      else if(cfg_port_d_dir_sel[0])  digital_io_oen[6]   = 1'b0;
 
      //Pin-3        PD1/WS[0]/MTXD/TXD[0]          digital_io[7]
      if     (cfg_muart_enb)          digital_io_oen[7]   = 1'b0;
      else if(cfg_uart_enb[0])        digital_io_oen[7]   = 1'b0;
-     else if(cfg_port_d_port_type[1])digital_io_oen[7]   = 1'b1;
+     else if(cfg_port_d_port_type[1])digital_io_oen[7]   = 1'b0;
      else if(cfg_port_d_dir_sel[1])  digital_io_oen[7]   = 1'b0;
 
     //Pin-4        PD2/WS[0]/RXD[1]/INT0      digital_io[8]
      if(cfg_int_enb[0])         digital_io_oen[8]   = 1'b1;
-     else if(cfg_port_d_port_type[2])digital_io_oen[8]   = 1'b1;
+     else if(cfg_port_d_port_type[2])digital_io_oen[8]   = 1'b0;
      else if(cfg_port_d_dir_sel[2])  digital_io_oen[8]   = 1'b0;
 
      //Pin-5        PD3/WS[1]/INT1/OC2B(PWM0)  digital_io[9]
      if(cfg_pwm_enb[0])              digital_io_oen[9]   = 1'b0;
      else if(cfg_int_enb[1])         digital_io_oen[9]   = 1'b1;
-     else if(cfg_port_d_port_type[3])digital_io_oen[9]   = 1'b1;
+     else if(cfg_port_d_port_type[3])digital_io_oen[9]   = 1'b0;
      else if(cfg_port_d_dir_sel[3])  digital_io_oen[9]   = 1'b0;
 
      //Pin-6        PD4/WS[1]/TXD[1]       digital_io[10]
      if   (cfg_uart_enb[1])          digital_io_oen[10]   = 1'b0;
-     else if(cfg_port_d_port_type[4])digital_io_oen[10]   = 1'b1;
+     else if(cfg_port_d_port_type[4])digital_io_oen[10]   = 1'b0;
      else if(cfg_port_d_dir_sel[4])  digital_io_oen[10]   = 1'b0;
 
      //Pin-9        PB6/WS[1]/XTAL1/TOSC1     digital_io[11]
-     if(cfg_port_b_port_type[6])       digital_io_oen[11]   = 1'b1;
+     if(cfg_port_b_port_type[6])       digital_io_oen[11]   = 1'b0;
      else if(cfg_port_b_dir_sel[6])    digital_io_oen[11]   = 1'b0;
 
      // Pin-10       PB7/WS[1]/XTAL2/TOSC2     digital_io[12]
-     if(cfg_port_b_port_type[7])       digital_io_oen[12]   = 1'b1;
+     if(cfg_port_b_port_type[7])       digital_io_oen[12]   = 1'b0;
      else if(cfg_port_b_dir_sel[7])    digital_io_oen[12]   = 1'b0;
 
      //Pin-11       PD5/WS[2]/SS[3]/OC0B(PWM1)/T1   digital_io[13]
      if(cfg_strap_pad_ctrl)          digital_io_oen[13]   = 1'b1;
      else if(cfg_pwm_enb[1])         digital_io_oen[13]   = 1'b0;
      else if(cfg_spim_cs_enb[3])     digital_io_oen[13]   = 1'b0;
-     else if(cfg_port_d_port_type[5])digital_io_oen[13]   = 1'b1;
+     else if(cfg_port_d_port_type[5])digital_io_oen[13]   = 1'b0;
      else if(cfg_port_d_dir_sel[5])  digital_io_oen[13]   = 1'b0;
 
      //Pin-12       PD6/SS[2]/OC0A(PWM2)/AIN0 digital_io[14] /analog_io[2]
      if(cfg_strap_pad_ctrl)          digital_io_oen[14]   = 1'b1;
      else if(cfg_pwm_enb[2])         digital_io_oen[14]   = 1'b0;
      else if(cfg_spim_cs_enb[2])     digital_io_oen[14]   = 1'b0;
-     else if(cfg_port_d_port_type[6])digital_io_oen[14]   = 1'b1;
+     else if(cfg_port_d_port_type[6])digital_io_oen[14]   = 1'b0;
      else if(cfg_port_d_dir_sel[6])  digital_io_oen[14]   = 1'b0;
 
-     //Pin-13       PD7/WS[2]/A1N1            digital_io[15]/analog_io[3]
+     //Pin-13       PD7/A1N1/WS[2]/IR-TX    digital_io[15]/analog_io[3]
      if(cfg_strap_pad_ctrl)          digital_io_oen[15]   = 1'b1;
-     else if(cfg_port_d_port_type[7])digital_io_oen[15]  = 1'b1;
+     else if(cfg_ir_tx_enb)          digital_io_oen[15]   = 1'b0;
+     else if(cfg_port_d_port_type[7])digital_io_oen[15]   = 1'b0;
      else if(cfg_port_d_dir_sel[7])  digital_io_oen[15]  = 1'b0;
      
      //Pin-14       PB0/WS[2]/CLKO/ICP1       digital_io[16]
      if(cfg_strap_pad_ctrl)          digital_io_oen[16]   = 1'b1;
-     else if(cfg_port_b_port_type[0])digital_io_oen[16]  = 1'b1;
+     else if(cfg_port_b_port_type[0])digital_io_oen[16]  = 1'b0;
      else if(cfg_port_b_dir_sel[0])  digital_io_oen[16]  = 1'b0;
 
      //Pin-15       PB1/WS[3]/SS[1]/OC1A(PWM3)      digital_io[17]
      if(cfg_strap_pad_ctrl)          digital_io_oen[17]   = 1'b1;
      else if(cfg_pwm_enb[3])         digital_io_oen[17]  = 1'b0;
      else if(cfg_spim_cs_enb[1])     digital_io_oen[17]  = 1'b0;
-     else if(cfg_port_b_port_type[1])digital_io_oen[17]  = 1'b1;
+     else if(cfg_port_b_port_type[1])digital_io_oen[17]  = 1'b0;
      else if(cfg_port_b_dir_sel[1])  digital_io_oen[17]  = 1'b0;
 
      //Pin-16       PB2/WS[3]/SS[0]/OC1B(PWM4)   digital_io[18]
      if(cfg_strap_pad_ctrl)          digital_io_oen[18]   = 1'b1;
      else if(cfg_pwm_enb[4])         digital_io_oen[18]  = 1'b0;
      else if(cfg_spim_cs_enb[0])     digital_io_oen[18]  = 1'b0;
-	 else if(cfg_port_b_port_type[2])digital_io_oen[18]  = 1'b1;
+	 else if(cfg_port_b_port_type[2])digital_io_oen[18]  = 1'b0;
      else if(cfg_port_b_dir_sel[2])  digital_io_oen[18]  = 1'b0;
 
      //Pin-17       PB3/WS[3]/MOSI/OC2A(PWM5) digital_io[19]
      if(cfg_strap_pad_ctrl)          digital_io_oen[19]   = 1'b1;
      else if(cfg_spim_enb)           digital_io_oen[19]  = 1'b1; // SPIM MOSI (Input)
      else if(cfg_pwm_enb[5])         digital_io_oen[19]  = 1'b0;
-     else if(cfg_port_b_port_type[3])digital_io_oen[19]  = 1'b1;
+     else if(cfg_port_b_port_type[3])digital_io_oen[19]  = 1'b0;
      else if(cfg_port_b_dir_sel[3])  digital_io_oen[19]  = 1'b0;
      else if(spis_boot)              digital_io_oen[19]  = 1'b0; // SPIS MISO (Output)
 
      //Pin-18       PB4/WS[3]/MISO         digital_io[20]
      if(cfg_strap_pad_ctrl)          digital_io_oen[20]  = 1'b1;
      else if(cfg_spim_enb)           digital_io_oen[20]  = 1'b0; // SPIM MISO (Output) 
-     else if(cfg_port_b_port_type[4])digital_io_oen[20]  = 1'b1;
+     else if(cfg_port_b_port_type[4])digital_io_oen[20]  = 1'b0;
      else if(cfg_port_b_dir_sel[4])  digital_io_oen[20]  = 1'b0;
      else if(spis_boot)              digital_io_oen[20]  = 1'b1; // SPIS MOSI (Input)
 
diff --git a/verilog/rtl/pinmux/src/pinmux_top.sv b/verilog/rtl/pinmux/src/pinmux_top.sv
index 0fb87ca..ef2fa83 100755
--- a/verilog/rtl/pinmux/src/pinmux_top.sv
+++ b/verilog/rtl/pinmux/src/pinmux_top.sv
@@ -209,7 +209,13 @@
                input logic [31:0]       reg_peri_rdata,
                input logic              reg_peri_ack,
 
-               input logic              rtc_intr
+               input logic              rtc_intr,
+
+               // IR Receiver I/F
+               output logic             ir_rx,
+               input  logic             ir_tx,
+               input  logic             ir_intr
+
                
    ); 
 
@@ -394,6 +400,7 @@
           .i2cm_intr                    (i2cm_intr               ),
           .pwm_intr                     (pwm_intr                ),
           .rtc_intr                     (rtc_intr                ),
+          .ir_intr                      (ir_intr                 ),
 
 
 
@@ -611,7 +618,10 @@
 
                .ws_txd                  (ws_txd              ),       
                                                    
-		       .dbg_clk_mon             (dbg_clk_mon         )
+		       .dbg_clk_mon             (dbg_clk_mon         ),
+
+               .ir_rx                   (ir_rx               ),
+               .ir_tx                   (ir_tx               )
 
 
    ); 
diff --git a/verilog/rtl/pinmux/src/pseudorandom.sv b/verilog/rtl/pinmux/src/pseudorandom.sv
new file mode 100644
index 0000000..0a27e77
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pseudorandom.sv
@@ -0,0 +1,68 @@
+////////////////////////////////////////////////////////////////////////////

+// SPDX-FileCopyrightText: 2022 , Julien OURY                       

+// 

+// 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 Julien OURY <julien.oury@outlook.fr>

+//

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+// Orginal Reference: https://github.com/JulienOury/ChristmasTreeController.git

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+

+

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+// Xoroshiro64++

+/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

+module pseudorandom (

+  input  wire        rst_n     , // Asynchronous reset (active low)

+  input  wire        clk       , // Clock (rising edge)

+  input  wire        next      , // Request next value

+  output wire [31:0] random      // Random value

+);

+  reg  [31:0] s0;

+  reg  [31:0] s1;

+  reg  [31:0] n0;

+  reg  [31:0] n1;

+  reg  [31:0] n1_plus_n0;

+  wire [31:0] s1_xor_s0;

+

+  assign s1_xor_s0 = (s1 ^ s0);

+

+  assign random = ({n1_plus_n0[14:0],n1_plus_n0[31 : 15]} + n0);

+  

+  always @(negedge rst_n or posedge clk) begin

+    if (rst_n == 1'b0) begin

+      s0         <= (32'h00000001);

+      s1         <= (32'h00000000);

+      n0         <= (32'h00000000);

+      n1         <= (32'h00000000);

+	  n1_plus_n0 <= (32'h00000000);

+    end else begin

+	

+	  // stage 1

+      if (next == 1'b1) begin

+        s0 <= n0;

+        s1 <= n1;

+      end

+

+	  // stage 2

+      n0 <= (({s0[5:0],s0[31:6]} ^ s1_xor_s0) ^ (s1_xor_s0 <<< 9));

+      n1 <= {s1_xor_s0[18:0],s1_xor_s0[31:19]};

+	  

+	  // stage 3

+	  n1_plus_n0 <= (n0 + n1);

+	  

+    end

+  end

+

+endmodule

diff --git a/verilog/rtl/user_params.svh b/verilog/rtl/user_params.svh
index 82c3685..3925f53 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'h0712_2022;
+parameter CHIP_RELEASE_DATE = 32'h1312_2022;
 // Software Reg-2: Poject Revison 5.1 = 0005200
-parameter CHIP_REVISION   = 32'h0006_3000;
+parameter CHIP_REVISION   = 32'h0006_4000;
 
 parameter CLK_SKEW1_RESET_VAL = 32'b0100_0000_0100_0111_1001_1110_1000_0011;
 parameter CLK_SKEW2_RESET_VAL = 32'b0111_1000_1000_1000_0100_0100_1000_1110;
@@ -161,5 +161,6 @@
 `define SEL_PERI    1'b1      // Peripheral
 `define SEL_D2A     4'b1000   // Digital2Analog  REGISTER
 `define SEL_RTC     4'b1001   // RTC     REGISTER
+`define SEL_IR      4'b1010   // IR     REGISTER
 `endif // USER_PARMS
 
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 9c767a2..f0e9ffd 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -43,6 +43,9 @@
 ////      16. AES 126 Encription/Decryption                       ////
 ////      17. FPU (Single Precision)                              ////
 ////      18. RTC                                                 ////
+////      19. Random Generator                                    ////
+////      20. NEC IR Receiver                                     ////
+////      21. NEC IR Transmitter                                  ////
 ////                                                              ////
 ////  To Do:                                                      ////
 ////    nothing                                                   ////
@@ -300,6 +303,12 @@
 ////    6.3  Dec 7, 2022, Dinesh A                                ////
 ////         A. peripheral block integration                      ////
 ////         B. RTC Integration                                   ////
+////    6.4  Dec 13, 2022, Dinesh A                               ////
+////         A. Random Generator Integration                      ////
+////         B. NEC IR Receiver Integration                       ////
+////         C. NEC IR Transmitter Integration                    ////
+////      Bug Fix In Pinmux                                       ////
+////         WS281x IO direction fix                              //// 
 //////////////////////////////////////////////////////////////////////
 ////                                                              ////
 //// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
@@ -843,6 +852,13 @@
 wire                           reg_peri_ack                           ;
 
 wire                           rtc_intr                               ; // RTC interrupt
+
+//---------------------------------------------------------------------
+// IR Receiver
+//---------------------------------------------------------------------
+wire                           ir_rx                                 ; // IR Receiver Input from pad
+wire                           ir_tx                                 ; // IR Transmitter
+wire                           ir_intr                               ; // IR Interrupt
 //---------------------------------------------------------------------
 // Strap
 //---------------------------------------------------------------------
@@ -1777,7 +1793,11 @@
           .reg_peri_rdata     (reg_peri_rdata               ),
           .reg_peri_ack       (reg_peri_ack                 ),
 
-          .rtc_intr           (rtc_intr                     )
+          .rtc_intr           (rtc_intr                     ),
+
+          .ir_rx              (ir_rx                        ),
+          .ir_tx              (ir_tx                        ),
+          .ir_intr            (ir_intr                      )
 
    ); 
 
@@ -1818,6 +1838,10 @@
           .inc_time_s              (                        ),
           .inc_date_d              (                        ),
 
+          .ir_rx                   (ir_rx                   ),
+          .ir_tx                   (ir_tx                   ),
+          .ir_intr                 (ir_intr                 ),
+
           .cfg_dac0_mux_sel        (cfg_dac0_mux_sel        ),
           .cfg_dac1_mux_sel        (cfg_dac1_mux_sel        ),
           .cfg_dac2_mux_sel        (cfg_dac2_mux_sel        ),
diff --git a/verilog/rtl/user_reg_map.v b/verilog/rtl/user_reg_map.v
index f2b704a..25b2a6e 100644
--- a/verilog/rtl/user_reg_map.v
+++ b/verilog/rtl/user_reg_map.v
@@ -17,6 +17,7 @@
 `define ADDR_SPACE_WS281X  32'h3002_0280
 `define ADDR_SPACE_ANALOG  32'h3002_0400
 `define ADDR_SPACE_RTC     32'h3002_0480
+`define ADDR_SPACE_IR      32'h3002_0500
 `define ADDR_SPACE_WBHOST  32'h3008_0000
 
 //--------------------------------------------------
@@ -39,6 +40,7 @@
 `define GLBL_CFG_CLK_CTRL      8'h18  // reg_6  - RTC/USB CLK CTRL
 `define GLBL_CFG_PLL_CTRL1     8'h1C  // reg_7  - PLL Control-1
 `define GLBL_CFG_PLL_CTRL2     8'h20  // reg_8  - PLL Control-2
+`define GLBL_CFG_RANDOM_NO     8'h24  // reg_9  - Random Number
 `define GLBL_CFG_PAD_STRAP     8'h30  // Strap as seen in Pad
 `define GLBL_CFG_STRAP_STICKY  8'h34  // Sticky Strap used in next soft boot
 `define GLBL_CFG_SYSTEM_STRAP  8'h38  // Current System Strap
@@ -177,3 +179,12 @@
 `define  RTC_ALRM1        8'hC
 `define  RTC_ALRM2        8'h10
 `define  RTC_CTRL         8'h14
+
+//--------------------------------------------------------
+// IR RECEIVER Register Map
+//--------------------------------------------------------
+`define IR_CFG_CMD          8'h00 
+`define IR_CFG_MULTIPLIER   8'h04 
+`define IR_CFG_DIVIDER      8'h08 
+`define IR_CFG_RX_DATA      8'h0C 
+`define IR_CFG_TX_DATA      8'h10