pinmux register remap as glbl,gpio,timer,pwm,semaphore
diff --git a/verilog/rtl/lib/registers.v b/verilog/rtl/lib/registers.v
index e4a87a1..b9a093e 100755
--- a/verilog/rtl/lib/registers.v
+++ b/verilog/rtl/lib/registers.v
@@ -288,6 +288,45 @@
endmodule
/*********************************************************************
+ module: generic 16b register
+***********************************************************************/
+module gen_16b_reg (
+ //List of Inputs
+ cs,
+ we,
+ data_in,
+ reset_n,
+ clk,
+
+ //List of Outs
+ data_out
+ );
+
+ parameter RESET_DEFAULT = 16'h0;
+ input [1:0] we;
+ input cs;
+ input [15:0] data_in;
+ input reset_n;
+ input clk;
+ output [15:0] data_out;
+
+
+ reg [15:0] data_out;
+
+always @ (posedge clk or negedge reset_n) begin
+ if (reset_n == 1'b0) begin
+ data_out <= RESET_DEFAULT ;
+ end
+ else begin
+ if(cs && we[0]) data_out[7:0] <= data_in[7:0];
+ if(cs && we[1]) data_out[15:8] <= data_in[15:8];
+ end
+end
+
+
+endmodule
+
+/*********************************************************************
module: generic 32b register
***********************************************************************/
module gen_32b_reg (
diff --git a/verilog/rtl/pinmux/src/glbl_reg.sv b/verilog/rtl/pinmux/src/glbl_reg.sv
new file mode 100644
index 0000000..d91ff4e
--- /dev/null
+++ b/verilog/rtl/pinmux/src/glbl_reg.sv
@@ -0,0 +1,437 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Global Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// Hold all the Global and PinMux Register ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module glbl_reg (
+ // System Signals
+ // Inputs
+ input logic mclk ,
+ input logic h_reset_n ,
+
+ // Global Reset control
+ output logic [1:0] cpu_core_rst_n ,
+ output logic cpu_intf_rst_n ,
+ output logic qspim_rst_n ,
+ output logic sspim_rst_n ,
+ output logic [1:0] uart_rst_n ,
+ output logic i2cm_rst_n ,
+ output logic usb_rst_n ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [3:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ input logic [1:0] ext_intr_in ,
+
+ // Risc configuration
+ output logic [15:0] irq_lines ,
+ output logic soft_irq ,
+ output logic [2:0] user_irq ,
+ input logic usb_intr ,
+ input logic i2cm_intr ,
+
+ output logic [15:0] cfg_riscv_ctrl ,
+ output logic [31:0] cfg_multi_func_sel ,// multifunction pins
+
+
+ input logic [2:0] timer_intr ,
+ input logic gpio_intr
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en;
+logic [4:0] sw_addr; // addressing 16 registers
+logic [31:0] sw_reg_wdata;
+logic [3:0] wr_be ;
+
+logic [31:0] reg_out;
+logic [31:0] reg_0; // Chip ID
+logic [31:0] reg_1; // Global Reg-0
+logic [31:0] reg_2; // Global Reg-1
+logic [31:0] reg_3; // Global Interrupt Mask
+logic [31:0] reg_4; // Global Interrupt Status
+logic [31:0] reg_5; // Multi Function Sel
+logic [31:0] reg_6; // Software Reg-0
+logic [31:0] reg_7; // Software Reg-1
+logic [31:0] reg_8; // Software Reg-2
+logic [31:0] reg_9; // Software Reg-3
+logic [31:0] reg_10; // Software Reg-4
+logic [31:0] reg_11; // Software Reg-5
+
+
+logic cs_int;
+
+
+assign sw_addr = reg_addr ;
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign wr_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (reg_cs && !reg_ack) begin
+ reg_rdata <= reg_out ;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+wire sw_wr_en_9 = sw_wr_en & (sw_addr == 4'h9);
+wire sw_wr_en_10 = sw_wr_en & (sw_addr == 4'hA);
+wire sw_wr_en_11 = sw_wr_en & (sw_addr == 4'hB);
+
+
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+wire sw_rd_en_9 = sw_rd_en & (sw_addr == 4'h9);
+wire sw_rd_en_10 = sw_rd_en & (sw_addr == 4'hA);
+wire sw_rd_en_11 = sw_rd_en & (sw_addr == 4'hB);
+
+//-----------------------------------------------------------------------
+// Individual register assignments
+//-----------------------------------------------------------------------
+
+// Chip ID
+// chip-id[3:0] mapping
+// 0 - YIFIVE (MPW-2)
+// 1 - Riscdunio (MPW-3)
+// 2 - Riscdunio (MPW-4)
+// 3 - Riscdunio (MPW-5)
+// 4 - Riscdunio (MPW-6)
+// 5 - Riscdunio (MPW-7)
+// 6 - Riscdunio (MPW-8)
+// 7 - Riscdunio (MPW-9)
+
+wire [15:0] manu_id = 16'h8268; // Asci value of RD
+wire [3:0] total_core = 4'h2;
+wire [3:0] chip_id = 4'h5;
+wire [7:0] chip_rev = 8'h01;
+
+assign reg_0 = {manu_id,total_core,chip_id,chip_rev};
+
+
+//------------------------------------------
+// reg-1: GLBL_CFG_0
+//------------------------------------------
+wire [31:0] cfg_glb_ctrl = reg_1;
+
+ctech_buf u_buf_cpu_intf_rst (.A(cfg_glb_ctrl[0]),.X(cpu_intf_rst_n));
+ctech_buf u_buf_qspim_rst (.A(cfg_glb_ctrl[1]),.X(qspim_rst_n));
+ctech_buf u_buf_sspim_rst (.A(cfg_glb_ctrl[2]),.X(sspim_rst_n));
+ctech_buf u_buf_uart0_rst (.A(cfg_glb_ctrl[3]),.X(uart_rst_n[0]));
+ctech_buf u_buf_i2cm_rst (.A(cfg_glb_ctrl[4]),.X(i2cm_rst_n));
+ctech_buf u_buf_usb_rst (.A(cfg_glb_ctrl[5]),.X(usb_rst_n));
+ctech_buf u_buf_uart1_rst (.A(cfg_glb_ctrl[6]),.X(uart_rst_n[1]));
+
+ctech_buf u_buf_cpu0_rst (.A(cfg_glb_ctrl[8]),.X(cpu_core_rst_n[0]));
+ctech_buf u_buf_cpu1_rst (.A(cfg_glb_ctrl[9]),.X(cpu_core_rst_n[1]));
+
+gen_32b_reg #(32'h0) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1 )
+ );
+
+//----------------------------------------------
+// reg-2: GLBL_CFG_1
+//------------------------------------------
+
+gen_32b_reg #(32'h0) u_reg_2 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_2 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_2 )
+ );
+
+assign cfg_riscv_ctrl = reg_2[31:16];
+
+//-----------------------------------------------------------------------
+// reg-3 : Global Interrupt Mask
+//-----------------------------------------------------------------------
+
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3 )
+ );
+
+//-----------------------------------------------------------------------
+// reg-4 : Global Interrupt Status
+//-----------------------------------------------------------------
+assign irq_lines = reg_3[15:0] & reg_4[15:0];
+assign soft_irq = reg_3[16] & reg_4[16];
+assign user_irq = reg_3[19:17]& reg_4[19:17];
+
+
+generic_register #(8,0 ) u_reg4_be0 (
+ .we ({8{sw_wr_en_4 &
+ wr_be[0] }} ),
+ .data_in (sw_reg_wdata[7:0] ),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[7:0] )
+ );
+
+
+wire [7:0] hware_intr_req = {gpio_intr, ext_intr_in[1:0], usb_intr, i2cm_intr,timer_intr[2:0]};
+
+generic_intr_stat_reg #(.WD(8),
+ .RESET_DEFAULT(0)) u_reg4_be1 (
+ //inputs
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .reg_we ({8{sw_wr_en_4 & reg_ack &
+ wr_be[1] }} ),
+ .reg_din (sw_reg_wdata[15:8] ),
+ .hware_req (hware_intr_req ),
+
+ //outputs
+ .data_out (reg_4[15:8] )
+ );
+
+
+
+generic_register #(4,0 ) u_reg4_be2 (
+ .we ({4{sw_wr_en_4 &
+ wr_be[2] }} ),
+ .data_in (sw_reg_wdata[19:16]),
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+
+ //List of Outs
+ .data_out (reg_4[19:16] )
+ );
+
+assign reg_4[31:20] = '0;
+
+
+//-----------------------------------------------------------------------
+// Logic for cfg_multi_func_sel :Enable GPIO to act as multi function pins
+//-----------------------------------------------------------------------
+assign cfg_multi_func_sel = reg_5[31:0]; // to be used for read
+
+
+gen_32b_reg #(32'h0) u_reg_5 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_5 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_5 )
+ );
+
+//-----------------------------------------
+// Software Reg-0 : ASCI Representation of RISC = 32'h8273_8343
+// ----------------------------------------
+gen_32b_reg #(32'h8273_8343) u_reg_6 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_6 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_6 )
+ );
+
+//-----------------------------------------
+// Software Reg-1, Release date: <DAY><MONTH><YEAR>
+// ----------------------------------------
+gen_32b_reg #(32'h1508_2022) u_reg_7 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_7 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_7 )
+ );
+
+//-----------------------------------------
+// Software Reg-2: Poject Revison 5.0 = 0005000
+// ----------------------------------------
+gen_32b_reg #(32'h0005_0000) u_reg_8 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_8 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_8 )
+ );
+
+//-----------------------------------------
+// Software Reg-3
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_9 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_9 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_9 )
+ );
+
+//-----------------------------------------
+// Software Reg-4
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_10 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_10 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_10 )
+ );
+
+//-----------------------------------------
+// Software Reg-5
+// ----------------------------------------
+gen_32b_reg #(32'h0) u_reg_11 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_11 ),
+ .we (wr_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_11 )
+ );
+
+
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ 4'b0011 : reg_out [31:0] = reg_3 [31:0];
+ 4'b0100 : reg_out [31:0] = reg_4 [31:0];
+ 4'b0101 : reg_out [31:0] = reg_5 [31:0];
+ 4'b0110 : reg_out [31:0] = reg_6 [31:0];
+ 4'b0111 : reg_out [31:0] = reg_7 [31:0];
+ 4'b1000 : reg_out [31:0] = reg_8 [31:0];
+ 4'b1001 : reg_out [31:0] = reg_9 [31:0];
+ 4'b1010 : reg_out [31:0] = reg_10 [31:0];
+ 4'b1011 : reg_out [31:0] = reg_11 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/gpio_control.sv b/verilog/rtl/pinmux/src/gpio_control.sv
deleted file mode 100644
index 4c917dc..0000000
--- a/verilog/rtl/pinmux/src/gpio_control.sv
+++ /dev/null
@@ -1,44 +0,0 @@
-
-// GPIO Interrupt Generation
-module gpio_intr (
- input logic mclk ,// System clk
- input logic h_reset_n ,// system reset
- input logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
- input logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
- input logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
- input logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
- input logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
- input logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
-
-
- output logic [31:0] pad_gpio_out ,// GPIO O/P to the gpio cfg reg
- output logic [31:0] gpio_int_event // to the cfg interrupt status reg
-
-);
-
-
-integer i;
-//-----------------------------------------------------------------------
-// Logic for interrupt detection
-//-----------------------------------------------------------------------
-
-reg [31:0] local_gpio_int_event; // to the cfg interrupt status reg
-always @(cfg_gpio_data_in or cfg_gpio_negedge_int_sel or cfg_gpio_posedge_int_sel
- or gpio_prev_indata)
-begin
- for (i=0; i<32; i=i+1)
- begin
- // looking for rising edge int
- local_gpio_int_event[i] = ((cfg_gpio_posedge_int_sel[i] & ~gpio_prev_indata[i]
- & cfg_gpio_data_in[i]) |
- (cfg_gpio_negedge_int_sel[i] & gpio_prev_indata[i] &
- ~cfg_gpio_data_in[i]));
- // looking for falling edge int
- end
-end
-
-assign gpio_int_event = local_gpio_int_event[31:0]; // goes as O/P to the cfg reg
-
-assign pad_gpio_out = cfg_gpio_out_data[31:0] ;// O/P on the GPIO bus
-
-endmodule
diff --git a/verilog/rtl/pinmux/src/gpio_reg.sv b/verilog/rtl/pinmux/src/gpio_reg.sv
new file mode 100644
index 0000000..be61923
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_reg.sv
@@ -0,0 +1,325 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// GPIO Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module gpio_reg (
+ // System Signals
+ // Inputs
+ input logic mclk ,
+ input logic h_reset_n ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [3:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+
+ input logic [31:0] gpio_in_data ,
+ output logic [31:0] gpio_prev_indata ,// previously captured GPIO I/P pins data
+ input logic [31:0] gpio_int_event ,
+ output logic [31:0] cfg_gpio_out_data ,// GPIO statuc O/P data from config reg
+ output logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output
+ output logic [31:0] cfg_gpio_out_type ,// GPIO Type, Unused
+ output logic [31:0] cfg_multi_func_sel ,// GPIO Multi function type
+ output logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
+ output logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
+ output logic [31:00] cfg_gpio_data_in ,
+
+ output logic gpio_intr
+
+
+ );
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [3:0] sw_addr ; // addressing 16 registers
+logic [31:0] sw_reg_wdata ;
+logic [3:0] sw_be ;
+
+logic [31:0] reg_out ;
+logic [31:0] reg_0 ; // GPIO Direction Select
+logic [31:0] reg_1 ; // GPIO TYPE - Unused
+logic [31:0] reg_2 ; // GPIO IN DATA
+logic [31:0] reg_3 ; // GPIO OUT DATA
+logic [31:0] reg_4 ; // GPIO INTERRUPT STATUS/CLEAR
+logic [31:0] reg_5 ; // GPIO INTERRUPT SET
+logic [31:0] reg_6 ; // GPIO INTERRUPT MASK
+logic [31:0] reg_7 ; // GPIO POSEDGE INTERRUPT SEL
+logic [31:0] reg_8 ; // GPIO NEGEDGE INTERRUPT SEL
+
+assign sw_addr = reg_addr;
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign sw_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 4'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 4'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 4'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 4'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 4'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 4'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 4'h6);
+wire sw_wr_en_7 = sw_wr_en & (sw_addr == 4'h7);
+wire sw_wr_en_8 = sw_wr_en & (sw_addr == 4'h8);
+
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 4'h0);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 4'h1);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 4'h2);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 4'h3);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 4'h4);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 4'h5);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 4'h6);
+wire sw_rd_en_7 = sw_rd_en & (sw_addr == 4'h7);
+wire sw_rd_en_8 = sw_rd_en & (sw_addr == 4'h8);
+
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (reg_cs && !reg_ack) begin
+ reg_rdata <= reg_out;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_dir_sel
+//-----------------------------------------------------------------------
+assign cfg_gpio_dir_sel = reg_0[31:0]; // data to the GPIO O/P pins
+
+gen_32b_reg #(32'h0) u_reg_0 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_0 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_0 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_type
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_type = reg_1[31:0]; // Un-used
+
+gen_32b_reg #(32'h0) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1 )
+ );
+//-----------------------------------------------------------------------
+// Logic for gpio_data_in
+//-----------------------------------------------------------------------
+logic [31:0] gpio_in_data_s;
+logic [31:0] gpio_in_data_ss;
+// Double Sync the gpio pin data for edge detection
+always @ (posedge mclk or negedge h_reset_n)
+begin
+ if (h_reset_n == 1'b0) begin
+ reg_2 <= 'h0 ;
+ gpio_in_data_s <= 32'd0;
+ gpio_in_data_ss <= 32'd0;
+ end
+ else begin
+ gpio_in_data_s <= gpio_in_data;
+ gpio_in_data_ss <= gpio_in_data_s;
+ reg_2 <= gpio_in_data_ss;
+ end
+end
+
+
+assign cfg_gpio_data_in = reg_2[31:0]; // to be used for edge interrupt detect
+assign gpio_prev_indata = gpio_in_data_ss;
+
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_out_data
+//-----------------------------------------------------------------------
+assign cfg_gpio_out_data = reg_3[31:0]; // data to the GPIO control blk
+
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3 )
+ );
+
+
+
+//--------------------------------------------------------
+// Interrupt Status Generation
+// Note: Reg_4 --> Interrupt Status Register, Writting '1' will clear the
+// corresponding interrupt status bit. Writting '0' has no
+// effect
+// Reg_5 --> Writting one to this register will set the interrupt in
+// interrupt status register (reg_4), Writting '0' does not has any
+// effect.
+/// Always update int_status, even if no register write is occuring.
+// Interrupt posting is higher priority than int clear by host
+//--------------------------------------------------------
+wire [31:0] gpio_int_status = reg_4;
+
+generic_intr_stat_reg #(.WD(32),
+ .RESET_DEFAULT(0)) u_reg_4 (
+ //inputs
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .reg_we ({
+ {8{sw_wr_en_4 & reg_ack & sw_be[2]}},
+ {8{sw_wr_en_4 & reg_ack & sw_be[2]}},
+ {8{sw_wr_en_4 & reg_ack & sw_be[1]}},
+ {8{sw_wr_en_4 & reg_ack & sw_be[0]}}
+ } ),
+ .reg_din (sw_reg_wdata[31:0] ),
+ .hware_req (gpio_int_event | {
+ {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[31:24],
+ {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[23:16],
+ {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[15:8] ,
+ {8{sw_wr_en_5 & reg_ack}} & sw_reg_wdata[7:0]
+ } ),
+
+ //outputs
+ .data_out (reg_4[31:0] )
+ );
+//-------------------------------------------------
+// Returns same value as interrupt status register
+//------------------------------------------------
+
+assign reg_5 = reg_4;
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_int_mask : GPIO interrupt mask
+//-----------------------------------------------------------------------
+wire [31:0] cfg_gpio_int_mask = reg_6[31:0]; // to be used for read
+
+assign gpio_intr = ( | (reg_4 & reg_6) ); // interrupt pin to the RISC
+
+
+// Register-11
+gen_32b_reg #(32'h0) u_reg_6 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_6 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_6 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_posedge_int_sel : Enable posedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_posedge_int_sel = reg_7[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_7 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_7 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_7 )
+ );
+//-----------------------------------------------------------------------
+// Logic for cfg_gpio_negedge_int_sel : Enable negedge GPIO interrupt
+//-----------------------------------------------------------------------
+assign cfg_gpio_negedge_int_sel = reg_8[31:0]; // to be used for read
+gen_32b_reg #(32'h0) u_reg_8 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_8 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_8 )
+ );
+
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [3:0])
+ 4'b0000 : reg_out [31:0] = reg_0 [31:0];
+ 4'b0001 : reg_out [31:0] = reg_1 [31:0];
+ 4'b0010 : reg_out [31:0] = reg_2 [31:0];
+ 4'b0011 : reg_out [31:0] = reg_3 [31:0];
+ 4'b0100 : reg_out [31:0] = reg_4 [31:0];
+ 4'b0101 : reg_out [31:0] = reg_5 [31:0];
+ 4'b0110 : reg_out [31:0] = reg_6 [31:0];
+ 4'b0111 : reg_out [31:0] = reg_7 [31:0];
+ 4'b1000 : reg_out [31:0] = reg_8 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/gpio_top.sv b/verilog/rtl/pinmux/src/gpio_top.sv
new file mode 100644
index 0000000..0a7fd02
--- /dev/null
+++ b/verilog/rtl/pinmux/src/gpio_top.sv
@@ -0,0 +1,130 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// GPIO Top ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+/// ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+
+module gpio_top (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [3:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ output logic [31:0] cfg_gpio_dir_sel,
+ input logic [31:0] pad_gpio_in,
+ output logic [31:0] pad_gpio_out,
+
+ output logic gpio_intr
+
+ );
+
+
+logic [31:0] gpio_prev_indata ;// previously captured GPIO I/P pins data
+logic [31:0] cfg_gpio_out_data ;// GPIO statuc O/P data from config reg
+logic [31:0] cfg_gpio_out_type ;// GPIO Type, Unused
+logic [31:0] cfg_multi_func_sel ;// GPIO Multi function type
+logic [31:0] cfg_gpio_posedge_int_sel ;// select posedge interrupt
+logic [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt
+logic [31:00] cfg_gpio_data_in ;
+logic [31:0] gpio_int_event ;
+
+
+gpio_reg u_reg (
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ // GPIO input pins
+ .gpio_in_data (pad_gpio_in ),
+ .gpio_prev_indata (gpio_prev_indata ),
+ .gpio_int_event (gpio_int_event ),
+
+ // GPIO config pins
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_type (cfg_gpio_out_type ),
+ .cfg_gpio_posedge_int_sel (cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel (cfg_gpio_negedge_int_sel),
+ .cfg_multi_func_sel (cfg_multi_func_sel ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+
+ .gpio_intr (gpio_intr )
+
+
+ );
+
+
+gpio_intr_gen u_gpio_intr (
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // GPIO cfg input pins
+ .gpio_prev_indata (gpio_prev_indata ),
+ .cfg_gpio_data_in (cfg_gpio_data_in ),
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_gpio_out_data (cfg_gpio_out_data ),
+ .cfg_gpio_posedge_int_sel(cfg_gpio_posedge_int_sel),
+ .cfg_gpio_negedge_int_sel(cfg_gpio_negedge_int_sel),
+
+
+ // GPIO output pins
+ .pad_gpio_out (pad_gpio_out ),
+ .gpio_int_event (gpio_int_event )
+ );
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux.sv b/verilog/rtl/pinmux/src/pinmux.sv
index e36556c..54c0ef9 100755
--- a/verilog/rtl/pinmux/src/pinmux.sv
+++ b/verilog/rtl/pinmux/src/pinmux.sv
@@ -17,13 +17,13 @@
//
//////////////////////////////////////////////////////////////////////
//// ////
-//// Pinmux ////
+//// Pinmux ////
//// ////
//// This file is part of the riscduino cores project ////
//// https://github.com/dineshannayya/riscduino.git ////
//// ////
//// Description ////
-//// PinMux Manages all the pin multiplexing ////
+//// Manages all the pin multiplexing ////
//// ////
//// To Do: ////
//// nothing ////
@@ -32,482 +32,9 @@
//// - Dinesh Annayya, dinesha@opencores.org ////
//// ////
//// Revision : ////
-//// 0.1 - 16th Feb 2021, Dinesh A ////
-//// initial version ////
-//// 0.2 - 6 April 2021, Dinesh A ////
-//// 1. SSPI CS# increased from 1 to 4 ////
-// 2. UART I/F increase from 1 to 2 ////
-//// 0.3 - 8 July 2022, Dinesh A ////
-//// In ardunio, SPI chip select are control through ////
-//// GPIO, So we have moved the Auto generated SPI CS ////
-//// different config bit. I2C config position moved from////
-//// bit[14] to bit [15] ////
-//// 0.4 - 20 July 2022, Dinesh A ////
-//// On Power On, If RESET* = 0, then system will enter ////
-//// in to SPIS slave mode to support boot ////
+//// 0.1 - 16th Aug 2022, Dinesh A ////
+//// Seperated the pinmux from pinmux_top module ////
//////////////////////////////////////////////////////////////////////
-
-module pinmux (
- `ifdef USE_POWER_PINS
- input logic vccd1,// User area 1 1.8V supply
- input logic vssd1,// User area 1 digital ground
- `endif
- // clock skew adjust
- input logic [3:0] cfg_cska_pinmux,
- input logic wbd_clk_int,
- output logic wbd_clk_pinmux,
- // System Signals
- // Inputs
- input logic mclk,
- input logic h_reset_n,
-
- // Global Reset control
- output logic [1:0] cpu_core_rst_n ,
- output logic cpu_intf_rst_n ,
- output logic qspim_rst_n ,
- output logic sspim_rst_n ,
- output logic [1:0] uart_rst_n ,
- output logic i2cm_rst_n ,
- output logic usb_rst_n ,
-
- output logic [15:0] cfg_riscv_ctrl,
-
- // Reg Bus Interface Signal
- input logic reg_cs,
- input logic reg_wr,
- input logic [7:0] reg_addr,
- input logic [31:0] reg_wdata,
- input logic [3:0] reg_be,
-
- // Outputs
- output logic [31:0] reg_rdata,
- output logic reg_ack,
-
- // Risc configuration
- output logic [15:0] irq_lines,
- output logic soft_irq,
- output logic [2:0] user_irq,
- input logic usb_intr,
- input logic i2cm_intr,
-
- // Digital IO
- output logic [37:0] digital_io_out,
- output logic [37:0] digital_io_oen,
- input logic [37:0] digital_io_in,
-
- // SFLASH I/F
- input logic sflash_sck,
- input logic [3:0] sflash_ss,
- input logic [3:0] sflash_oen,
- input logic [3:0] sflash_do,
- output logic [3:0] sflash_di,
-
- // SSRAM I/F - Temp Masked
- //input logic ssram_sck,
- //input logic ssram_ss,
- //input logic [3:0] ssram_oen,
- //input logic [3:0] ssram_do,
- //output logic [3:0] ssram_di,
-
- // USB I/F
- input logic usb_dp_o,
- input logic usb_dn_o,
- input logic usb_oen,
- output logic usb_dp_i,
- output logic usb_dn_i,
-
- // UART I/F
- input logic [1:0] uart_txd,
- output logic [1:0] uart_rxd,
-
- // I2CM I/F
- input logic i2cm_clk_o,
- output logic i2cm_clk_i,
- input logic i2cm_clk_oen,
- input logic i2cm_data_oen,
- input logic i2cm_data_o,
- output logic i2cm_data_i,
-
- // SPI MASTER
- input logic spim_sck,
- input logic [3:0] spim_ssn,
- input logic spim_miso,
- output logic spim_mosi,
-
- // SPI SLAVE
- output logic spis_sck,
- output logic spis_ssn,
- input logic spis_miso,
- output logic spis_mosi,
-
- // UART MASTER I/F
- output logic uartm_rxd ,
- input logic uartm_txd ,
-
- output logic pulse1m_mclk,
- output logic [31:0] pinmux_debug,
-
- input logic dbg_clk_mon
-
- );
-
-
-
-logic sreset_n; // Sync Reset
-
-/* clock pulse */
-//********************************************************
-logic pulse_1us ; // 1 UsSecond Pulse for waveform Generator
-logic pulse_1ms ; // 1 UsSecond Pulse for waveform Generator
-logic pulse_1s ; // 1Second Pulse for waveform Generator
-logic [9:0] cfg_pulse_1us ; // 1us pulse generation config
-
-
-//---------------------------------------------------------
-// Timer Register
-// -------------------------------------------------------
-logic [2:0] cfg_timer_update ; // CPU write to timer register
-logic [31:0] cfg_timer0 ; // Timer-0 register
-logic [31:0] cfg_timer1 ; // Timer-1 register
-logic [31:0] cfg_timer2 ; // Timer-2 register
-logic [2:0] timer_intr ;
-
-//---------------------------------------------------
-// 6 PWM variabled
-//---------------------------------------------------
-
-logic [5:0] pwm_wfm ;
-logic [5:0] cfg_pwm_enb ;
-logic [15:0] cfg_pwm0_high ;
-logic [15:0] cfg_pwm0_low ;
-logic [15:0] cfg_pwm1_high ;
-logic [15:0] cfg_pwm1_low ;
-logic [15:0] cfg_pwm2_high ;
-logic [15:0] cfg_pwm2_low ;
-logic [15:0] cfg_pwm3_high ;
-logic [15:0] cfg_pwm3_low ;
-logic [15:0] cfg_pwm4_high ;
-logic [15:0] cfg_pwm4_low ;
-logic [15:0] cfg_pwm5_high ;
-logic [15:0] cfg_pwm5_low ;
-
-
-wire [31:0] gpio_prev_indata ;// previously captured GPIO I/P pins data
-wire [31:0] cfg_gpio_out_data ;// GPIO statuc O/P data from config reg
-wire [31:0] cfg_gpio_dir_sel ;// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output
-wire [31:0] cfg_gpio_out_type ;// GPIO Type, Unused
-wire [31:0] cfg_multi_func_sel ;// GPIO Multi function type
-wire [31:0] cfg_gpio_posedge_int_sel ;// select posedge interrupt
-wire [31:0] cfg_gpio_negedge_int_sel ;// select negedge interrupt
-wire [31:00] cfg_gpio_data_in ;
-
-
-reg [7:0] port_a_in; // PORT A Data In
-reg [7:0] port_b_in; // PORT B Data In
-reg [7:0] port_c_in; // PORT C Data In
-reg [7:0] port_d_in; // PORT D Data In
-
-wire [7:0] port_a_out; // PORT A Data Out
-wire [7:0] port_b_out; // PORT B Data Out
-wire [7:0] port_c_out; // PORT C Data Out
-wire [7:0] port_d_out; // PORT D Data Out
-wire [31:0] pad_gpio_in; // GPIO data input from PAD
-wire [31:0] pad_gpio_out; // GPIO Data out towards PAD
-wire [31:0] gpio_int_event; // GPIO Interrupt indication
-reg [1:0] ext_intr_in; // External PAD level interrupt
-
-// GPIO to PORT Mapping
-assign pad_gpio_in[7:0] = port_a_in;
-assign pad_gpio_in[15:8] = port_b_in;
-assign pad_gpio_in[23:16] = port_c_in;
-assign pad_gpio_in[31:24] = port_d_in;
-
-assign port_a_out = pad_gpio_out[7:0];
-assign port_b_out = pad_gpio_out[15:8];
-assign port_c_out = pad_gpio_out[23:16];
-assign port_d_out = pad_gpio_out[31:24];
-
-assign pinmux_debug = '0; // Todo: Need to fix
-
-// SSRAM I/F - Temp masked
-//input logic ssram_sck,
-//input logic ssram_ss,
-//input logic [3:0] ssram_oen,
-//input logic [3:0] ssram_do,
-//output logic [3:0] ssram_di,
-
-// pinmux clock skew control
-clk_skew_adjust u_skew_pinmux
- (
-`ifdef USE_POWER_PINS
- .vccd1 (vccd1 ),// User area 1 1.8V supply
- .vssd1 (vssd1 ),// User area 1 digital ground
-`endif
- .clk_in (wbd_clk_int ),
- .sel (cfg_cska_pinmux ),
- .clk_out (wbd_clk_pinmux )
- );
-
-reset_sync u_rst_sync (
- .scan_mode (1'b0 ),
- .dclk (mclk ), // Destination clock domain
- .arst_n (h_reset_n ), // active low async reset
- .srst_n (sreset_n )
- );
-
-gpio_intr_gen u_gpio_intr (
- // System Signals
- // Inputs
- .mclk (mclk ),
- .h_reset_n (sreset_n ),
-
- // GPIO cfg input pins
- .gpio_prev_indata (gpio_prev_indata ),
- .cfg_gpio_data_in (cfg_gpio_data_in ),
- .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
- .cfg_gpio_out_data (cfg_gpio_out_data ),
- .cfg_gpio_posedge_int_sel(cfg_gpio_posedge_int_sel),
- .cfg_gpio_negedge_int_sel(cfg_gpio_negedge_int_sel),
-
-
- // GPIO output pins
- .pad_gpio_out (pad_gpio_out ),
- .gpio_int_event (gpio_int_event )
- );
-
-
-// 1us pulse
-pulse_gen_type2 #(.WD(10)) u_pulse_1us (
-
- .clk_pulse_o (pulse_1us ),
- .clk (mclk ),
- .reset_n (sreset_n ),
- .cfg_max_cnt (cfg_pulse_1us )
-
- );
-
-// 1millisecond pulse
-pulse_gen_type1 u_pulse_1ms (
-
- .clk_pulse_o (pulse_1ms ),
- .clk (mclk ),
- .reset_n (sreset_n ),
- .trigger (pulse_1us )
-
- );
-
-// 1 second pulse
-pulse_gen_type1 u_pulse_1s (
-
- .clk_pulse_o (pulse_1s ),
- .clk (mclk ),
- .reset_n (sreset_n ),
- .trigger (pulse_1ms )
-
- );
-
-
-// Timer
-
-wire cfg_timer0_enb = cfg_timer0[16];
-wire [1:0] cfg_timer0_clksel = cfg_timer0[18:17];
-wire [15:0] cfg_timer0_compare = cfg_timer0[15:0];
-
-timer u_timer_0
- (
- .reset_n (sreset_n ),// system syn reset
- .mclk (mclk ),// master clock
- .pulse_1us (pulse_1us ),
- .pulse_1ms (pulse_1ms ),
- .pulse_1s (pulse_1s ),
-
- .cfg_timer_update (cfg_timer_update[0] ),
- .cfg_timer_enb (cfg_timer0_enb ),
- .cfg_timer_compare (cfg_timer0_compare ),
- .cfg_timer_clksel (cfg_timer0_clksel ),// to select the timer 1us/1ms reference clock
-
- .timer_intr (timer_intr[0] )
- );
-
-// Timer
-wire cfg_timer1_enb = cfg_timer1[16];
-wire [1:0] cfg_timer1_clksel = cfg_timer1[18:17];
-wire [15:0] cfg_timer1_compare = cfg_timer1[15:0];
-timer u_timer_1
- (
- .reset_n (sreset_n ),// system syn reset
- .mclk (mclk ),// master clock
- .pulse_1us (pulse_1us ),
- .pulse_1ms (pulse_1ms ),
- .pulse_1s (pulse_1s ),
-
- .cfg_timer_update (cfg_timer_update[1] ),
- .cfg_timer_enb (cfg_timer1_enb ),
- .cfg_timer_compare (cfg_timer1_compare ),
- .cfg_timer_clksel (cfg_timer1_clksel ),// to select the timer 1us/1ms reference clock
-
- .timer_intr (timer_intr[1] )
- );
-
-// Timer
-wire cfg_timer2_enb = cfg_timer2[16];
-wire [1:0] cfg_timer2_clksel = cfg_timer2[18:17];
-wire [15:0] cfg_timer2_compare = cfg_timer2[15:0];
-timer u_timer_2
- (
- .reset_n (sreset_n ),// system syn reset
- .mclk (mclk ),// master clock
- .pulse_1us (pulse_1us ),
- .pulse_1ms (pulse_1ms ),
- .pulse_1s (pulse_1s ),
-
- .cfg_timer_update (cfg_timer_update[2] ),
- .cfg_timer_enb (cfg_timer2_enb ),
- .cfg_timer_compare (cfg_timer2_compare ),
- .cfg_timer_clksel (cfg_timer2_clksel ),// to select the timer 1us/1ms reference clock
-
- .timer_intr (timer_intr[2] )
- );
-
-
-pinmux_reg u_pinmux_reg(
- // System Signals
- // Inputs
- .mclk (mclk ),
- .h_reset_n (sreset_n ),
-
- .cpu_core_rst_n (cpu_core_rst_n ),
- .cpu_intf_rst_n (cpu_intf_rst_n ),
- .qspim_rst_n (qspim_rst_n ),
- .sspim_rst_n (sspim_rst_n ),
- .uart_rst_n (uart_rst_n ),
- .i2cm_rst_n (i2cm_rst_n ),
- .usb_rst_n (usb_rst_n ),
-
- .cfg_riscv_ctrl (cfg_riscv_ctrl ),
-
-
- // Reg read/write Interface Inputs
- .reg_cs (reg_cs ),
- .reg_wr (reg_wr ),
- .reg_addr (reg_addr ),
- .reg_wdata (reg_wdata ),
- .reg_be (reg_be ),
-
- .reg_rdata (reg_rdata ),
- .reg_ack (reg_ack ),
-
- .ext_intr_in (ext_intr_in ),
-
- .irq_lines (irq_lines ),
- .soft_irq (soft_irq ),
- .user_irq (user_irq ),
- .usb_intr (usb_intr ),
- .i2cm_intr (i2cm_intr ),
-
- .cfg_pulse_1us (cfg_pulse_1us ),
-
-
- .cfg_pwm0_high (cfg_pwm0_high ),
- .cfg_pwm0_low (cfg_pwm0_low ),
- .cfg_pwm1_high (cfg_pwm1_high ),
- .cfg_pwm1_low (cfg_pwm1_low ),
- .cfg_pwm2_high (cfg_pwm2_high ),
- .cfg_pwm2_low (cfg_pwm2_low ),
- .cfg_pwm3_high (cfg_pwm3_high ),
- .cfg_pwm3_low (cfg_pwm3_low ),
- .cfg_pwm4_high (cfg_pwm4_high ),
- .cfg_pwm4_low (cfg_pwm4_low ),
- .cfg_pwm5_high (cfg_pwm5_high ),
- .cfg_pwm5_low (cfg_pwm5_low ),
-
- // GPIO input pins
- .gpio_in_data (pad_gpio_in ),
- .gpio_int_event (gpio_int_event ),
-
- // GPIO config pins
- .cfg_gpio_out_data (cfg_gpio_out_data ),
- .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
- .cfg_gpio_out_type (cfg_gpio_out_type ),
- .cfg_gpio_posedge_int_sel (cfg_gpio_posedge_int_sel),
- .cfg_gpio_negedge_int_sel (cfg_gpio_negedge_int_sel),
- .cfg_multi_func_sel (cfg_multi_func_sel ),
- .cfg_gpio_data_in (cfg_gpio_data_in ),
-
-
- // Outputs
- .gpio_prev_indata (gpio_prev_indata ) ,
-
-
- .timer_intr (timer_intr ),
- .cfg_timer_update (cfg_timer_update ),
- .cfg_timer0 (cfg_timer0 ),
- .cfg_timer1 (cfg_timer1 ),
- .cfg_timer2 (cfg_timer2 )
-
-
- );
-
-
-// 6 PWM Waveform Generator
-pwm u_pwm_0 (
- .waveform (pwm_wfm[0] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[0] ),
- .cfg_pwm_high (cfg_pwm0_high ),
- .cfg_pwm_low (cfg_pwm0_low )
- );
-
-pwm u_pwm_1 (
- .waveform (pwm_wfm[1] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[1] ),
- .cfg_pwm_high (cfg_pwm1_high ),
- .cfg_pwm_low (cfg_pwm1_low )
- );
-
-pwm u_pwm_2 (
- .waveform (pwm_wfm[2] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[2] ),
- .cfg_pwm_high (cfg_pwm2_high ),
- .cfg_pwm_low (cfg_pwm2_low )
- );
-
-pwm u_pwm_3 (
- .waveform (pwm_wfm[3] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[3] ),
- .cfg_pwm_high (cfg_pwm3_high ),
- .cfg_pwm_low (cfg_pwm3_low )
- );
-pwm u_pwm_4 (
- .waveform (pwm_wfm[4] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[4] ),
- .cfg_pwm_high (cfg_pwm4_high ),
- .cfg_pwm_low (cfg_pwm4_low )
- );
-pwm u_pwm_5 (
- .waveform (pwm_wfm[5] ),
- .h_reset_n (sreset_n ),
- .mclk (mclk ),
- .pulse1m_mclk (pulse_1ms ),
- .cfg_pwm_enb (cfg_pwm_enb[5] ),
- .cfg_pwm_high (cfg_pwm5_high ),
- .cfg_pwm_low (cfg_pwm5_low )
- );
-
/************************************************
* Pin Mapping ATMGE CONFIG
* ATMEGA328 caravel Pin Mapping
@@ -559,6 +86,99 @@
* Pin-1 RESET is not supported as there is no suppport for fuse config
**************/
+module pinmux (
+ // Digital IO
+ output logic [37:0] digital_io_out ,
+ output logic [37:0] digital_io_oen ,
+ input logic [37:0] digital_io_in ,
+
+ // Config
+ input logic [31:0] cfg_gpio_dir_sel ,
+ input logic [31:0] cfg_multi_func_sel ,
+
+ output logic[5:0] cfg_pwm_enb ,
+ input logic [5:0] pwm_wfm ,
+ output logic [1:0] ext_intr_in , // External PAD level interrupt
+ output logic [31:0] pad_gpio_in , // GPIO data input from PAD
+ input logic [31:0] pad_gpio_out , // GPIO Data out towards PAD
+
+ // SFLASH I/F
+ input logic sflash_sck ,
+ input logic [3:0] sflash_ss ,
+ input logic [3:0] sflash_oen ,
+ input logic [3:0] sflash_do ,
+ output logic [3:0] sflash_di ,
+
+ // SSRAM I/F - Temp Masked
+ //input logic ssram_sck,
+ //input logic ssram_ss,
+ //input logic [3:0] ssram_oen,
+ //input logic [3:0] ssram_do,
+ //output logic [3:0] ssram_di,
+
+ // USB I/F
+ input logic usb_dp_o,
+ input logic usb_dn_o,
+ input logic usb_oen,
+ output logic usb_dp_i,
+ output logic usb_dn_i,
+
+ // UART I/F
+ input logic [1:0] uart_txd,
+ output logic [1:0] uart_rxd,
+
+ // I2CM I/F
+ input logic i2cm_clk_o,
+ output logic i2cm_clk_i,
+ input logic i2cm_clk_oen,
+ input logic i2cm_data_oen,
+ input logic i2cm_data_o,
+ output logic i2cm_data_i,
+
+ // SPI MASTER
+ input logic spim_sck,
+ input logic [3:0] spim_ssn,
+ input logic spim_miso,
+ output logic spim_mosi,
+
+ // SPI SLAVE
+ output logic spis_sck,
+ output logic spis_ssn,
+ input logic spis_miso,
+ output logic spis_mosi,
+
+ // UART MASTER I/F
+ output logic uartm_rxd ,
+ input logic uartm_txd ,
+
+ input logic dbg_clk_mon
+
+ );
+
+
+
+reg [7:0] port_a_in; // PORT A Data In
+reg [7:0] port_b_in; // PORT B Data In
+reg [7:0] port_c_in; // PORT C Data In
+reg [7:0] port_d_in; // PORT D Data In
+
+wire [7:0] port_a_out; // PORT A Data Out
+wire [7:0] port_b_out; // PORT B Data Out
+wire [7:0] port_c_out; // PORT C Data Out
+wire [7:0] port_d_out; // PORT D Data Out
+
+// GPIO to PORT Mapping
+assign pad_gpio_in[7:0] = port_a_in;
+assign pad_gpio_in[15:8] = port_b_in;
+assign pad_gpio_in[23:16] = port_c_in;
+assign pad_gpio_in[31:24] = port_d_in;
+
+assign port_a_out = pad_gpio_out[7:0];
+assign port_b_out = pad_gpio_out[15:8];
+assign port_c_out = pad_gpio_out[23:16];
+assign port_d_out = pad_gpio_out[31:24];
+
+
assign cfg_pwm_enb = cfg_multi_func_sel[5:0];
wire [1:0] cfg_int_enb = cfg_multi_func_sel[7:6];
wire [1:0] cfg_uart_enb = cfg_multi_func_sel[9:8];
diff --git a/verilog/rtl/pinmux/src/pinmux_reg.sv b/verilog/rtl/pinmux/src/pinmux_reg.sv
deleted file mode 100644
index 744c07b..0000000
--- a/verilog/rtl/pinmux/src/pinmux_reg.sv
+++ /dev/null
@@ -1,902 +0,0 @@
-//////////////////////////////////////////////////////////////////////////////
-// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-// SPDX-License-Identifier: Apache-2.0
-// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
-//
-//////////////////////////////////////////////////////////////////////
-//// ////
-//// Pinmux Register ////
-//// ////
-//// This file is part of the riscduino cores project ////
-//// https://github.com/dineshannayya/riscduino.git ////
-//// ////
-//// Description ////
-//// Hold all the Global and PinMux Register ////
-//// ////
-//// To Do: ////
-//// nothing ////
-//// ////
-//// Author(s): ////
-//// - Dinesh Annayya, dinesha@opencores.org ////
-//// ////
-//// Revision : ////
-//// 0.1 - 16th Feb 2021, Dinesh A ////
-//// initial version ////
-//////////////////////////////////////////////////////////////////////
-//
-module pinmux_reg (
- // System Signals
- // Inputs
- input logic mclk,
- input logic h_reset_n,
-
- // Global Reset control
- output logic [1:0] cpu_core_rst_n ,
- output logic cpu_intf_rst_n ,
- output logic qspim_rst_n ,
- output logic sspim_rst_n ,
- output logic [1:0] uart_rst_n ,
- output logic i2cm_rst_n ,
- output logic usb_rst_n ,
-
- // Reg Bus Interface Signal
- input logic reg_cs,
- input logic reg_wr,
- input logic [7:0] reg_addr,
- input logic [31:0] reg_wdata,
- input logic [3:0] reg_be,
-
- // Outputs
- output logic [31:0] reg_rdata,
- output logic reg_ack,
-
- input logic [1:0] ext_intr_in,
-
- // Risc configuration
- output logic [15:0] irq_lines,
- output logic soft_irq,
- output logic [2:0] user_irq,
- input logic usb_intr,
- input logic i2cm_intr,
-
- output logic [9:0] cfg_pulse_1us,
- output logic [15:0] cfg_riscv_ctrl,
-
- //---------------------------------------------------
- // 6 PWM Configuration
- //---------------------------------------------------
-
- output logic [15:0] cfg_pwm0_high ,
- output logic [15:0] cfg_pwm0_low ,
- output logic [15:0] cfg_pwm1_high ,
- output logic [15:0] cfg_pwm1_low ,
- output logic [15:0] cfg_pwm2_high ,
- output logic [15:0] cfg_pwm2_low ,
- output logic [15:0] cfg_pwm3_high ,
- output logic [15:0] cfg_pwm3_low ,
- output logic [15:0] cfg_pwm4_high ,
- output logic [15:0] cfg_pwm4_low ,
- output logic [15:0] cfg_pwm5_high ,
- output logic [15:0] cfg_pwm5_low ,
-
- // GPIO input pins
- input logic [31:0] gpio_in_data ,// GPIO I/P pins
- input logic [31:0] gpio_int_event ,// from gpio control blk
-
-
-
- // GPIO config pins
- output logic [31:0] cfg_gpio_out_data ,// to the GPIO control block
- output logic [31:0] cfg_gpio_data_in ,// GPIO I/P pins data captured into this
- output logic [31:0] cfg_gpio_dir_sel ,// decides on GPIO pin is I/P or O/P at pad level
- output logic [31:0] cfg_gpio_out_type ,// O/P is static , '1' : waveform
- output logic [31:0] cfg_gpio_posedge_int_sel ,// select posedge interrupt
- output logic [31:0] cfg_gpio_negedge_int_sel ,// select negedge interrupt
- output logic [31:0] cfg_multi_func_sel ,// multifunction pins
-
- // Outputs
- output logic [31:0] gpio_prev_indata ,// prv data from GPIO I/P pins
-
- input logic [2:0] timer_intr ,
- output logic [2:0] cfg_timer_update ,
- output logic [31:0] cfg_timer0 ,
- output logic [31:0] cfg_timer1 ,
- output logic [31:0] cfg_timer2
- );
-
-
-
-//-----------------------------------------------------------------------
-// Internal Wire Declarations
-//-----------------------------------------------------------------------
-
-logic sw_rd_en ;
-logic sw_wr_en;
-logic [4:0] sw_addr; // addressing 16 registers
-logic [31:0] sw_reg_wdata;
-logic [3:0] wr_be ;
-
-logic [31:0] reg_out;
-logic [31:0] reg_0; // Chip ID
-logic [31:0] reg_1; // Risc Fuse Id
-logic [31:0] reg_2; // Global config-1
-logic [31:0] reg_3; // Global config-2
-logic [31:0] reg_4; // GPIO Read Data
-logic [31:0] reg_5; // GPIO Output Data
-logic [31:0] reg_6; // GPIO Dir Sel
-logic [31:0] reg_7; // GPIO Type
-logic [31:0] reg_8; // Interrupt
-logic [31:0] reg_9; // GPIO Interrupt Status
-logic [31:0] reg_10; // GPIO Interrupt Status
-logic [31:0] reg_11; // GPIO Interrupt Mask
-logic [31:0] reg_12; // GPIO Posedge Interrupt Select
-logic [31:0] reg_13; // GPIO Negedge Interrupt Select
-logic [31:0] reg_14; // Software-Reg_14
-logic [31:0] reg_15; // Software-Reg_15
-logic [31:0] reg_16; // PWN-0 Config
-logic [31:0] reg_17; // PWN-1 Config
-logic [31:0] reg_18; // PWN-2 Config
-logic [31:0] reg_19; // PWN-3 Config
-logic [31:0] reg_20; // PWN-4 Config
-logic [31:0] reg_21; // PWN-5 Config
-logic [31:0] reg_22; // Software-Reg1
-logic [31:0] reg_23; // Software-Reg2
-logic [31:0] reg_24; // Software-Reg3
-logic [31:0] reg_25; // Software-Reg4
-logic [31:0] reg_26; // Software-Reg5
-logic [31:0] reg_27; // Software-Reg6
-logic [31:0] reg_28; // Software-Reg6
-logic [31:0] reg_29; // Software-Reg6
-logic [31:0] reg_30; // Software-Reg6
-
-
-logic cs_int;
-logic gpio_intr;
-
-
-assign sw_addr = reg_addr [6:2];
-assign sw_rd_en = reg_cs & !reg_wr;
-assign sw_wr_en = reg_cs & reg_wr;
-assign wr_be = reg_be;
-assign sw_reg_wdata = reg_wdata;
-
-
-//-----------------------------------
-// Edge detection for Logic Bist
-// ----------------------------------
-
-logic wb_req;
-logic wb_req_d;
-logic wb_req_pedge;
-
-always_ff @(negedge h_reset_n or posedge mclk) begin
- if ( h_reset_n == 1'b0 ) begin
- wb_req <= '0;
- wb_req_d <= '0;
- end else begin
- wb_req <= reg_cs && (reg_ack == 0) ;
- wb_req_d <= wb_req;
- end
-end
-
-// Detect pos edge of request
-assign wb_req_pedge = (wb_req_d ==0) && (wb_req==1'b1);
-
-
-always @ (posedge mclk or negedge h_reset_n)
-begin : preg_out_Seq
- if (h_reset_n == 1'b0) begin
- reg_rdata <= 'h0;
- reg_ack <= 1'b0;
- end else if (reg_cs && !reg_ack) begin
- reg_rdata <= reg_out ;
- reg_ack <= 1'b1;
- end else begin
- reg_ack <= 1'b0;
- end
-end
-
-
-
-//-----------------------------------------------------------------------
-// register read enable and write enable decoding logic
-//-----------------------------------------------------------------------
-wire sw_wr_en_0 = sw_wr_en & (sw_addr == 5'h0);
-wire sw_wr_en_1 = sw_wr_en & (sw_addr == 5'h1);
-wire sw_wr_en_2 = sw_wr_en & (sw_addr == 5'h2);
-wire sw_wr_en_3 = sw_wr_en & (sw_addr == 5'h3);
-wire sw_wr_en_4 = sw_wr_en & (sw_addr == 5'h4);
-wire sw_wr_en_5 = sw_wr_en & (sw_addr == 5'h5);
-wire sw_wr_en_6 = sw_wr_en & (sw_addr == 5'h6);
-wire sw_wr_en_7 = sw_wr_en & (sw_addr == 5'h7);
-wire sw_wr_en_8 = sw_wr_en & (sw_addr == 5'h8);
-wire sw_wr_en_9 = sw_wr_en & (sw_addr == 5'h9);
-wire sw_wr_en_10 = sw_wr_en & (sw_addr == 5'hA);
-wire sw_wr_en_11 = sw_wr_en & (sw_addr == 5'hB);
-wire sw_wr_en_12 = sw_wr_en & (sw_addr == 5'hC);
-wire sw_wr_en_13 = sw_wr_en & (sw_addr == 5'hD);
-wire sw_wr_en_14 = sw_wr_en & (sw_addr == 5'hE);
-wire sw_wr_en_15 = sw_wr_en & (sw_addr == 5'hF);
-wire sw_wr_en_16 = sw_wr_en & (sw_addr == 5'h10);
-wire sw_wr_en_17 = sw_wr_en & (sw_addr == 5'h11);
-wire sw_wr_en_18 = sw_wr_en & (sw_addr == 5'h12);
-wire sw_wr_en_19 = sw_wr_en & (sw_addr == 5'h13);
-wire sw_wr_en_20 = sw_wr_en & (sw_addr == 5'h14);
-wire sw_wr_en_21 = sw_wr_en & (sw_addr == 5'h15);
-
-wire sw_wr_en_22 = sw_wr_en & (sw_addr == 5'h16);
-wire sw_wr_en_23 = sw_wr_en & (sw_addr == 5'h17);
-wire sw_wr_en_24 = sw_wr_en & (sw_addr == 5'h18);
-wire sw_wr_en_25 = sw_wr_en & (sw_addr == 5'h19);
-wire sw_wr_en_26 = sw_wr_en & (sw_addr == 5'h1A);
-wire sw_wr_en_27 = sw_wr_en & (sw_addr == 5'h1B);
-wire sw_wr_en_28 = sw_wr_en & (sw_addr == 5'h1C);
-wire sw_wr_en_29 = sw_wr_en & (sw_addr == 5'h1D);
-wire sw_wr_en_30 = sw_wr_en & (sw_addr == 5'h1E);
-wire sw_wr_en_31 = sw_wr_en & (sw_addr == 5'h1F);
-
-wire sw_rd_en_28 = sw_rd_en & (sw_addr == 5'h1C);
-wire sw_rd_en_29 = sw_rd_en & (sw_addr == 5'h1D);
-wire sw_rd_en_30 = sw_rd_en & (sw_addr == 5'h1E);
-wire sw_rd_en_31 = sw_rd_en & (sw_addr == 5'h1F);
-
-
-//-----------------------------------------------------------------------
-// Individual register assignments
-//-----------------------------------------------------------------------
-
-
-// Chip ID
-// chip-id[3:0] mapping
-// 0 - YIFIVE (MPW-2)
-// 1 - Riscdunio (MPW-3)
-// 2 - Riscdunio (MPW-4)
-// 3 - Riscdunio (MPW-5)
-
-wire [15:0] manu_id = 16'h8268; // Asci value of RD
-wire [3:0] total_core = 4'h2;
-wire [3:0] chip_id = 4'h3;
-wire [7:0] chip_rev = 8'h01;
-
-assign reg_0 = {manu_id,total_core,chip_id,chip_rev};
-
-
-//------------------------------------------
-// reg-2: GLBL_CFG_0
-//------------------------------------------
-wire [31:0] cfg_glb_ctrl = reg_1;
-
-ctech_buf u_buf_cpu_intf_rst (.A(cfg_glb_ctrl[0]),.X(cpu_intf_rst_n));
-ctech_buf u_buf_qspim_rst (.A(cfg_glb_ctrl[1]),.X(qspim_rst_n));
-ctech_buf u_buf_sspim_rst (.A(cfg_glb_ctrl[2]),.X(sspim_rst_n));
-ctech_buf u_buf_uart0_rst (.A(cfg_glb_ctrl[3]),.X(uart_rst_n[0]));
-ctech_buf u_buf_i2cm_rst (.A(cfg_glb_ctrl[4]),.X(i2cm_rst_n));
-ctech_buf u_buf_usb_rst (.A(cfg_glb_ctrl[5]),.X(usb_rst_n));
-ctech_buf u_buf_uart1_rst (.A(cfg_glb_ctrl[6]),.X(uart_rst_n[1]));
-
-ctech_buf u_buf_cpu0_rst (.A(cfg_glb_ctrl[8]),.X(cpu_core_rst_n[0]));
-ctech_buf u_buf_cpu1_rst (.A(cfg_glb_ctrl[9]),.X(cpu_core_rst_n[1]));
-
-gen_32b_reg #(32'h0) u_reg_1 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_1 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_1 )
- );
-
-//----------------------------------------------
-// reg-2: GLBL_CFG_1
-//------------------------------------------
-
-gen_32b_reg #(32'h0) u_reg_2 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_2 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_2 )
- );
-
-assign cfg_pulse_1us = reg_2[9:0];
-assign cfg_riscv_ctrl = reg_2[31:16];
-
-//-----------------------------------------------------------------------
-// reg-3 : Global Interrupt Mask
-//-----------------------------------------------------------------------
-
-gen_32b_reg #(32'h0) u_reg_3 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_3 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_3 )
- );
-
-//-----------------------------------------------------------------------
-// reg-4 : Global Interrupt Status
-//-----------------------------------------------------------------
-assign irq_lines = reg_3[15:0] & reg_4[15:0];
-assign soft_irq = reg_3[16] & reg_4[16];
-assign user_irq = reg_3[19:17]& reg_4[19:17];
-
-
-generic_register #(8,0 ) u_reg4_be0 (
- .we ({8{sw_wr_en_4 &
- wr_be[0] }} ),
- .data_in (sw_reg_wdata[7:0] ),
- .reset_n (h_reset_n ),
- .clk (mclk ),
-
- //List of Outs
- .data_out (reg_4[7:0] )
- );
-
-
-wire [7:0] hware_intr_req = {gpio_intr, ext_intr_in[1:0], usb_intr, i2cm_intr,timer_intr[2:0]};
-
-generic_intr_stat_reg #(.WD(8),
- .RESET_DEFAULT(0)) u_reg4_be1 (
- //inputs
- .clk (mclk ),
- .reset_n (h_reset_n ),
- .reg_we ({8{sw_wr_en_4 & reg_ack &
- wr_be[1] }} ),
- .reg_din (sw_reg_wdata[15:8] ),
- .hware_req (hware_intr_req ),
-
- //outputs
- .data_out (reg_4[15:8] )
- );
-
-
-
-generic_register #(4,0 ) u_reg4_be2 (
- .we ({4{sw_wr_en_4 &
- wr_be[2] }} ),
- .data_in (sw_reg_wdata[19:16]),
- .reset_n (h_reset_n ),
- .clk (mclk ),
-
- //List of Outs
- .data_out (reg_4[19:16] )
- );
-
-assign reg_4[31:20] = '0;
-
-
-//-----------------------------------------------------------------------
-// Logic for gpio_data_in
-//-----------------------------------------------------------------------
-logic [31:0] gpio_in_data_s;
-logic [31:0] gpio_in_data_ss;
-// Double Sync the gpio pin data for edge detection
-always @ (posedge mclk or negedge h_reset_n)
-begin
- if (h_reset_n == 1'b0) begin
- reg_5 <= 'h0 ;
- gpio_in_data_s <= 32'd0;
- gpio_in_data_ss <= 32'd0;
- end
- else begin
- gpio_in_data_s <= gpio_in_data;
- gpio_in_data_ss <= gpio_in_data_s;
- reg_5 <= gpio_in_data_ss;
- end
-end
-
-
-assign cfg_gpio_data_in = reg_5[31:0]; // to be used for edge interrupt detect
-assign gpio_prev_indata = gpio_in_data_ss;
-
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_out_data
-//-----------------------------------------------------------------------
-assign cfg_gpio_out_data = reg_6[31:0]; // data to the GPIO control blk
-
-gen_32b_reg #(32'h0) u_reg_6 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_6 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_6 )
- );
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_dir_sel
-//-----------------------------------------------------------------------
-assign cfg_gpio_dir_sel = reg_7[31:0]; // data to the GPIO O/P pins
-
-gen_32b_reg #(32'h0) u_reg_7 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_7 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_7 )
- );
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_out_type
-//-----------------------------------------------------------------------
-assign cfg_gpio_out_type = reg_8[31:0]; // to be used for read
-
-gen_32b_reg #(32'h0) u_reg_8 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_8 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_8 )
- );
-
-
-
-//-----------------------------------------------------------------------
-// Logic for cfg_int_status
-// Always update int_status, even if no register write is occuring.
-// Interrupt posting is higher priority than int clear by host
-//-----------------------------------------------------------------------
-wire [31:0] cfg_gpio_int_status = reg_9[31:0]; // to be used for read
-
-//--------------------------------------------------------
-// Interrupt Status Generation
-// Note: Reg_9 --> Interrupt Status Register, Writting '1' will clear the
-// corresponding interrupt status bit. Writting '0' has no
-// effect
-// Reg_10 --> Writting one to this register will set the interrupt in
-// interrupt status register (reg_9), Writting '0' does not has any
-// effect.
-/// Always update int_status, even if no register write is occuring.
-// Interrupt posting is higher priority than int clear by host
-//--------------------------------------------------------
-wire [31:0] gpio_int_status = reg_9;
-
-generic_intr_stat_reg #(.WD(32),
- .RESET_DEFAULT(0)) u_reg_9 (
- //inputs
- .clk (mclk ),
- .reset_n (h_reset_n ),
- .reg_we ({
- {8{sw_wr_en_9 & reg_ack & wr_be[2]}},
- {8{sw_wr_en_9 & reg_ack & wr_be[2]}},
- {8{sw_wr_en_9 & reg_ack & wr_be[1]}},
- {8{sw_wr_en_9 & reg_ack & wr_be[0]}}
- } ),
- .reg_din (sw_reg_wdata[31:0] ),
- .hware_req (gpio_int_event | {
- {8{sw_wr_en_10 & reg_ack}} & sw_reg_wdata[31:24],
- {8{sw_wr_en_10 & reg_ack}} & sw_reg_wdata[23:16],
- {8{sw_wr_en_10 & reg_ack}} & sw_reg_wdata[15:8] ,
- {8{sw_wr_en_10 & reg_ack}} & sw_reg_wdata[7:0]
- } ),
-
- //outputs
- .data_out (reg_9[31:0] )
- );
-//-------------------------------------------------
-// Returns same value as interrupt status register
-//------------------------------------------------
-
-assign reg_10 = reg_9;
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_int_mask : GPIO interrupt mask
-//-----------------------------------------------------------------------
-wire [31:0] cfg_gpio_int_mask = reg_11[31:0]; // to be used for read
-
-assign gpio_intr = ( | (reg_9 & reg_11) ); // interrupt pin to the RISC
-
-
-// Register-11
-gen_32b_reg #(32'h0) u_reg_11 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_11 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_11 )
- );
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_posedge_int_sel : Enable posedge GPIO interrupt
-//-----------------------------------------------------------------------
-assign cfg_gpio_posedge_int_sel = reg_12[31:0]; // to be used for read
-gen_32b_reg #(32'h0) u_reg_12 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_12 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_12 )
- );
-//-----------------------------------------------------------------------
-// Logic for cfg_gpio_negedge_int_sel : Enable negedge GPIO interrupt
-//-----------------------------------------------------------------------
-assign cfg_gpio_negedge_int_sel = reg_13[31:0]; // to be used for read
-gen_32b_reg #(32'h0) u_reg_13 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_13 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_13 )
- );
-
-//-----------------------------------------------------------------------
-// Logic for cfg_multi_func_sel :Enable GPIO to act as multi function pins
-//-----------------------------------------------------------------------
-assign cfg_multi_func_sel = reg_14[31:0]; // to be used for read
-
-
-gen_32b_reg #(32'h0) u_reg_14 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_14 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_14 )
- );
-
-// Reg-15
-gen_32b_reg #(32'h0) u_reg_15 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_15 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_15 )
- );
-//-----------------------------------------------------------------------
-// Logic for PWM-0 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm0_low = reg_16[15:0]; // low period of w/f
-assign cfg_pwm0_high = reg_16[31:16]; // high period of w/f
-
-gen_32b_reg #(32'h0) u_reg_16 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_16 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_16 )
- );
-
-
-//-----------------------------------------------------------------------
-// Logic for PWM-1 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm1_low = reg_17[15:0]; // low period of w/f
-assign cfg_pwm1_high = reg_17[31:16]; // high period of w/f
-gen_32b_reg #(32'h0) u_reg_17 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_17 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_17 )
- );
-
-//-----------------------------------------------------------------------
-// Logic for PWM-2 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm2_low = reg_18[15:0]; // low period of w/f
-assign cfg_pwm2_high = reg_18[31:16]; // high period of w/f
-gen_32b_reg #(32'h0) u_reg_18 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_18 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_18 )
- );
-
-//-----------------------------------------------------------------------
-// Logic for PWM-3 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm3_low = reg_19[15:0]; // low period of w/f
-assign cfg_pwm3_high = reg_19[31:16]; // high period of w/f
-gen_32b_reg #(32'h0) u_reg_19 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_19 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_19 )
- );
-
-//-----------------------------------------------------------------------
-// Logic for PWM-4 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm4_low = reg_20[15:0]; // low period of w/f
-assign cfg_pwm4_high = reg_20[31:16]; // high period of w/f
-
-gen_32b_reg #(32'h0) u_reg_20 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_20 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_20 )
- );
-
-//-----------------------------------------------------------------------
-// Logic for PWM-5 Config
-//-----------------------------------------------------------------------
-assign cfg_pwm5_low = reg_21[15:0]; // low period of w/f
-assign cfg_pwm5_high = reg_21[31:16]; // high period of w/f
-
-gen_32b_reg #(32'h0) u_reg_21 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_21 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_21 )
- );
-
-
-//-----------------------------------------
-// Software Reg-1 : ASCI Representation of RISC = 32'h8273_8343
-// ----------------------------------------
-gen_32b_reg #(32'h8273_8343) u_reg_22 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_22 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_22 )
- );
-
-//-----------------------------------------
-// Software Reg-2, Release date: <DAY><MONTH><YEAR>
-// ----------------------------------------
-gen_32b_reg #(32'h2007_2022) u_reg_23 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_23 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_23 )
- );
-
-//-----------------------------------------
-// Software Reg-3: Poject Revison 4.7 = 0004800
-// ----------------------------------------
-gen_32b_reg #(32'h0004_8000) u_reg_24 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_24 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_24 )
- );
-
-//-----------------------------------------
-// Software Reg-4
-// ----------------------------------------
-gen_32b_reg #(32'h0) u_reg_25 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_25 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_25 )
- );
-
-//-----------------------------------------
-// Software Reg-5
-// ----------------------------------------
-gen_32b_reg #(32'h0) u_reg_26 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_26 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_26 )
- );
-
-//-----------------------------------------
-// Software Reg-6
-// ----------------------------------------
-gen_32b_reg #(32'h0) u_reg_27 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_27 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_27 )
- );
-
-
-//-----------------------------------------------------------------------
-// reg-28
-// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
-// In first cycle, local register will be updated
-// In second cycle, update indication sent to timer block
-// -----------------------------------------------------------------
-assign cfg_timer0 = reg_28[18:0];
-assign cfg_timer_update[0] = sw_wr_en_28 & reg_ack;
-
-gen_32b_reg #(32'h0) u_reg_28 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_28 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_28[31:0] )
- );
-
-//-----------------------------------------------------------------------
-// reg-29
-// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
-// In first cycle, local register will be updated
-// In second cycle, update indication sent to timer block
-// -----------------------------------------------------------------
-assign cfg_timer1 = reg_29[18:0];
-assign cfg_timer_update[1] = sw_wr_en_29 & reg_ack;
-
-gen_32b_reg #(32'h0) u_reg_29 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_29 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_29[31:0] )
- );
-
-
-//-----------------------------------------------------------------------
-// reg-30
-// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
-// In first cycle, local register will be updated
-// In second cycle, update indication sent to timer block
-// -----------------------------------------------------------------
-assign cfg_timer2 = reg_30[18:0];
-assign cfg_timer_update[2] = sw_wr_en_30 & reg_ack;
-
-gen_32b_reg #(32'h0) u_reg_30 (
- //List of Inputs
- .reset_n (h_reset_n ),
- .clk (mclk ),
- .cs (sw_wr_en_30 ),
- .we (wr_be ),
- .data_in (sw_reg_wdata ),
-
- //List of Outs
- .data_out (reg_30[31:0] )
- );
-
-//-----------------------------------------------------------------------
-// Register Read Path Multiplexer instantiation
-//-----------------------------------------------------------------------
-
-always_comb
-begin
- reg_out [31:0] = 32'h0;
-
- case (sw_addr [4:0])
- 5'b00000 : reg_out [31:0] = reg_0 [31:0];
- 5'b00001 : reg_out [31:0] = reg_1 [31:0];
- 5'b00010 : reg_out [31:0] = reg_2 [31:0];
- 5'b00011 : reg_out [31:0] = reg_3 [31:0];
- 5'b00100 : reg_out [31:0] = reg_4 [31:0];
- 5'b00101 : reg_out [31:0] = reg_5 [31:0];
- 5'b00110 : reg_out [31:0] = reg_6 [31:0];
- 5'b00111 : reg_out [31:0] = reg_7 [31:0];
- 5'b01000 : reg_out [31:0] = reg_8 [31:0];
- 5'b01001 : reg_out [31:0] = reg_9 [31:0];
- 5'b01010 : reg_out [31:0] = reg_10 [31:0];
- 5'b01011 : reg_out [31:0] = reg_11 [31:0];
- 5'b01100 : reg_out [31:0] = reg_12 [31:0];
- 5'b01101 : reg_out [31:0] = reg_13 [31:0];
- 5'b01110 : reg_out [31:0] = reg_14 [31:0];
- 5'b01111 : reg_out [31:0] = reg_15 [31:0];
- 5'b10000 : reg_out [31:0] = reg_16 [31:0];
- 5'b10001 : reg_out [31:0] = reg_17 [31:0];
- 5'b10010 : reg_out [31:0] = reg_18 [31:0];
- 5'b10011 : reg_out [31:0] = reg_19 [31:0];
- 5'b10100 : reg_out [31:0] = reg_20 [31:0];
- 5'b10101 : reg_out [31:0] = reg_21 [31:0];
- 5'b10110 : reg_out [31:0] = reg_22 [31:0];
- 5'b10111 : reg_out [31:0] = reg_23 [31:0];
- 5'b11000 : reg_out [31:0] = reg_24 [31:0];
- 5'b11001 : reg_out [31:0] = reg_25 [31:0];
- 5'b11010 : reg_out [31:0] = reg_26 [31:0];
- 5'b11011 : reg_out [31:0] = reg_27 [31:0];
- 5'b11100 : reg_out [31:0] = reg_28 [31:0];
- 5'b11101 : reg_out [31:0] = reg_29 [31:0];
- 5'b11110 : reg_out [31:0] = reg_30 [31:0];
- 5'b11111 : reg_out [31:0] = 32'h0;
- default : reg_out [31:0] = 32'h0;
- endcase
-end
-
-
-endmodule
diff --git a/verilog/rtl/pinmux/src/pinmux_top.sv b/verilog/rtl/pinmux/src/pinmux_top.sv
new file mode 100755
index 0000000..c84c1a7
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pinmux_top.sv
@@ -0,0 +1,485 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Pinmux ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// PinMux Manages all the pin multiplexing ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 16th Feb 2021, Dinesh A ////
+//// initial version ////
+//// 0.2 - 6 April 2021, Dinesh A ////
+//// 1. SSPI CS# increased from 1 to 4 ////
+// 2. UART I/F increase from 1 to 2 ////
+//// 0.3 - 8 July 2022, Dinesh A ////
+//// In ardunio, SPI chip select are control through ////
+//// GPIO, So we have moved the Auto generated SPI CS ////
+//// different config bit. I2C config position moved from////
+//// bit[14] to bit [15] ////
+//// 0.4 - 20 July 2022, Dinesh A ////
+//// On Power On, If RESET* = 0, then system will enter ////
+//// in to SPIS slave mode to support boot ////
+//////////////////////////////////////////////////////////////////////
+
+module pinmux_top (
+ `ifdef USE_POWER_PINS
+ input logic vccd1,// User area 1 1.8V supply
+ input logic vssd1,// User area 1 digital ground
+ `endif
+ // clock skew adjust
+ input logic [3:0] cfg_cska_pinmux,
+ input logic wbd_clk_int,
+ output logic wbd_clk_pinmux,
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Global Reset control
+ output logic [1:0] cpu_core_rst_n ,
+ output logic cpu_intf_rst_n ,
+ output logic qspim_rst_n ,
+ output logic sspim_rst_n ,
+ output logic [1:0] uart_rst_n ,
+ output logic i2cm_rst_n ,
+ output logic usb_rst_n ,
+
+ output logic [15:0] cfg_riscv_ctrl,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [8:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ // Risc configuration
+ output logic [15:0] irq_lines,
+ output logic soft_irq,
+ output logic [2:0] user_irq,
+ input logic usb_intr,
+ input logic i2cm_intr,
+
+ // Digital IO
+ output logic [37:0] digital_io_out,
+ output logic [37:0] digital_io_oen,
+ input logic [37:0] digital_io_in,
+
+ // SFLASH I/F
+ input logic sflash_sck,
+ input logic [3:0] sflash_ss,
+ input logic [3:0] sflash_oen,
+ input logic [3:0] sflash_do,
+ output logic [3:0] sflash_di,
+
+ // SSRAM I/F - Temp Masked
+ //input logic ssram_sck,
+ //input logic ssram_ss,
+ //input logic [3:0] ssram_oen,
+ //input logic [3:0] ssram_do,
+ //output logic [3:0] ssram_di,
+
+ // USB I/F
+ input logic usb_dp_o,
+ input logic usb_dn_o,
+ input logic usb_oen,
+ output logic usb_dp_i,
+ output logic usb_dn_i,
+
+ // UART I/F
+ input logic [1:0] uart_txd,
+ output logic [1:0] uart_rxd,
+
+ // I2CM I/F
+ input logic i2cm_clk_o,
+ output logic i2cm_clk_i,
+ input logic i2cm_clk_oen,
+ input logic i2cm_data_oen,
+ input logic i2cm_data_o,
+ output logic i2cm_data_i,
+
+ // SPI MASTER
+ input logic spim_sck,
+ input logic [3:0] spim_ssn,
+ input logic spim_miso,
+ output logic spim_mosi,
+
+ // SPI SLAVE
+ output logic spis_sck,
+ output logic spis_ssn,
+ input logic spis_miso,
+ output logic spis_mosi,
+
+ // UART MASTER I/F
+ output logic uartm_rxd ,
+ input logic uartm_txd ,
+
+ output logic pulse1m_mclk,
+ output logic [31:0] pinmux_debug,
+
+ input logic dbg_clk_mon
+
+ );
+
+
+
+logic sreset_n; // Sync Reset
+
+/* clock pulse */
+//********************************************************
+logic pulse_1ms ; // 1 Milli Second Pulse for waveform Generator
+logic [5:0] cfg_pwm_enb ;
+
+
+//---------------------------------------------------------
+// Timer Register
+// -------------------------------------------------------
+logic [2:0] timer_intr ;
+
+//---------------------------------------------------
+// 6 PWM variabled
+//---------------------------------------------------
+
+logic [5:0] pwm_wfm ;
+
+
+wire [31:0] cfg_gpio_dir_sel ;// decides on GPIO pin is I/P or O/P at pad level, 0 -> Input, 1 -> Output
+wire [31:0] cfg_gpio_out_type ;// GPIO Type, Unused
+wire [31:0] cfg_multi_func_sel ;// GPIO Multi function type
+
+
+reg [7:0] port_a_in; // PORT A Data In
+reg [7:0] port_b_in; // PORT B Data In
+reg [7:0] port_c_in; // PORT C Data In
+reg [7:0] port_d_in; // PORT D Data In
+
+wire [7:0] port_a_out; // PORT A Data Out
+wire [7:0] port_b_out; // PORT B Data Out
+wire [7:0] port_c_out; // PORT C Data Out
+wire [7:0] port_d_out; // PORT D Data Out
+wire [31:0] pad_gpio_in; // GPIO data input from PAD
+wire [31:0] pad_gpio_out; // GPIO Data out towards PAD
+wire [31:0] gpio_int_event; // GPIO Interrupt indication
+reg [1:0] ext_intr_in; // External PAD level interrupt
+
+
+assign pinmux_debug = '0; // Todo: Need to fix
+
+//------------------------------------------------------
+// Register Map Decoding
+
+`define SEL_GLBL 3'b000 // GLOBAL REGISTER
+`define SEL_GPIO 3'b001 // GPIO REGISTER
+`define SEL_PWM 3'b010 // PWM REGISTER
+`define SEL_TIMER 3'b011 // TIMER REGISTER
+`define SEL_SEMA 3'b100 // SEMAPHORE REGISTER
+
+
+//----------------------------------------
+// Register Response Path Mux
+// --------------------------------------
+logic [31:0] reg_glbl_rdata;
+logic reg_glbl_ack;
+
+logic [31:0] reg_gpio_rdata;
+logic reg_gpio_ack;
+
+logic [31:0] reg_pwm_rdata;
+logic reg_pwm_ack;
+
+logic [31:0] reg_timer_rdata;
+logic reg_timer_ack;
+
+logic [15:0] reg_sema_rdata;
+logic reg_sema_ack;
+
+
+assign reg_rdata = (reg_addr[8:6] == `SEL_GLBL) ? {reg_glbl_rdata} :
+ (reg_addr[8:6] == `SEL_GPIO) ? {reg_gpio_rdata} :
+ (reg_addr[8:6] == `SEL_PWM) ? {reg_pwm_rdata} :
+ (reg_addr[8:6] == `SEL_TIMER) ? reg_timer_rdata :
+ (reg_addr[8:6] == `SEL_SEMA) ? {16'h0,reg_sema_rdata} : 'h0;
+
+assign reg_ack = (reg_addr[8:6] == `SEL_GLBL) ? reg_glbl_ack :
+ (reg_addr[8:6] == `SEL_GPIO) ? reg_gpio_ack :
+ (reg_addr[8:6] == `SEL_PWM) ? reg_pwm_ack :
+ (reg_addr[8:6] == `SEL_TIMER) ? reg_timer_ack :
+ (reg_addr[8:6] == `SEL_SEMA) ? reg_sema_ack : 1'b0;
+
+wire reg_glbl_cs = (reg_addr[8:6] == `SEL_GLBL) ? reg_cs : 1'b0;
+wire reg_gpio_cs = (reg_addr[8:6] == `SEL_GPIO) ? reg_cs : 1'b0;
+wire reg_pwm_cs = (reg_addr[8:6] == `SEL_PWM) ? reg_cs : 1'b0;
+wire reg_timer_cs = (reg_addr[8:6] == `SEL_TIMER)? reg_cs : 1'b0;
+wire reg_sema_cs = (reg_addr[8:6] == `SEL_SEMA) ? reg_cs : 1'b0;
+
+//---------------------------------------------------------------------
+
+// SSRAM I/F - Temp masked
+//input logic ssram_sck,
+//input logic ssram_ss,
+//input logic [3:0] ssram_oen,
+//input logic [3:0] ssram_do,
+//output logic [3:0] ssram_di,
+
+// pinmux clock skew control
+clk_skew_adjust u_skew_pinmux
+ (
+`ifdef USE_POWER_PINS
+ .vccd1 (vccd1 ),// User area 1 1.8V supply
+ .vssd1 (vssd1 ),// User area 1 digital ground
+`endif
+ .clk_in (wbd_clk_int ),
+ .sel (cfg_cska_pinmux ),
+ .clk_out (wbd_clk_pinmux )
+ );
+
+reset_sync u_rst_sync (
+ .scan_mode (1'b0 ),
+ .dclk (mclk ), // Destination clock domain
+ .arst_n (h_reset_n ), // active low async reset
+ .srst_n (sreset_n )
+ );
+
+//------------------------------------------------------------------
+// Global Register
+//------------------------------------------------------------------
+glbl_reg u_glbl_reg(
+ // System Signals
+ // Inputs
+ .mclk (mclk ),
+ .h_reset_n (sreset_n ),
+
+ .cpu_core_rst_n (cpu_core_rst_n ),
+ .cpu_intf_rst_n (cpu_intf_rst_n ),
+ .qspim_rst_n (qspim_rst_n ),
+ .sspim_rst_n (sspim_rst_n ),
+ .uart_rst_n (uart_rst_n ),
+ .i2cm_rst_n (i2cm_rst_n ),
+ .usb_rst_n (usb_rst_n ),
+
+ .cfg_riscv_ctrl (cfg_riscv_ctrl ),
+ .cfg_multi_func_sel (cfg_multi_func_sel ),
+
+
+ // Reg read/write Interface Inputs
+ .reg_cs (reg_glbl_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ .reg_rdata (reg_glbl_rdata ),
+ .reg_ack (reg_glbl_ack ),
+
+ .ext_intr_in (ext_intr_in ),
+
+ .irq_lines (irq_lines ),
+ .soft_irq (soft_irq ),
+ .user_irq (user_irq ),
+ .usb_intr (usb_intr ),
+ .i2cm_intr (i2cm_intr ),
+
+
+
+ .timer_intr (timer_intr ),
+ .gpio_intr (gpio_intr )
+
+
+ );
+
+//-----------------------------------------------------------------------
+// GPIO Top
+//-----------------------------------------------------------------------
+gpio_top u_gpio(
+ // System Signals
+ // Inputs
+ .mclk ( mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_gpio_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_gpio_rdata ),
+ .reg_ack (reg_gpio_ack ),
+
+
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .pad_gpio_in (pad_gpio_in ),
+ .pad_gpio_out (pad_gpio_out ),
+
+ .gpio_intr (gpio_intr )
+
+
+ );
+
+//-----------------------------------------------------------------------
+// PWM Top
+//-----------------------------------------------------------------------
+pwm_top u_pwm(
+ // System Signals
+ // Inputs
+ .mclk ( mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_pwm_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[4:2] ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_pwm_rdata ),
+ .reg_ack (reg_pwm_ack ),
+
+ .pulse_1ms (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb ),
+ .pwm_wfm (pwm_wfm )
+ );
+
+//-----------------------------------------------------------------------
+// Timer Top
+//-----------------------------------------------------------------------
+timer_top u_timer(
+ // System Signals
+ // Inputs
+ .mclk ( mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_timer_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[3:2] ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_timer_rdata ),
+ .reg_ack (reg_timer_ack ),
+
+ .pulse_1ms (pulse_1ms ),
+ .timer_intr (timer_intr )
+ );
+
+//-----------------------------------------------------------------------
+// Semaphore Register
+//-----------------------------------------------------------------------
+semaphore_reg u_semaphore(
+ // System Signals
+ // Inputs
+ .mclk ( mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_sema_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr[5:2] ),
+ .reg_wdata (reg_wdata[15:0] ),
+ .reg_be (reg_be[1:0] ),
+
+ // Outputs
+ .reg_rdata (reg_sema_rdata ),
+ .reg_ack (reg_sema_ack )
+ );
+
+
+pinmux u_pinmux (
+ // Digital IO
+ .digital_io_out (digital_io_out ),
+ .digital_io_oen (digital_io_oen ),
+ .digital_io_in (digital_io_in ),
+
+ // Config
+ .cfg_gpio_dir_sel (cfg_gpio_dir_sel ),
+ .cfg_multi_func_sel (cfg_multi_func_sel ),
+
+ .cfg_pwm_enb (cfg_pwm_enb ),
+ .pwm_wfm (pwm_wfm ),
+ .ext_intr_in (ext_intr_in ), // External PAD level interrupt
+ .pad_gpio_in (pad_gpio_in ), // GPIO data input from PAD
+ .pad_gpio_out (pad_gpio_out ), // GPIO Data out towards PAD
+
+ // SFLASH I/F
+ .sflash_sck (sflash_sck ),
+ .sflash_ss (sflash_ss ),
+ .sflash_oen (sflash_oen ),
+ .sflash_do (sflash_do ),
+ .sflash_di (sflash_di ),
+
+ // USB I/F
+ .usb_dp_o (usb_dp_o ),
+ .usb_dn_o (usb_dn_o ),
+ .usb_oen (usb_oen ),
+ .usb_dp_i (usb_dp_i ),
+ .usb_dn_i (usb_dn_i ),
+
+ // UART I/F
+ .uart_txd (uart_txd ),
+ .uart_rxd (uart_rxd ),
+
+ // I2CM I/F
+ .i2cm_clk_o (i2cm_clk_o ),
+ .i2cm_clk_i (i2cm_clk_i ),
+ .i2cm_clk_oen (i2cm_clk_oen ),
+ .i2cm_data_oen (i2cm_data_oen ),
+ .i2cm_data_o (i2cm_data_o ),
+ .i2cm_data_i (i2cm_data_i ),
+
+ // SPI MASTER
+ .spim_sck (spim_sck ),
+ .spim_ssn (spim_ssn ),
+ .spim_miso (spim_miso ),
+ .spim_mosi (spim_mosi ),
+
+ // SPI SLAVE
+ .spis_sck (spis_sck ),
+ .spis_ssn (spis_ssn ),
+ .spis_miso (spis_miso ),
+ .spis_mosi (spis_mosi ),
+
+ // UART MASTER I/F
+ .uartm_rxd (uartm_rxd ),
+ .uartm_txd (uartm_txd ),
+
+ .dbg_clk_mon (dbg_clk_mon )
+
+ );
+
+endmodule
+
+
diff --git a/verilog/rtl/pinmux/src/pwm_reg.sv b/verilog/rtl/pinmux/src/pwm_reg.sv
new file mode 100644
index 0000000..702c138
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pwm_reg.sv
@@ -0,0 +1,255 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// PWM Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module pwm_reg (
+ // System Signals
+ // Inputs
+ input logic mclk ,
+ input logic h_reset_n ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [2:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ output logic [15:0] cfg_pwm0_high ,
+ output logic [15:0] cfg_pwm0_low ,
+ output logic [15:0] cfg_pwm1_high ,
+ output logic [15:0] cfg_pwm1_low ,
+ output logic [15:0] cfg_pwm2_high ,
+ output logic [15:0] cfg_pwm2_low ,
+ output logic [15:0] cfg_pwm3_high ,
+ output logic [15:0] cfg_pwm3_low ,
+ output logic [15:0] cfg_pwm4_high ,
+ output logic [15:0] cfg_pwm4_low ,
+ output logic [15:0] cfg_pwm5_high ,
+ output logic [15:0] cfg_pwm5_low
+
+ );
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [2:0] sw_addr ; // addressing 16 registers
+logic [31:0] sw_reg_wdata ;
+logic [3:0] sw_be ;
+
+logic [31:0] reg_out ;
+logic [31:0] reg_0 ; // CONFIG - Unused
+logic [31:0] reg_1 ; // PWM-REG-0
+logic [31:0] reg_2 ; // PWM-REG-1
+logic [31:0] reg_3 ; // PWM-REG-2
+logic [31:0] reg_4 ; // PWM-REG-3
+logic [31:0] reg_5 ; // PWM-REG-4
+logic [31:0] reg_6 ; // PWM-REG-5
+
+assign sw_addr = reg_addr;
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign sw_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 3'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 3'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 3'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 3'h3);
+wire sw_wr_en_4 = sw_wr_en & (sw_addr == 3'h4);
+wire sw_wr_en_5 = sw_wr_en & (sw_addr == 3'h5);
+wire sw_wr_en_6 = sw_wr_en & (sw_addr == 3'h6);
+
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 3'h0);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 3'h1);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 3'h2);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 3'h3);
+wire sw_rd_en_4 = sw_rd_en & (sw_addr == 3'h4);
+wire sw_rd_en_5 = sw_rd_en & (sw_addr == 3'h5);
+wire sw_rd_en_6 = sw_rd_en & (sw_addr == 3'h6);
+
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (reg_cs && !reg_ack) begin
+ reg_rdata <= reg_out;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+//--------------------------------------------
+// reg-0: Reserve for pwm global config
+//---------------------------------------------
+assign reg_0 = 'h0;
+//-----------------------------------------------------------------------
+// Logic for PWM-0 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm0_low = reg_1[15:0]; // low period of w/f
+assign cfg_pwm0_high = reg_1[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1 )
+ );
+
+
+//-----------------------------------------------------------------------
+// Logic for PWM-1 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm1_low = reg_2[15:0]; // low period of w/f
+assign cfg_pwm1_high = reg_2[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_2 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_2 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_2 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-2 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm2_low = reg_3[15:0]; // low period of w/f
+assign cfg_pwm2_high = reg_3[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-3 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm3_low = reg_4[15:0]; // low period of w/f
+assign cfg_pwm3_high = reg_4[31:16]; // high period of w/f
+gen_32b_reg #(32'h0) u_reg_4 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_4 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_4 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-4 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm4_low = reg_5[15:0]; // low period of w/f
+assign cfg_pwm4_high = reg_5[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_5 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_5 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_5 )
+ );
+
+//-----------------------------------------------------------------------
+// Logic for PWM-5 Config
+//-----------------------------------------------------------------------
+assign cfg_pwm5_low = reg_6[15:0]; // low period of w/f
+assign cfg_pwm5_high = reg_6[31:16]; // high period of w/f
+
+gen_32b_reg #(32'h0) u_reg_6 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_6 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_6 )
+ );
+
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [2:0])
+ 3'b000 : reg_out [31:0] = reg_0 [31:0];
+ 3'b001 : reg_out [31:0] = reg_1 [31:0];
+ 3'b010 : reg_out [31:0] = reg_2 [31:0];
+ 3'b011 : reg_out [31:0] = reg_3 [31:0];
+ 3'b100 : reg_out [31:0] = reg_4 [31:0];
+ 3'b101 : reg_out [31:0] = reg_5 [31:0];
+ 3'b110 : reg_out [31:0] = reg_6 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/pwm_top.sv b/verilog/rtl/pinmux/src/pwm_top.sv
new file mode 100644
index 0000000..2b8d3a5
--- /dev/null
+++ b/verilog/rtl/pinmux/src/pwm_top.sv
@@ -0,0 +1,172 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// PWM Top ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+/// Includes 6 PWM ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+
+module pwm_top (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [2:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+
+ input logic pulse_1ms,
+ input logic [5:0] cfg_pwm_enb,
+ output logic [5:0] pwm_wfm
+
+ );
+
+//---------------------------------------------------
+// 6 PWM variabled
+//---------------------------------------------------
+
+logic [15:0] cfg_pwm0_high ;
+logic [15:0] cfg_pwm0_low ;
+logic [15:0] cfg_pwm1_high ;
+logic [15:0] cfg_pwm1_low ;
+logic [15:0] cfg_pwm2_high ;
+logic [15:0] cfg_pwm2_low ;
+logic [15:0] cfg_pwm3_high ;
+logic [15:0] cfg_pwm3_low ;
+logic [15:0] cfg_pwm4_high ;
+logic [15:0] cfg_pwm4_low ;
+logic [15:0] cfg_pwm5_high ;
+logic [15:0] cfg_pwm5_low ;
+
+
+
+pwm_reg u_reg (
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ .cfg_pwm0_high (cfg_pwm0_high ),
+ .cfg_pwm0_low (cfg_pwm0_low ),
+ .cfg_pwm1_high (cfg_pwm1_high ),
+ .cfg_pwm1_low (cfg_pwm1_low ),
+ .cfg_pwm2_high (cfg_pwm2_high ),
+ .cfg_pwm2_low (cfg_pwm2_low ),
+ .cfg_pwm3_high (cfg_pwm3_high ),
+ .cfg_pwm3_low (cfg_pwm3_low ),
+ .cfg_pwm4_high (cfg_pwm4_high ),
+ .cfg_pwm4_low (cfg_pwm4_low ),
+ .cfg_pwm5_high (cfg_pwm5_high ),
+ .cfg_pwm5_low (cfg_pwm5_low )
+
+ );
+
+
+// 6 PWM Waveform Generator
+pwm u_pwm_0 (
+ .waveform (pwm_wfm[0] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[0] ),
+ .cfg_pwm_high (cfg_pwm0_high ),
+ .cfg_pwm_low (cfg_pwm0_low )
+ );
+
+pwm u_pwm_1 (
+ .waveform (pwm_wfm[1] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[1] ),
+ .cfg_pwm_high (cfg_pwm1_high ),
+ .cfg_pwm_low (cfg_pwm1_low )
+ );
+
+pwm u_pwm_2 (
+ .waveform (pwm_wfm[2] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[2] ),
+ .cfg_pwm_high (cfg_pwm2_high ),
+ .cfg_pwm_low (cfg_pwm2_low )
+ );
+
+pwm u_pwm_3 (
+ .waveform (pwm_wfm[3] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[3] ),
+ .cfg_pwm_high (cfg_pwm3_high ),
+ .cfg_pwm_low (cfg_pwm3_low )
+ );
+pwm u_pwm_4 (
+ .waveform (pwm_wfm[4] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[4] ),
+ .cfg_pwm_high (cfg_pwm4_high ),
+ .cfg_pwm_low (cfg_pwm4_low )
+ );
+pwm u_pwm_5 (
+ .waveform (pwm_wfm[5] ),
+ .h_reset_n (h_reset_n ),
+ .mclk (mclk ),
+ .pulse1m_mclk (pulse_1ms ),
+ .cfg_pwm_enb (cfg_pwm_enb[5] ),
+ .cfg_pwm_high (cfg_pwm5_high ),
+ .cfg_pwm_low (cfg_pwm5_low )
+ );
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/semaphore_reg.sv b/verilog/rtl/pinmux/src/semaphore_reg.sv
new file mode 100644
index 0000000..c347178
--- /dev/null
+++ b/verilog/rtl/pinmux/src/semaphore_reg.sv
@@ -0,0 +1,165 @@
+//////////////////////////////////////////////////////////////////////////////
+// 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>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Semaphore Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// A semaphore is a variable or abstract data type that ////
+//// provides a simple but useful abstraction for controlling ////
+//// access by multiple processes to a common resource in a ////
+//// parallel programming or multi-user environment. ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+/***************************************************************
+ Special Semaphore Register Implementation
+ Read access from 0 to 14 will return corresponsonding bit lock status.
+ If lock is free, then it return '1' and also lock the corresponding bit
+ If lock is busy, then it return '0'
+ Write & Read access with address 15 does normal write and read access,
+ this location should used for only debug purpose
+
+*****************************************************************/
+module semaphore_reg #(parameter DW = 16, // DATA WIDTH
+ parameter AW = $clog2(DW), // ADDRESS WIDTH
+ parameter BW = $clog2(AW) // BYTE WIDTH
+ ) (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [AW-1:0] reg_addr,
+ input logic [DW-1:0] reg_wdata,
+ input logic [BW-1:0] reg_be,
+
+ // Outputs
+ output logic [DW-1:0] reg_rdata,
+ output logic reg_ack
+
+ );
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [AW-1:0] sw_addr ; // addressing 16 registers
+logic [DW-1:0] sw_reg_wdata ;
+logic [BW-1:0] sw_be ;
+
+logic [DW-1:0] reg_out ;
+logic [DW-1:0] reg_0 ;
+logic sw_wr_en_0 ;
+
+assign sw_addr = reg_addr;
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (reg_cs && !reg_ack) begin
+ reg_rdata <= reg_out[DW-1:0] ;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+/***************************************************************
+ Special Semaphore Register Implementation
+ Read access from 0 to 30 will return corresponsonding bit lock status.
+ If lock is free, then it return '1' and lock the corresponding bit
+ If lock is busy, then it return '0' and lock the corresponding bit
+*****************************************************************/
+
+gen_16b_reg #('h0) u_reg_0 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_0 ),
+ .we (sw_be[BW-1:0] ),
+ .data_in (sw_reg_wdata[DW-1:0] ),
+
+ //List of Outs
+ .data_out (reg_0 )
+ );
+
+
+//-----------------------------------------------------------------------
+// Register Write Data
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ sw_reg_wdata = 'h0;
+ sw_wr_en_0 = 'b0;
+ sw_be = 'h0;
+
+ // Address 0xF, is Simple Write Register
+ if(sw_addr == {AW {1'b1}}) begin
+ sw_reg_wdata = reg_0;
+ sw_wr_en_0 = sw_wr_en & reg_ack;
+ sw_be = reg_be[BW-1:0];
+ end else begin // 0 to 0xE is Semaphore Register
+ if(sw_rd_en) begin // Read will always lock the bit '1'
+ sw_reg_wdata = (reg_0 | ( 1 << sw_addr)) ;
+ end else begin // To release the Lock Write with '1'
+ sw_reg_wdata = (reg_0 ^ ((reg_wdata [DW-1:0] & 'h1) << sw_addr)) ;
+ end
+ sw_wr_en_0 = reg_ack;
+ sw_be = {BW{1'b1}};
+ end
+end
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ if(sw_addr == {AW {1'b1}}) begin
+ reg_out = reg_0;
+ end else begin
+ reg_out = (reg_0 >> sw_addr ) ^ 'h1;
+ end
+end
+
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/timer_reg.sv b/verilog/rtl/pinmux/src/timer_reg.sv
new file mode 100644
index 0000000..cd48587
--- /dev/null
+++ b/verilog/rtl/pinmux/src/timer_reg.sv
@@ -0,0 +1,213 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Timer Register ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+//
+module timer_reg (
+ // System Signals
+ // Inputs
+ input logic mclk ,
+ input logic h_reset_n ,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs ,
+ input logic reg_wr ,
+ input logic [1:0] reg_addr ,
+ input logic [31:0] reg_wdata ,
+ input logic [3:0] reg_be ,
+
+ // Outputs
+ output logic [31:0] reg_rdata ,
+ output logic reg_ack ,
+
+ output logic [9:0] cfg_pulse_1us ,
+ output logic [2:0] cfg_timer_update , // CPU write to timer register
+ output logic [18:0] cfg_timer0 , // Timer-0 register
+ output logic [18:0] cfg_timer1 , // Timer-1 register
+ output logic [18:0] cfg_timer2 , // Timer-2 register
+ output logic [2:0] timer_intr
+
+ );
+
+//-----------------------------------------------------------------------
+// Internal Wire Declarations
+//-----------------------------------------------------------------------
+
+logic sw_rd_en ;
+logic sw_wr_en ;
+logic [1:0] sw_addr ; // addressing 16 registers
+logic [31:0] sw_reg_wdata ;
+logic [3:0] sw_be ;
+
+logic [31:0] reg_out ;
+logic [31:0] reg_0 ; // TIMER GLOBAL CONFIG
+logic [31:0] reg_1 ; // TIMER-0
+logic [31:0] reg_2 ; // TIMER-1
+logic [31:0] reg_3 ; // TIMER-2
+
+assign sw_addr = reg_addr;
+assign sw_rd_en = reg_cs & !reg_wr;
+assign sw_wr_en = reg_cs & reg_wr;
+assign sw_be = reg_be;
+assign sw_reg_wdata = reg_wdata;
+
+//-----------------------------------------------------------------------
+// register read enable and write enable decoding logic
+//-----------------------------------------------------------------------
+wire sw_wr_en_0 = sw_wr_en & (sw_addr == 2'h0);
+wire sw_wr_en_1 = sw_wr_en & (sw_addr == 2'h1);
+wire sw_wr_en_2 = sw_wr_en & (sw_addr == 2'h2);
+wire sw_wr_en_3 = sw_wr_en & (sw_addr == 2'h3);
+
+wire sw_rd_en_0 = sw_rd_en & (sw_addr == 2'h0);
+wire sw_rd_en_1 = sw_rd_en & (sw_addr == 2'h1);
+wire sw_rd_en_2 = sw_rd_en & (sw_addr == 2'h2);
+wire sw_rd_en_3 = sw_rd_en & (sw_addr == 2'h3);
+
+
+always @ (posedge mclk or negedge h_reset_n)
+begin : preg_out_Seq
+ if (h_reset_n == 1'b0) begin
+ reg_rdata <= 'h0;
+ reg_ack <= 1'b0;
+ end else if (reg_cs && !reg_ack) begin
+ reg_rdata <= reg_out;
+ reg_ack <= 1'b1;
+ end else begin
+ reg_ack <= 1'b0;
+ end
+end
+
+
+//----------------------------------------------
+// reg-0: GLBL_CFG
+//------------------------------------------
+
+gen_32b_reg #('h0) u_reg_0 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_0 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_0 )
+ );
+
+assign cfg_pulse_1us = reg_0[9:0];
+
+//-----------------------------------------------------------------------
+// reg-1
+// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
+// In first cycle, local register will be updated
+// In second cycle, update indication sent to timer block
+// -----------------------------------------------------------------
+assign cfg_timer0 = reg_1[18:0];
+assign cfg_timer_update[0] = sw_wr_en_1 & reg_ack;
+
+gen_32b_reg #(32'h0) u_reg_1 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_1 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_1[31:0] )
+ );
+
+//-----------------------------------------------------------------------
+// reg-2
+// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
+// In first cycle, local register will be updated
+// In second cycle, update indication sent to timer block
+// -----------------------------------------------------------------
+assign cfg_timer1 = reg_2[18:0];
+assign cfg_timer_update[1] = sw_wr_en_2 & reg_ack;
+
+gen_32b_reg #(32'h0) u_reg_2 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_2 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_2[31:0] )
+ );
+
+
+//-----------------------------------------------------------------------
+// reg-3
+// Assumption: wr_en is two cycle and reg_ack is asserted in second cycle
+// In first cycle, local register will be updated
+// In second cycle, update indication sent to timer block
+// -----------------------------------------------------------------
+assign cfg_timer2 = reg_3[18:0];
+assign cfg_timer_update[2] = sw_wr_en_3 & reg_ack;
+
+gen_32b_reg #(32'h0) u_reg_3 (
+ //List of Inputs
+ .reset_n (h_reset_n ),
+ .clk (mclk ),
+ .cs (sw_wr_en_3 ),
+ .we (sw_be ),
+ .data_in (sw_reg_wdata ),
+
+ //List of Outs
+ .data_out (reg_3[31:0] )
+ );
+
+//-----------------------------------------------------------------------
+// Register Read Path Multiplexer instantiation
+//-----------------------------------------------------------------------
+
+always_comb
+begin
+ reg_out [31:0] = 32'h0;
+
+ case (sw_addr [1:0])
+ 2'b00 : reg_out [31:0] = reg_0 [31:0];
+ 2'b01 : reg_out [31:0] = reg_1 [31:0];
+ 2'b10 : reg_out [31:0] = reg_2 [31:0];
+ 2'b11 : reg_out [31:0] = reg_3 [31:0];
+ default : reg_out [31:0] = 32'h0;
+ endcase
+end
+
+endmodule
diff --git a/verilog/rtl/pinmux/src/timer_top.sv b/verilog/rtl/pinmux/src/timer_top.sv
new file mode 100644
index 0000000..ae981dc
--- /dev/null
+++ b/verilog/rtl/pinmux/src/timer_top.sv
@@ -0,0 +1,191 @@
+//////////////////////////////////////////////////////////////////////////////
+// SPDX-FileCopyrightText: 2021 , Dinesh Annayya
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// SPDX-License-Identifier: Apache-2.0
+// SPDX-FileContributor: Created by Dinesh Annayya <dinesha@opencores.org>
+//
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Timer Top ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// 0.1 - 15th Aug 2022, Dinesh A ////
+//// initial version ////
+//////////////////////////////////////////////////////////////////////
+
+module timer_top (
+ // System Signals
+ // Inputs
+ input logic mclk,
+ input logic h_reset_n,
+
+ // Reg Bus Interface Signal
+ input logic reg_cs,
+ input logic reg_wr,
+ input logic [1:0] reg_addr,
+ input logic [31:0] reg_wdata,
+ input logic [3:0] reg_be,
+
+ // Outputs
+ output logic [31:0] reg_rdata,
+ output logic reg_ack,
+
+ output logic pulse_1ms,
+ output logic [2:0] timer_intr
+
+ );
+
+//---------------------------------------------------------
+// Timer Register
+// -------------------------------------------------------
+logic [2:0] cfg_timer_update ; // CPU write to timer register
+logic [18:0] cfg_timer0 ; // Timer-0 register
+logic [18:0] cfg_timer1 ; // Timer-1 register
+logic [18:0] cfg_timer2 ; // Timer-2 register
+
+/* clock pulse */
+//********************************************************
+logic pulse_1us ; // 1 UsSecond Pulse for waveform Generator
+logic pulse_1s ; // 1Second Pulse for waveform Generator
+logic [9:0] cfg_pulse_1us ; // 1us pulse generation config
+
+timer_reg u_reg (
+ .mclk (mclk ),
+ .h_reset_n (h_reset_n ),
+
+ // Reg Bus Interface Signal
+ .reg_cs (reg_cs ),
+ .reg_wr (reg_wr ),
+ .reg_addr (reg_addr ),
+ .reg_wdata (reg_wdata ),
+ .reg_be (reg_be ),
+
+ // Outputs
+ .reg_rdata (reg_rdata ),
+ .reg_ack (reg_ack ),
+
+ .cfg_pulse_1us (cfg_pulse_1us ),
+ .cfg_timer_update (cfg_timer_update ),
+ .cfg_timer0 (cfg_timer0 ),
+ .cfg_timer1 (cfg_timer1 ),
+ .cfg_timer2 (cfg_timer2 )
+
+ );
+
+// 1us pulse
+pulse_gen_type2 #(.WD(10)) u_pulse_1us (
+
+ .clk_pulse_o (pulse_1us ),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .cfg_max_cnt (cfg_pulse_1us )
+
+ );
+
+// 1us/1000 to 1millisecond pulse
+pulse_gen_type1 u_pulse_1ms (
+
+ .clk_pulse_o (pulse_1ms ),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .trigger (pulse_1us )
+
+ );
+
+// 1ms/1000 => 1 second pulse
+pulse_gen_type1 u_pulse_1s (
+
+ .clk_pulse_o (pulse_1s ),
+ .clk (mclk ),
+ .reset_n (h_reset_n ),
+ .trigger (pulse_1ms )
+
+ );
+
+// Timer
+
+wire [1:0] cfg_timer0_clksel = cfg_timer0[18:17];
+wire cfg_timer0_enb = cfg_timer0[16];
+wire [15:0] cfg_timer0_compare = cfg_timer0[15:0];
+
+timer u_timer_0
+ (
+ .reset_n (sreset_n ),// system syn reset
+ .mclk (mclk ),// master clock
+ .pulse_1us (pulse_1us ),
+ .pulse_1ms (pulse_1ms ),
+ .pulse_1s (pulse_1s ),
+
+ .cfg_timer_update (cfg_timer_update[0] ),
+ .cfg_timer_enb (cfg_timer0_enb ),
+ .cfg_timer_compare (cfg_timer0_compare ),
+ .cfg_timer_clksel (cfg_timer0_clksel ),// to select the timer 1us/1ms reference clock
+
+ .timer_intr (timer_intr[0] )
+ );
+
+// Timer
+wire [1:0] cfg_timer1_clksel = cfg_timer1[18:17];
+wire cfg_timer1_enb = cfg_timer1[16];
+wire [15:0] cfg_timer1_compare = cfg_timer1[15:0];
+timer u_timer_1
+ (
+ .reset_n (sreset_n ),// system syn reset
+ .mclk (mclk ),// master clock
+ .pulse_1us (pulse_1us ),
+ .pulse_1ms (pulse_1ms ),
+ .pulse_1s (pulse_1s ),
+
+ .cfg_timer_update (cfg_timer_update[1] ),
+ .cfg_timer_enb (cfg_timer1_enb ),
+ .cfg_timer_compare (cfg_timer1_compare ),
+ .cfg_timer_clksel (cfg_timer1_clksel ),// to select the timer 1us/1ms reference clock
+
+ .timer_intr (timer_intr[1] )
+ );
+
+// Timer
+wire [1:0] cfg_timer2_clksel = cfg_timer2[18:17];
+wire cfg_timer2_enb = cfg_timer2[16];
+wire [15:0] cfg_timer2_compare = cfg_timer2[15:0];
+
+timer u_timer_2
+ (
+ .reset_n (sreset_n ),// system syn reset
+ .mclk (mclk ),// master clock
+ .pulse_1us (pulse_1us ),
+ .pulse_1ms (pulse_1ms ),
+ .pulse_1s (pulse_1s ),
+
+ .cfg_timer_update (cfg_timer_update[2] ),
+ .cfg_timer_enb (cfg_timer2_enb ),
+ .cfg_timer_compare (cfg_timer2_compare ),
+ .cfg_timer_clksel (cfg_timer2_clksel ),// to select the timer 1us/1ms reference clock
+
+ .timer_intr (timer_intr[2] )
+ );
+
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_cfg.sv b/verilog/rtl/sspim/src/sspim_cfg.sv
index e849f81..cc81df0 100755
--- a/verilog/rtl/sspim/src/sspim_cfg.sv
+++ b/verilog/rtl/sspim/src/sspim_cfg.sv
@@ -46,17 +46,28 @@
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
+/*******************************************************************
+SPI Mode:
+ Mode 0 (the default)− Clock is normally low (CPOL = 0), and Data sampled on rising edge and shifted out on the falling edge. (CPHA = 0). - Supported
+ Mode 1 − Clock is normally low (CPOL = 0), and Data sampled on the falling edge and shifted out on the rising edge. (CPHA = 1). - Not Supported
+ Mode 2 − Clock is normally high (CPOL = 1), and Data sampled on the rising edge and shifted out on the falling edge. (CPHA = 0). - Supported
+ Mode 3 − Clock is normally high (CPOL = 1), and Data sampled on the falling edge and shifted out on the rising edge (CPHA = 1). - Not Supported
+********************************************************************/
+
module sspim_cfg (
input logic mclk ,
input logic reset_n ,
output logic [1:0] cfg_tgt_sel ,
-
+
+ output logic cfg_cpol , // spi clock idle phase
+ output logic cfg_cpha , // spi data sample and lanch phase
+ output logic cfg_bit_order , // SPI TX/RX Bit Order, 1 -> LSBFIRST or 0 -> MSBFIRST
output logic cfg_op_req , // SPI operation request
- output logic cfg_endian , // Endian selection
+ output logic cfg_endian , // Endian selection
output logic [1:0] cfg_op_type , // SPI operation type
output logic [1:0] cfg_transfer_size , // SPI transfer size
output logic [5:0] cfg_sck_period , // sck clock period
@@ -98,6 +109,7 @@
logic [31:0] reg_1; // Software-Reg_1
logic [31:0] reg_2; // Software-Reg_2
logic [31:0] reg_out;
+logic [1:0] cfg_spi_mode;
//-----------------------------------------------------------------------
// Main code starts here
@@ -168,7 +180,13 @@
//-----------------------------------------------------------------------
// Logic for Register 0 : SPI Control Register
//-----------------------------------------------------------------------
+
+assign cfg_cpha = cfg_spi_mode[0];
+assign cfg_cpol = cfg_spi_mode[1];
+
assign cfg_op_req = reg_0[31]; // cpu request
+assign cfg_bit_order = reg_0[28]; // 1 -> LSBFIRST or 0 -> MSBFIRST
+assign cfg_spi_mode = reg_0[27:26]; // spi mode
assign cfg_endian = reg_0[25]; // Endian, 0 - little, 1 - Big
assign cfg_tgt_sel = reg_0[24:23]; // target chip select
assign cfg_op_type = reg_0[22:21]; // SPI operation type
@@ -210,18 +228,17 @@
.data_out (reg_0[23:16] )
);
-generic_register #(2,0 ) u_spi_ctrl_be3 (
- .we ({2{sw_wr_en_0 &
+generic_register #(7,0 ) u_spi_ctrl_be3 (
+ .we ({7{sw_wr_en_0 &
wr_be[3] }} ),
- .data_in (reg_wdata[25:24] ),
+ .data_in (reg_wdata[30:24] ),
.reset_n (reset_n ),
.clk (mclk ),
//List of Outs
- .data_out (reg_0[25:24] )
+ .data_out (reg_0[30:24] )
);
-assign reg_0[30:26] = 5'h0;
req_register #(0 ) u_spi_ctrl_req (
.cpu_we ({sw_wr_en_0 &
diff --git a/verilog/rtl/sspim/src/sspim_clkgen.sv b/verilog/rtl/sspim/src/sspim_clkgen.sv
new file mode 100755
index 0000000..bb1a8b4
--- /dev/null
+++ b/verilog/rtl/sspim/src/sspim_clkgen.sv
@@ -0,0 +1,146 @@
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// Single SPI Master Interface Module ////
+//// ////
+//// This file is part of the riscduino cores project ////
+//// https://github.com/dineshannayya/riscduino.git ////
+//// ////
+//// Description ////
+//// SPI Clock Gen module ////
+//// ////
+//// To Do: ////
+//// nothing ////
+//// ////
+//// Author(s): ////
+//// - Dinesh Annayya, dinesha@opencores.org ////
+//// ////
+//// Revision : ////
+//// V.0 - 06 Oct 2021 ////
+//// Initial SpI Module picked from ////
+//// http://www.opencores.org/cores/turbo8051/ ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+//// ////
+//// 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 ////
+//// ////
+//////////////////////////////////////////////////////////////////////
+/*********************************************************************
+ Design Implementation Reference
+ Reference: https://www.allaboutcircuits.com/technical-articles/spi-serial-peripheral-interface/
+*********************************************************************/
+
+
+module sspim_clkgen
+ (
+ input logic clk,
+ input logic reset_n,
+ input logic cfg_op_req,
+ input logic cfg_cpol, // CPOL : clock polarity CPOL :0- Clock Idle state low, 1 - Clock idle state high
+ input logic cfg_cpha, // CPHA : Clock Phase
+
+ input logic [5:0] cfg_sck_period,
+
+ input logic sck_active,
+
+ output logic sck_int, // SCLK
+ output logic shift, // Data Shift Phase
+ output logic sample, // Data Sample Phase
+ output logic sck_ne, // sclk negative phase
+ output logic sck_pe // sclk positive phase
+
+ );
+
+ //*************************************************************************
+
+
+ logic [5:0] clk_cnt;
+ logic [5:0] sck_half_period;
+
+
+
+ assign sck_ne = (cfg_cpha == 0) ? shift : sample;
+ assign sck_pe = (cfg_cpha == 0) ? sample : shift;
+
+ assign sck_half_period = {1'b0, cfg_sck_period[5:1]};
+ // The first transition on the sck_toggle happens one SCK period
+ // after op_en or boot_en is asserted
+ always @(posedge clk or negedge reset_n) begin
+ if(!reset_n) begin
+ shift <= 1'b0;
+ sample <= 1'b0;
+ clk_cnt <= 6'h0;
+ sck_int <= 1'b1;
+ end // if (!reset_n)
+ else
+ begin
+ if(cfg_op_req)
+ begin
+ // clock counter
+ if(clk_cnt == cfg_sck_period) begin
+ clk_cnt <= 'h0;
+ end else begin
+ clk_cnt <= clk_cnt + 1'b1;
+ end
+
+ if(clk_cnt == sck_half_period)
+ begin
+ shift <= 1'b1;
+ sample <= 1'b0;
+ end // if (clk_cnt == sck_half_period)
+ else
+ begin
+ if(clk_cnt == cfg_sck_period)
+ begin
+ shift <= 1'b0;
+ sample <= 1'b1;
+ end // if (clk_cnt == cfg_sck_period)
+ else
+ begin
+ shift <= 1'b0;
+ sample <= 1'b0;
+ end // else: !if(clk_cnt == cfg_sck_period)
+ end // else: !if(clk_cnt == sck_half_period)
+ end // if (op_en)
+ else
+ begin
+ clk_cnt <= 6'h0;
+ shift <= 1'b0;
+ sample <= 1'b0;
+ end // else: !if(op_en)
+
+
+ if(sck_active) begin
+ if(sck_ne) sck_int <= 0;
+ else if(sck_pe) sck_int <= 1;
+ end else if (cfg_cpol == 0) begin // CPOL :0- Clock Idle state low
+ sck_int <= 0;
+ end else begin // CPOL :1- Clock Idle state High
+ sck_int <= 1;
+ end
+ end // else: !if(!reset_n)
+ end // always @ (posedge clk or negedge reset_n)
+
+
+
+endmodule
diff --git a/verilog/rtl/sspim/src/sspim_ctl.sv b/verilog/rtl/sspim/src/sspim_ctl.sv
index ea6aa1f..25971e0 100755
--- a/verilog/rtl/sspim/src/sspim_ctl.sv
+++ b/verilog/rtl/sspim/src/sspim_ctl.sv
@@ -52,25 +52,24 @@
(
input logic clk,
input logic reset_n,
+ input logic cfg_cpol,
input logic cfg_op_req,
input logic cfg_endian,
input logic [1:0] cfg_op_type,
input logic [1:0] cfg_transfer_size,
+ input logic [4:0] cfg_sck_cs_period,
- input logic [5:0] cfg_sck_period,
- input logic [4:0] cfg_sck_cs_period, // cs setup & hold period
input logic [7:0] cfg_cs_byte,
input logic [31:0] cfg_datain,
output logic [31:0] cfg_dataout,
output logic [7:0] byte_out, // Byte out for Serial Shifting out
input logic [7:0] byte_in, // Serial Received Byte
- output logic sck_int,
output logic cs_int_n,
- output logic sck_pe,
- output logic sck_ne,
- output logic shift_out,
- output logic shift_in,
+ input logic shift,
+ input logic sample,
+
+ output logic sck_active,
output logic load_byte,
output logic op_done
@@ -80,74 +79,25 @@
parameter LITTLE_ENDIAN = 1'b0;
parameter BIG_ENDIAN = 1'b1;
+
+ parameter SPI_WR = 2'b00;
+ parameter SPI_RD = 2'b01;
+ parameter SPI_WR_RD = 2'b10;
- logic [5:0] clk_cnt;
logic [5:0] sck_cnt;
logic [3:0] spiif_cs;
- logic shift_enb;
- logic clr_sck_cnt ;
- logic sck_out_en;
- logic [5:0] sck_half_period;
logic [2:0] byte_cnt;
`define SPI_IDLE 4'b0000
`define SPI_CS_SU 4'b0001
- `define SPI_WRITE 4'b0010
- `define SPI_READ 4'b0011
- `define SPI_CS_HLD 4'b0100
- `define SPI_WAIT 4'b0101
+ `define SPI_DATA 4'b0010
+ `define SPI_CS_HLD 4'b0011
+ `define SPI_WAIT 4'b0100
- assign sck_half_period = {1'b0, cfg_sck_period[5:1]};
- // The first transition on the sck_toggle happens one SCK period
- // after op_en or boot_en is asserted
- always @(posedge clk or negedge reset_n) begin
- if(!reset_n) begin
- sck_ne <= 1'b0;
- clk_cnt <= 6'h1;
- sck_pe <= 1'b0;
- sck_int <= 1'b0;
- end // if (!reset_n)
- else
- begin
- if(cfg_op_req)
- begin
- if(clk_cnt == sck_half_period)
- begin
- sck_ne <= 1'b1;
- sck_pe <= 1'b0;
- if(sck_out_en) sck_int <= 0;
- clk_cnt <= clk_cnt + 1'b1;
- end // if (clk_cnt == sck_half_period)
- else
- begin
- if(clk_cnt == cfg_sck_period)
- begin
- sck_ne <= 1'b0;
- sck_pe <= 1'b1;
- if(sck_out_en) sck_int <= 1;
- clk_cnt <= 6'h1;
- end // if (clk_cnt == cfg_sck_period)
- else
- begin
- clk_cnt <= clk_cnt + 1'b1;
- sck_pe <= 1'b0;
- sck_ne <= 1'b0;
- end // else: !if(clk_cnt == cfg_sck_period)
- end // else: !if(clk_cnt == sck_half_period)
- end // if (op_en)
- else
- begin
- clk_cnt <= 6'h1;
- sck_pe <= 1'b0;
- sck_ne <= 1'b0;
- end // else: !if(op_en)
- end // else: !if(!reset_n)
- end // always @ (posedge clk or negedge reset_n)
-
wire [1:0] cs_data = (byte_cnt == 2'b00) ? cfg_cs_byte[7:6] :
(byte_cnt == 2'b01) ? cfg_cs_byte[5:4] :
@@ -162,104 +112,72 @@
(byte_cnt == 2'b10) ? cfg_datain[15:8] : cfg_datain[7:0]) ;
-assign shift_out = shift_enb && sck_ne;
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
spiif_cs <= `SPI_IDLE;
sck_cnt <= 6'h0;
- shift_in <= 1'b0;
- clr_sck_cnt <= 1'b1;
byte_cnt <= 2'b00;
cs_int_n <= 1'b1;
- sck_out_en <= 1'b0;
- shift_enb <= 1'b0;
cfg_dataout <= 32'h0;
load_byte <= 1'b0;
+ sck_active <= 1'b0;
end
else begin
- if(sck_ne)
- sck_cnt <= clr_sck_cnt ? 6'h0 : sck_cnt + 1 ;
-
case(spiif_cs)
`SPI_IDLE :
begin
+ sck_active <= 1'b0;
+ load_byte <= 1'b0;
op_done <= 0;
- clr_sck_cnt <= 1'b1;
- sck_out_en <= 1'b0;
- shift_enb <= 1'b0;
if(cfg_op_req)
begin
cfg_dataout <= 32'h0;
spiif_cs <= `SPI_CS_SU;
- end
- else begin
+ end else begin
spiif_cs <= `SPI_IDLE;
end
end
`SPI_CS_SU :
begin
- if(sck_ne) begin
+ if(shift) begin
cs_int_n <= cs_data[1];
if(sck_cnt == cfg_sck_cs_period) begin
- clr_sck_cnt <= 1'b1;
- if(cfg_op_type == 0) begin // Write Mode
+ sck_cnt <= 'h0;
+ if((cfg_op_type == SPI_WR) || (cfg_op_type == SPI_WR_RD )) begin // Write Mode
load_byte <= 1'b1;
- spiif_cs <= `SPI_WRITE;
- shift_enb <= 1'b0;
- end else begin
- shift_in <= 1;
- spiif_cs <= `SPI_READ;
- end
- end
- else begin
- clr_sck_cnt <= 1'b0;
- end
+ end
+ spiif_cs <= `SPI_DATA;
+ end else begin
+ sck_cnt <= sck_cnt + 1 ;
+ end
end
end
- `SPI_WRITE :
+ `SPI_DATA :
begin
load_byte <= 1'b0;
- if(sck_ne) begin
- if(sck_cnt == 3'h7 )begin
- clr_sck_cnt <= 1'b1;
- spiif_cs <= `SPI_CS_HLD;
- shift_enb <= 1'b0;
- sck_out_en <= 1'b0; // Disable clock output
- end
- else begin
- shift_enb <= 1'b1;
- sck_out_en <= 1'b1;
- clr_sck_cnt <= 1'b0;
- end
- end else begin
- shift_enb <= 1'b1;
- end
- end
-
- `SPI_READ :
- begin
- if(sck_ne) begin
- if( sck_cnt == 3'h7 ) begin
- clr_sck_cnt <= 1'b1;
- shift_in <= 0;
- spiif_cs <= `SPI_CS_HLD;
- sck_out_en <= 1'b0; // Disable clock output
- end
- else begin
- sck_out_en <= 1'b1; // Disable clock output
- clr_sck_cnt <= 1'b0;
- end
+ if((shift && (cfg_cpol == 1)) || (sample && (cfg_cpol == 0)) ) begin
+ sck_active <= 1'b1;
+ end else if((sample && (cfg_cpol == 1)) || (shift && (cfg_cpol == 0)) ) begin
+ if(sck_cnt == 4'h8 )begin
+ sck_active <= 1'b0;
+ sck_cnt <= 'h0;
+ spiif_cs <= `SPI_CS_HLD;
+ end
+ else begin
+ sck_active <= 1'b1;
+ sck_cnt <= sck_cnt + 1 ;
+ end
end
end
`SPI_CS_HLD : begin
- if(sck_ne) begin
+ if(shift) begin
cs_int_n <= cs_data[0];
if(sck_cnt == cfg_sck_cs_period) begin
- if(cfg_op_type == 1) begin // Read Mode
+ if((cfg_op_type == SPI_RD) || (cfg_op_type == SPI_WR_RD)) begin // Read Mode
cfg_dataout <= (cfg_endian == LITTLE_ENDIAN) ?
((byte_cnt[1:0] == 2'b00) ? { cfg_dataout[31:8],byte_in } :
(byte_cnt[1:0] == 2'b01) ? { cfg_dataout[31:16], byte_in, cfg_dataout[7:0] } :
@@ -270,7 +188,7 @@
(byte_cnt[1:0] == 2'b10) ? { cfg_dataout[31:16], byte_in, cfg_dataout[7:0] } :
{ cfg_dataout[31:8],byte_in}) ;
end
- clr_sck_cnt <= 1'b1;
+ sck_cnt <= 'h0;
if(byte_cnt == cfg_transfer_size) begin
spiif_cs <= `SPI_WAIT;
byte_cnt <= 0;
@@ -281,7 +199,7 @@
end
end
else begin
- clr_sck_cnt <= 1'b0;
+ sck_cnt <= sck_cnt + 1 ;
end
end
end // case: `SPI_CS_HLD
diff --git a/verilog/rtl/sspim/src/sspim_if.sv b/verilog/rtl/sspim/src/sspim_if.sv
index 42b18f2..ece9ffd 100755
--- a/verilog/rtl/sspim/src/sspim_if.sv
+++ b/verilog/rtl/sspim/src/sspim_if.sv
@@ -47,24 +47,25 @@
module sspim_if
(
- input logic clk,
- input logic reset_n,
- input logic sck_pe,
- input logic sck_int,
- input logic cs_int_n,
+ input logic clk,
+ input logic reset_n,
+ input logic sck_int,
+ input logic cs_int_n,
+ input logic cfg_bit_order, // 1 -> LSBFIRST or 0 -> MSBFIRST
input logic load_byte,
input logic [1:0] cfg_tgt_sel,
input logic [7:0] byte_out,
- input logic shift_out,
- input logic shift_in,
+ input logic sck_active,
+ input logic shift,
+ input logic sample,
- output logic [7:0] byte_in,
- output logic sck,
- output logic so,
- output logic [3:0] cs_n,
- input logic si
+ output logic [7:0]byte_in,
+ output logic sck,
+ output logic so,
+ output logic [3:0]cs_n,
+ input logic si
);
@@ -73,6 +74,9 @@
logic [7:0] si_reg;
+ wire shift_out = shift & sck_active;
+ wire sample_in = sample & sck_active;
+
//Output Shift Register
always @(posedge clk or negedge reset_n) begin
@@ -86,13 +90,19 @@
if(shift_out) begin
// Handling backto back case :
// Last Transfer bit + New Trasfer Load
- so <= so_reg[7];
+ if(cfg_bit_order) so <= so_reg[0]; // LSB FIRST
+ else so <= so_reg[7]; // MSB FIRST
end
end // if (load_byte)
else begin
if(shift_out) begin
- so <= so_reg[7];
- so_reg <= {so_reg[6:0],1'b0};
+ if(cfg_bit_order) begin // LSB FIRST
+ so <= so_reg[0];
+ so_reg <= {1'b0,so_reg[7:1]};
+ end else begin
+ so <= so_reg[7];
+ so_reg <= {so_reg[6:0],1'b0};
+ end
end // if (shift_out)
end // else: !if(load_byte)
end // else: !if(!reset_n)
@@ -103,11 +113,14 @@
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
si_reg <= 8'h0;
- end
- else begin
- if(sck_pe & shift_in) begin
- si_reg[7:0] <= {si_reg[6:0],si};
- end // if (sck_pe & shift_in)
+ end else begin
+ if(sample_in) begin
+ if(cfg_bit_order) begin // LSB FIRST
+ si_reg[7:0] <= {si,si_reg[7:1]};
+ end else begin // MSB FIRST
+ si_reg[7:0] <= {si_reg[6:0],si};
+ end
+ end // if (sample_in)
end // else: !if(!reset_n)
end // always @ (posedge clk or negedge reset_n)
diff --git a/verilog/rtl/sspim/src/sspim_top.sv b/verilog/rtl/sspim/src/sspim_top.sv
index 2a28d2e..6f0f17f 100755
--- a/verilog/rtl/sspim/src/sspim_top.sv
+++ b/verilog/rtl/sspim/src/sspim_top.sv
@@ -46,6 +46,9 @@
//// out is big endian, i.e bit[7],[6] ..[0] ////
//// 0.3 - April 6, 2022, Dinesh A ////
//// Four chip select are driven out ////
+//// 0.4 - Aug 5, 2022, Dinesh A ////
+//// A. SPI Mode 0 to 3 support added, ////
+//// B. SPI Duplex mode TX-RX Mode added ////
//// ////
//////////////////////////////////////////////////////////////////////
//// ////
@@ -125,54 +128,81 @@
logic [31:0] cfg_datain ; // data for transfer
logic [31:0] cfg_dataout ; // data for received
logic hware_op_done ; // operation done
-
+logic cfg_bit_order ; // Bit order 1 -> LSBFIRST or 0 -> MSBFIRST
+logic cfg_cpol ; // spi clock idle phase
+logic cfg_cpha ; // spi data sample and lanch phase
sspim_if u_spi_if
(
. clk (clk ),
. reset_n (reset_n ),
- // towards ctrl i/f
- . sck_pe (sck_pe ),
+ // cfg
+ . cfg_bit_order (cfg_bit_order ),
+ . cfg_tgt_sel (cfg_tgt_sel ),
+
+ // clkgen
+ . shift (shift ),
+ . sample (sample ),
. sck_int (sck_int ),
+
+ // towards ctrl i/f
+ . sck_active (sck_active ),
. cs_int_n (cs_int_n ),
. byte_in (byte_in ),
. load_byte (load_byte ),
. byte_out (byte_out ),
- . shift_out (shift_out ),
- . shift_in (shift_in ),
- . cfg_tgt_sel (cfg_tgt_sel ),
-
+ // External I/F
. sck (sck ),
. so (so ),
. si (si ),
. cs_n (ssn )
);
+sspim_clkgen u_clkgen
+ (
+ . clk (clk ),
+ . reset_n (reset_n ),
+
+ // cfg
+ . cfg_cpol (cfg_cpol ),
+ . cfg_cpha (cfg_cpha ),
+ . cfg_sck_period (cfg_sck_period ),
+ . cfg_op_req (cfg_op_req ),
+
+ // ctrl
+ . sck_active (sck_active ),
+
+ . sck_int (sck_int ),
+ . shift (shift ),
+ . sample (sample ),
+ . sck_ne (),
+ . sck_pe ()
+
+ );
sspim_ctl u_spi_ctrl
(
. clk (clk ),
. reset_n (reset_n ),
+ // cfg
+ . cfg_cpol (cfg_cpol ),
. cfg_op_req (cfg_op_req ),
. cfg_endian (cfg_endian ),
. cfg_op_type (cfg_op_type ),
. cfg_transfer_size (cfg_transfer_size ),
- . cfg_sck_period (cfg_sck_period ),
. cfg_sck_cs_period (cfg_sck_cs_period ),
. cfg_cs_byte (cfg_cs_byte ),
. cfg_datain (cfg_datain ),
. cfg_dataout (cfg_dataout ),
. op_done (hware_op_done ),
- . sck_int (sck_int ),
+ . sck_active (sck_active ),
. cs_int_n (cs_int_n ),
- . sck_pe (sck_pe ),
- . sck_ne (sck_ne ),
- . shift_out (shift_out ),
- . shift_in (shift_in ),
+ . shift (shift ),
+ . sample (sample ),
. load_byte (load_byte ),
. byte_out (byte_out ),
. byte_in (byte_in )
@@ -200,6 +230,9 @@
// configuration signal
+ . cfg_cpol (cfg_cpol ),
+ . cfg_cpha (cfg_cpha ),
+ . cfg_bit_order (cfg_bit_order ),
. cfg_tgt_sel (cfg_tgt_sel ),
. cfg_op_req (cfg_op_req ), // SPI operation request
. cfg_endian (cfg_endian ),
diff --git a/verilog/rtl/uart/src/uart_core.sv b/verilog/rtl/uart/src/uart_core.sv
index 948cd35..653e285 100644
--- a/verilog/rtl/uart/src/uart_core.sv
+++ b/verilog/rtl/uart/src/uart_core.sv
@@ -185,8 +185,9 @@
//##############################################################
// 16x Baud clock generation
+// Baud Rate config = (F_CPU / (BAUD * 16)) - 2
// Example: to generate 19200 Baud clock from 50Mhz Link clock
-// 50 * 1000 * 1000 / (2 + cfg_baud_16x) = 19200 * 16
+// cfg_baud_16x = ((50 * 1000 * 1000) / (19200 * 16)) - 2
// cfg_baud_16x = 0xA0 (160)
//###############################################################
diff --git a/verilog/rtl/user_project_wrapper.v b/verilog/rtl/user_project_wrapper.v
index 34c8794..3429628 100644
--- a/verilog/rtl/user_project_wrapper.v
+++ b/verilog/rtl/user_project_wrapper.v
@@ -35,6 +35,7 @@
//// 8. 2KB icache and 2KB dcache ////
//// 8. 6 Channel ADC ////
//// 9. Pinmux with GPIO and 6 PWM ////
+////
//// ////
//// To Do: ////
//// nothing ////
@@ -216,6 +217,20 @@
//// SPI ISP boot option added in wb_host, spi slave uses ////
//// same spi master interface, but will be active only ////
//// when internal SPI config disabled + RESET PIN = 0 ////
+//// 4.9 Aug 5 2022, Dinesh A ////
+//// changes in sspim ////
+//// A. SPI Mode 0 to 3 support added, ////
+//// B. SPI Duplex mode TX-RX Mode added ////
+//// 5.0 Aug 15 2022, Dinesh A ////
+//// A. 15 Hardware Semahore added ////
+//// B. Pinmux Address Space are Split as ////
+//// `define ADDR_SPACE_PINMUX 32'h1002_0000 ////
+//// `define ADDR_SPACE_GLBL 32'h1002_0000 ////
+//// `define ADDR_SPACE_GPIO 32'h1002_0040 ////
+//// `define ADDR_SPACE_PWM 32'h1002_0080 ////
+//// `define ADDR_SPACE_TIMER 32'h1002_00C0 ////
+//// `define ADDR_SPACE_SEMA 32'h1002_0100 ////
+//// ////
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2000 Authors and OPENCORES.ORG ////
@@ -243,6 +258,32 @@
//// ////
//////////////////////////////////////////////////////////////////////
+/*********************************************************************
+ Memory Map: ////
+ ////
+ SOC Memory Map ////
+ 0x0000_0000 to 0x0FFF_FFFF - QSPIM MEMORY ////
+ 0x1000_0000 to 0x1000_00FF - QSPIM REG
+ 0x1001_0000 to 0x1001_003F - UART0
+ 0x1001_0040 to 0x1001_007F - I2
+ 0x1001_0080 to 0x1001_00BF - USB
+ 0x1001_00C0 to 0x1001_00FF - SSPIM
+ 0x1001_0100 to 0x1001_013F - UART1
+ 0x1002_0000 to 0x1002_00FF - PINMUX
+
+ Caravel Memory Map:
+-----------------------------------------------------------------------
+ caravel user space is 0x3000_0000 to 0x300F_FFFF
+ So we have allocated
+ 0x3008_0000 - 0x3008_00FF - Assigned to WB Host Address Space
+ Since We need more than 16MB Address space to access SDRAM/SPI we have
+ added indirect MSB 13 bit address select option
+ So Address will be {Bank_Sel[15:3], wbm_adr_i[18:0]}
+ ---------------------------------------------------------------------
+ 0x3080_0000 to 0x3080_00FF - WB HOST
+ 0x3000_0000 to 0x307F_FFFF - Indirect Address
+ {Bank_Sel[15:3],WB ADDR[18:0]}
+***********************************************************************/
module user_project_wrapper (
`ifdef USE_POWER_PINS
@@ -418,7 +459,7 @@
// Global Register Wishbone Interface
//---------------------------------------------------------------------
wire wbd_glbl_stb_o ; // strobe/request
-wire [7:0] wbd_glbl_adr_o ; // address
+wire [8:0] wbd_glbl_adr_o ; // address
wire wbd_glbl_we_o ; // write
wire [WB_WIDTH-1:0] wbd_glbl_dat_o ; // data output
wire [3:0] wbd_glbl_sel_o ; // byte enable
@@ -1214,7 +1255,7 @@
);
-pinmux u_pinmux(
+pinmux_top u_pinmux(
`ifdef USE_POWER_PINS
.vccd1 (vccd1 ),// User area 1 1.8V supply
.vssd1 (vssd1 ),// User area 1 digital ground
diff --git a/verilog/rtl/user_reg_map.v b/verilog/rtl/user_reg_map.v
index 42f9e73..53d8331 100644
--- a/verilog/rtl/user_reg_map.v
+++ b/verilog/rtl/user_reg_map.v
@@ -9,6 +9,11 @@
`define ADDR_SPACE_SSPI 32'h3001_00C0
`define ADDR_SPACE_UART1 32'h3001_0100
`define ADDR_SPACE_PINMUX 32'h3002_0000
+`define ADDR_SPACE_GLBL 32'h3002_0000
+`define ADDR_SPACE_GPIO 32'h3002_0040
+`define ADDR_SPACE_PWM 32'h3002_0080
+`define ADDR_SPACE_TIMER 32'h3002_00C0
+`define ADDR_SPACE_SEMA 32'h3002_0100
`define ADDR_SPACE_WBHOST 32'h3008_0000
//--------------------------------------------------
@@ -21,41 +26,74 @@
`define WBHOST_PLL_CTRL 8'h10 // reg_4 - PLL Control
//--------------------------------------------------
-// Pinmux Register
+// GLOBAL Register
// -------------------------------------------------
+`define GLBL_CFG_CHIP_ID 8'h00 // reg_0 - Chip ID
+`define GLBL_CFG_CFG0 8'h04 // reg_1 - Global Config-0
+`define GLBL_CFG_CFG1 8'h08 // reg_2 - Global Config-1
+`define GLBL_CFG_INTR_MSK 8'h0C // reg_3 - Global Interrupt Mask
+`define GLBL_CFG_INTR_STAT 8'h10 // reg_4 - Global Interrupt
+`define GLBL_CFG_MUTI_FUNC 8'h14 // reg_5 - Multi functional sel
+`define GLBL_CFG_SOFT_REG_0 8'h18 // reg_6 - Sof Register
+`define GLBL_CFG_SOFT_REG_1 8'h1C // reg_7 - Sof Register
+`define GLBL_CFG_SOFT_REG_2 8'h20 // reg_8 - Sof Register
+`define GLBL_CFG_SOFT_REG_3 8'h24 // reg_9 - Sof Register
+`define GLBL_CFG_SOFT_REG_4 8'h28 // reg_10 - Sof Register
+`define GLBL_CFG_SOFT_REG_5 8'h2C // reg_11 - Sof Register
-`define PINMUX_CHIP_ID 8'h00 // reg_0 - Chip ID
-`define PINMUX_GBL_CFG0 8'h04 // reg_1 - Global Config-2
-`define PINMUX_GBL_CFG1 8'h08 // reg_2 - Global Config-1
-`define PINMUX_GBL_INTR_MSK 8'h0C // reg_3 - Global Interrupt Mask
-`define PINMUX_GBL_INTR 8'h10 // reg_4 - Global Interrupt
-`define PINMUX_GPIO_IDATA 8'h14 // reg_5 - GPIO Data In
-`define PINMUX_GPIO_ODATA 8'h18 // reg_6 - GPIO Data Out
-`define PINMUX_GPIO_DSEL 8'h1C // reg_7 - GPIO Direction Select
-`define PINMUX_GPIO_TYPE 8'h20 // reg_8 - GPIO TYPE - Static/Waveform
-`define PINMUX_GPIO_INTR_STAT 8'h24 // reg_9 - GPIO Interrupt status
-`define PINMUX_GPIO_INTR_CLR 8'h24 // reg_9 - GPIO Interrupt Clear
-`define PINMUX_GPIO_INTR_SET 8'h28 // reg_10 - GPIO Interrupt Set
-`define PINMUX_GPIO_INTR_MASK 8'h2C // reg_11 - GPIO Interrupt Mask
-`define PINMUX_GPIO_POS_INTR 8'h30 // reg_12 - GPIO Posedge Interrupt
-`define PINMUX_GPIO_NEG_INTR 8'h34 // reg_13 - GPIO Neg Interrupt
-`define PINMUX_GPIO_MULTI_FUNC 8'h38 // reg_14 - GPIO Multi Function
-`define PINMUX_SOFT_REG_0 8'h3C // reg_15 - Soft Register
-`define PINMUX_CFG_PWM0 8'h40 // reg_16 - PWM Reg-0
-`define PINMUX_CFG_PWM1 8'h44 // reg_17 - PWM Reg-1
-`define PINMUX_CFG_PWM2 8'h48 // reg_18 - PWM Reg-2
-`define PINMUX_CFG_PWM3 8'h4C // reg_19 - PWM Reg-3
-`define PINMUX_CFG_PWM4 8'h50 // reg_20 - PWM Reg-4
-`define PINMUX_CFG_PWM5 8'h54 // reg_21 - PWM Reg-5
-`define PINMUX_SOFT_REG_1 8'h58 // reg_22 - Sof Register
-`define PINMUX_SOFT_REG_2 8'h5C // reg_23 - Sof Register
-`define PINMUX_SOFT_REG_3 8'h60 // reg_24 - Sof Register
-`define PINMUX_SOFT_REG_4 8'h64 // reg_25 - Sof Register
-`define PINMUX_SOFT_REG_5 8'h68 // reg_26 - Sof Register
-`define PINMUX_SOFT_REG_6 8'h6C // reg_27 - Sof Register
-`define PINMUX_CFG_TIMER0 8'h70 // reg_28 - Timer-0
-`define PINMUX_CFG_TIMER1 8'h74 // reg_28 - Timer-1
-`define PINMUX_CFG_TIMER2 8'h78 // reg_28 - Timer-2
+//--------------------------------------------------
+// GPIO Register
+// -------------------------------------------------
+`define GPIO_CFG_DSEL 8'h00 // reg_0 - GPIO Direction Select
+`define GPIO_CFG_TYPE 8'h04 // reg_1 - GPIO TYPE - Static/Waveform
+`define GPIO_CFG_IDATA 8'h08 // reg_2 - GPIO Data In
+`define GPIO_CFG_ODATA 8'h0C // reg_3 - GPIO Data Out
+`define GPIO_CFG_INTR_STAT 8'h10 // reg_4 - GPIO Interrupt status
+`define GPIO_CFG_INTR_CLR 8'h10 // reg_4 - GPIO Interrupt Clear
+`define GPIO_CFG_INTR_SET 8'h14 // reg_5 - GPIO Interrupt Set
+`define GPIO_CFG_INTR_MASK 8'h18 // reg_6 - GPIO Interrupt Mask
+`define GPIO_CFG_POS_INTR_SEL 8'h1C // reg_7 - GPIO Posedge Interrupt
+`define GPIO_CFG_NEG_INTR_SEL 8'h20 // reg_8 - GPIO Neg Interrupt
+
+
+//--------------------------------------------------
+// PWM Register
+// -------------------------------------------------
+`define PWM_GLBL_CFG 8'h00 // reg_0 - PWM Global Config
+`define PWM_CFG_PWM_0 8'h04 // reg_1 - PWM Reg-0
+`define PWM_CFG_PWM_1 8'h08 // reg_2 - PWM Reg-1
+`define PWM_CFG_PWM_2 8'h0C // reg_3 - PWM Reg-2
+`define PWM_CFG_PWM_3 8'h10 // reg_4 - PWM Reg-3
+`define PWM_CFG_PWM_4 8'h14 // reg_5 - PWM Reg-4
+`define PWM_CFG_PWM_5 8'h18 // reg_6 - PWM Reg-5
+
+//--------------------------------------------------
+// TIMER Register
+// -------------------------------------------------
+`define TIMER_CFG_GLBL 8'h00 // reg_0 - Global Config
+`define TIMER_CFG_TIMER_0 8'h04 // reg_1 - Timer-0
+`define TIMER_CFG_TIMER_1 8'h08 // reg_2 - Timer-1
+`define TIMER_CFG_TIMER_2 8'h0C // reg_3 - Timer-2
+
+//--------------------------------------------------
+// SEMAPHORE Register
+// -------------------------------------------------
+`define SEMA_CFG_LOCK_0 8'h00 // reg_0 - Semaphore Lock Bit-0
+`define SEMA_CFG_LOCK_1 8'h04 // reg_1 - Semaphore Lock Bit-1
+`define SEMA_CFG_LOCK_2 8'h08 // reg_2 - Semaphore Lock Bit-2
+`define SEMA_CFG_LOCK_3 8'h0C // reg_3 - Semaphore Lock Bit-3
+`define SEMA_CFG_LOCK_4 8'h10 // reg_4 - Semaphore Lock Bit-4
+`define SEMA_CFG_LOCK_5 8'h14 // reg_5 - Semaphore Lock Bit-5
+`define SEMA_CFG_LOCK_6 8'h18 // reg_6 - Semaphore Lock Bit-6
+`define SEMA_CFG_LOCK_7 8'h1C // reg_7 - Semaphore Lock Bit-7
+`define SEMA_CFG_LOCK_8 8'h20 // reg_8 - Semaphore Lock Bit-8
+`define SEMA_CFG_LOCK_9 8'h24 // reg_9 - Semaphore Lock Bit-9
+`define SEMA_CFG_LOCK_10 8'h28 // reg_10 - Semaphore Lock Bit-10
+`define SEMA_CFG_LOCK_11 8'h2C // reg_11 - Semaphore Lock Bit-11
+`define SEMA_CFG_LOCK_12 8'h30 // reg_12 - Semaphore Lock Bit-12
+`define SEMA_CFG_LOCK_13 8'h34 // reg_13 - Semaphore Lock Bit-13
+`define SEMA_CFG_LOCK_14 8'h38 // reg_14 - Semaphore Lock Bit-14
+`define SEMA_CFG_STATUS 8'h3C // reg_15 - Semaphore Lock Status
//----------------------------------------------------------
// QSPI Register Map
diff --git a/verilog/rtl/wb_host/src/wb_host.sv b/verilog/rtl/wb_host/src/wb_host.sv
index 26029c2..d3d85cc 100644
--- a/verilog/rtl/wb_host/src/wb_host.sv
+++ b/verilog/rtl/wb_host/src/wb_host.sv
@@ -411,11 +411,11 @@
// Locally there register are define to control the reset and clock for user
// area
//-----------------------------------------------------------------------
-// caravel user space is 0x3000_0000 to 0x3007_FFFF
+// caravel user space is 0x3000_0000 to 0x300F_FFFF
// So we have allocated
// 0x3008_0000 - 0x3008_00FF - Assigned to WB Host Address Space
// Since We need more than 16MB Address space to access SDRAM/SPI we have
-// added indirect MSB 8 bit address select option
+// added indirect MSB 13 bit address select option
// So Address will be {Bank_Sel[15:3], wbm_adr_i[18:0]}
// ---------------------------------------------------------------------
assign reg_sel = wb_req & (wb_adr_i[19] == 1'b1);
diff --git a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
index 9fb6344..7e348fc 100644
--- a/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
+++ b/verilog/rtl/wb_interconnect/src/wb_interconnect.sv
@@ -203,8 +203,8 @@
input logic s2_wbd_ack_i,
// input logic s2_wbd_err_i, - unused
output logic [31:0] s2_wbd_dat_o,
- output logic [7:0] s2_wbd_adr_o, // glbl reg need only 8 bits
- output logic [3:0] s2_wbd_sel_o,
+ output logic [8:0] s2_wbd_adr_o, // glbl reg need only 9 bits
+ output logic [3:0] s2_wbd_sel_o,
output logic s2_wbd_we_o,
output logic s2_wbd_cyc_o,
output logic s2_wbd_stb_o
@@ -677,7 +677,7 @@
assign s1_wbd_stb_o = s1_wb_wr.wbd_stb ;
assign s2_wbd_dat_o = s2_wb_wr.wbd_dat ;
- assign s2_wbd_adr_o = s2_wb_wr.wbd_adr[7:0] ; // Global Reg Need 8 bit
+ assign s2_wbd_adr_o = s2_wb_wr.wbd_adr[8:0] ; // Global Reg Need 8 bit
assign s2_wbd_sel_o = s2_wb_wr.wbd_sel ;
assign s2_wbd_we_o = s2_wb_wr.wbd_we ;
assign s2_wbd_cyc_o = s2_wb_wr.wbd_cyc ;