diff --git a/EF_UART.yaml b/EF_UART.yaml index 6a0d63c..5d6cd4b 100644 --- a/EF_UART.yaml +++ b/EF_UART.yaml @@ -7,8 +7,8 @@ info: license: APACHE 2.0 author: Mohamed Shalan email: mshalan@efabless.com - version: v1.1.3 - date: 20-5-2024 + version: v1.1.4 + date: 08-07-2024 category: digital tags: - peripheral diff --git a/fw/EF_UART.c b/fw/EF_UART.c index 91ab04e..1af17f2 100644 --- a/fw/EF_UART.c +++ b/fw/EF_UART.c @@ -8,6 +8,11 @@ #include +void EF_UART_setGclkEnable (uint32_t uart_base, int value){ + EF_UART_TYPE* uart = (EF_UART_TYPE*)uart_base; + uart->GCLK = value; +} + void EF_UART_enable(uint32_t uart_base){ EF_UART_TYPE* uart = (EF_UART_TYPE*)uart_base; diff --git a/fw/EF_UART.h b/fw/EF_UART.h index 4a30f47..f185f9d 100644 --- a/fw/EF_UART.h +++ b/fw/EF_UART.h @@ -13,6 +13,7 @@ enum parity_type {NONE = 0, ODD = 1, EVEN = 2, STICKY_0 = 4, STICKY_1 = 5}; +void EF_UART_setGclkEnable (uint32_t uart_base, int value); //! enables using uart by setting "en" bit in the control register to 1 /*! diff --git a/fw/EF_UART_regs.h b/fw/EF_UART_regs.h index 5438668..290acad 100644 --- a/fw/EF_UART_regs.h +++ b/fw/EF_UART_regs.h @@ -90,6 +90,7 @@ typedef struct _EF_UART_TYPE_ { __R MIS; __R RIS; __W IC; + __W GCLK; } EF_UART_TYPE; #endif diff --git a/hdl/rtl/bus_wrappers/EF_UART_APB.pp.v b/hdl/rtl/bus_wrappers/EF_UART_APB.pp.v index 0aedb50..907f7c0 100644 --- a/hdl/rtl/bus_wrappers/EF_UART_APB.pp.v +++ b/hdl/rtl/bus_wrappers/EF_UART_APB.pp.v @@ -21,67 +21,6 @@ `timescale 1ns/1ps `default_nettype none - - - -/* - Copyright 2020 AUCOHL - - Author: Mohamed Shalan (mshalan@aucegypt.edu) - - 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. -*/ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - module EF_UART_APB #( parameter @@ -90,6 +29,10 @@ module EF_UART_APB #( GFLEN = 8, FAW = 4 ) ( +`ifdef USE_POWER_PINS + input wire VPWR, + input wire VGND, +`endif input wire PCLK, input wire PRESETn, input wire PWRITE, @@ -121,7 +64,23 @@ module EF_UART_APB #( localparam MIS_REG_OFFSET = 16'hFF04; localparam RIS_REG_OFFSET = 16'hFF08; localparam IC_REG_OFFSET = 16'hFF0C; - wire clk = PCLK; + + wire clk_g; + wire clk_gated_en = GCLK_REG[0]; + + (* keep *) sky130_fd_sc_hd__dlclkp_4 clk_gate( + `ifdef USE_POWER_PINS + .VPWR(VPWR), + .VGND(VGND), + .VNB(VGND), + .VPB(VPWR), + `endif + .GCLK(clk_g), + .GATE(clk_gated_en), + .CLK(PCLK) + ); + + wire clk = clk_g; wire rst_n = PRESETn; @@ -233,6 +192,12 @@ module EF_UART_APB #( else TX_FIFO_FLUSH_REG <= 1'h0 & TX_FIFO_FLUSH_REG; + localparam GCLK_REG_OFFSET = 16'hFF10; + reg [0:0] GCLK_REG; + always @(posedge PCLK or negedge PRESETn) if(~PRESETn) GCLK_REG <= 0; + else if(apb_we & (PADDR[16-1:0]==GCLK_REG_OFFSET)) + GCLK_REG <= PWDATA[1-1:0]; + reg [9:0] IM_REG; reg [9:0] IC_REG; reg [9:0] RIS_REG; @@ -357,6 +322,7 @@ module EF_UART_APB #( (PADDR[16-1:0] == MIS_REG_OFFSET) ? MIS_REG : (PADDR[16-1:0] == RIS_REG_OFFSET) ? RIS_REG : (PADDR[16-1:0] == IC_REG_OFFSET) ? IC_REG : + (PADDR[16-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : 32'hDEADBEEF; assign PREADY = 1'b1; diff --git a/hdl/rtl/bus_wrappers/EF_UART_APB.v b/hdl/rtl/bus_wrappers/EF_UART_APB.v index b7e8f34..6c17d10 100644 --- a/hdl/rtl/bus_wrappers/EF_UART_APB.v +++ b/hdl/rtl/bus_wrappers/EF_UART_APB.v @@ -33,6 +33,10 @@ module EF_UART_APB #( GFLEN = 8, FAW = 4 ) ( +`ifdef USE_POWER_PINS + input wire VPWR, + input wire VGND, +`endif `APB_SLAVE_PORTS, input wire [1-1:0] rx, output wire [1-1:0] tx @@ -54,7 +58,23 @@ module EF_UART_APB #( localparam MIS_REG_OFFSET = `APB_AW'hFF04; localparam RIS_REG_OFFSET = `APB_AW'hFF08; localparam IC_REG_OFFSET = `APB_AW'hFF0C; - wire clk = PCLK; + + wire clk_g; + wire clk_gated_en = GCLK_REG[0]; + + (* keep *) sky130_fd_sc_hd__dlclkp_4 clk_gate( + `ifdef USE_POWER_PINS + .VPWR(VPWR), + .VGND(VGND), + .VNB(VGND), + .VPB(VPWR), + `endif + .GCLK(clk_g), + .GATE(clk_gated_en), + .CLK(PCLK) + ); + + wire clk = clk_g; wire rst_n = PRESETn; @@ -144,6 +164,10 @@ module EF_UART_APB #( assign tx_fifo_flush = TX_FIFO_FLUSH_REG[0 : 0]; `APB_REG_AC(TX_FIFO_FLUSH_REG, 0, 1, 1'h0) + localparam GCLK_REG_OFFSET = `APB_AW'hFF10; + reg [0:0] GCLK_REG; + `APB_REG(GCLK_REG, 0, 1) + reg [9:0] IM_REG; reg [9:0] IC_REG; reg [9:0] RIS_REG; @@ -262,6 +286,7 @@ module EF_UART_APB #( (PADDR[`APB_AW-1:0] == MIS_REG_OFFSET) ? MIS_REG : (PADDR[`APB_AW-1:0] == RIS_REG_OFFSET) ? RIS_REG : (PADDR[`APB_AW-1:0] == IC_REG_OFFSET) ? IC_REG : + (PADDR[`APB_AW-1:0] == GCLK_REG_OFFSET) ? GCLK_REG : 32'hDEADBEEF; assign PREADY = 1'b1;