1. Initial version of westbone interface files copied from turbo8051 open core project
2. Initial version of RISCV Open core project copied from Syntacore SCR1 package
diff --git a/verilog/rtl/lib/wb_crossbar.v b/verilog/rtl/lib/wb_crossbar.v
new file mode 100644
index 0000000..9eb8f29
--- /dev/null
+++ b/verilog/rtl/lib/wb_crossbar.v
@@ -0,0 +1,399 @@
+//////////////////////////////////////////////////////////////////////

+////                                                              ////

+////  OMS 8051 cores common library Module                        ////

+////                                                              ////

+////  This file is part of the OMS 8051 cores project             ////

+////  http://www.opencores.org/cores/oms8051mini/                 ////

+////                                                              ////

+////  Description                                                 ////

+////  OMS 8051 definitions.                                       ////

+////                                                              ////

+////  To Do:                                                      ////

+////    nothing                                                   ////

+////                                                              ////

+////  Author(s):                                                  ////

+////      - Dinesh Annayya, dinesha@opencores.org                 ////

+////                                                              ////

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

+////  Revision : Nov 26, 2016                                    

+////      v-0.0 - Dinesh.A, Nov 26, 2016

+////          1. Initial Version

+////      v-0.1 - Dinesh.A, Jan 19, 2017

+////          1. Lint warning fixes, Seperated resetable and non 

+//               resetable logic                        

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

+////                                                              ////

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

+////                                                              ////

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

+

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

+      Web-bone cross bar M-Master By S-Slave

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

+

+module wb_crossbar (

+

+              rst_n               , 

+              clk                 ,

+

+

+    // Master Interface Signal

+              wbd_taddr_master    ,

+              wbd_din_master      ,

+              wbd_dout_master     ,

+              wbd_adr_master      , 

+              wbd_be_master       , 

+              wbd_we_master       , 

+              wbd_ack_master      ,

+              wbd_stb_master      , 

+              wbd_cyc_master      , 

+              wbd_err_master      ,

+              wbd_rty_master      ,

+ 

+    // Slave Interface Signal

+              wbd_din_slave       , 

+              wbd_dout_slave      ,

+              wbd_adr_slave       , 

+              wbd_be_slave        , 

+              wbd_we_slave        , 

+              wbd_ack_slave       ,

+              wbd_stb_slave       , 

+              wbd_cyc_slave       , 

+              wbd_err_slave       ,

+              wbd_rty_slave

+         );

+

+parameter WB_SLAVE   = 4 ;

+parameter WB_MASTER  = 4 ;

+

+parameter D_WD    = 16; // Data Width

+parameter BE_WD   = 2;  // Byte Enable

+parameter ADR_WD  = 28; // Address Width

+parameter TAR_WD  = 4;  // Target Width

+

+input                  clk; // CLK_I The clock input [CLK_I] coordinates all activities 

+                            // for the internal logic within the WISHBONE interconnect. 

+                            // All WISHBONE output signals are registered at the 

+                            // rising edge of [CLK_I]. 

+                            // All WISHBONE input signals must be stable before the 

+                            // rising edge of [CLK_I]. 

+input                  rst_n; // RST_I The reset input [RST_I] forces the WISHBONE interface 

+                            // to restart. Furthermore, all internal self-starting state 

+                            // machines will be forced into an initial state. 

+

+input [(WB_MASTER *TAR_WD)-1:0] wbd_taddr_master; // target address from master 

+input [WB_MASTER-1:0]  wbd_stb_master;  

+                    // STB_O The strobe output [STB_O] indicates a valid data 

+                    // transfer cycle. It is used to qualify various other signals 

+                    // on the interface such as [SEL_O(7..0)]. The SLAVE must 

+                    // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in 

+                    // response to every assertion of the [STB_O] signal. 

+output [WB_SLAVE-1:0]  wbd_stb_slave;  

+                    // STB_O The strobe output [STB_O] indicates a valid data 

+                    // transfer cycle. It is used to qualify various other signals 

+                    // on the interface such as [SEL_O(7..0)]. The SLAVE must 

+                    // assert either the [ACK_I], [ERR_I] or [RTY_I] signals in 

+                    // response to every assertion of the [STB_O] signal. 

+

+input [WB_MASTER-1:0]   wbd_we_master;    

+                    // WE_O The write enable output [WE_O] indicates whether the 

+                    // current local bus cycle is a READ or WRITE cycle. The 

+                    // signal is negated during READ cycles, and is asserted 

+                    // during WRITE cycles. 

+output [WB_SLAVE-1:0]   wbd_we_slave;    

+                    // WE_O The write enable output [WE_O] indicates whether the 

+                    // current local bus cycle is a READ or WRITE cycle. The 

+                    // signal is negated during READ cycles, and is asserted 

+                    // during WRITE cycles. 

+

+output [WB_MASTER-1:0]  wbd_ack_master; 

+                    // The acknowledge input [ACK_I], when asserted, 

+                    // indicates the termination of a normal bus cycle. 

+                    // Also see the [ERR_I] and [RTY_I] signal descriptions. 

+input [WB_SLAVE-1:0]  wbd_ack_slave; 

+                    // The acknowledge input [ACK_I], when asserted, 

+                    // indicates the termination of a normal bus cycle. 

+                    // Also see the [ERR_I] and [RTY_I] signal descriptions. 

+

+input [(WB_MASTER *ADR_WD)-1:0] wbd_adr_master; 

+                    // The address output array [ADR_O(63..0)] is used 

+                    // to pass a binary address, with the most significant 

+                    // address bit at the higher numbered end of the signal array. 

+                    // The lower array boundary is specific to the data port size. 

+                    // The higher array boundary is core-specific. 

+                    // In some cases (such as FIFO interfaces) 

+                    // the array may not be present on the interface. 

+

+output [(WB_SLAVE *ADR_WD)-1:0] wbd_adr_slave; 

+                    // The address output array [ADR_O(63..0)] is used 

+                    // to pass a binary address, with the most significant 

+                    // address bit at the higher numbered end of the signal array. 

+                    // The lower array boundary is specific to the data port size. 

+                    // The higher array boundary is core-specific. 

+                    // In some cases (such as FIFO interfaces) 

+                    // the array may not be present on the interface. 

+

+input [(WB_MASTER * BE_WD)-1:0] wbd_be_master; // Byte Enable 

+                    // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates 

+                    // where valid data is expected on the [DAT_I(63..0)] signal 

+                    // array during READ cycles, and where it is placed on the 

+                    // [DAT_O(63..0)] signal array during WRITE cycles. 

+                    // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] 

+                    // signal descriptions.

+output [(WB_SLAVE * BE_WD)-1:0] wbd_be_slave; // Byte Enable  

+                    // SEL_O(7..0) The select output array [SEL_O(7..0)] indicates 

+                    // where valid data is expected on the [DAT_I(63..0)] signal 

+                    // array during READ cycles, and where it is placed on the 

+                    // [DAT_O(63..0)] signal array during WRITE cycles. 

+                    // Also see the [DAT_I(63..0)], [DAT_O(63..0)] and [STB_O] 

+                    // signal descriptions.

+

+input [WB_MASTER -1:0] wbd_cyc_master; 

+                    // CYC_O The cycle output [CYC_O], when asserted, 

+                    // indicates that a valid bus cycle is in progress. 

+                    // The signal is asserted for the duration of all bus cycles. 

+                    // For example, during a BLOCK transfer cycle there can be 

+                    // multiple data transfers. The [CYC_O] signal is asserted 

+                    // during the first data transfer, and remains asserted 

+                    // until the last data transfer. The [CYC_O] signal is useful 

+                    // for interfaces with multi-port interfaces 

+                    // (such as dual port memories). In these cases, 

+                    // the [CYC_O] signal requests use of a common bus from an 

+                    // arbiter. Once the arbiter grants the bus to the MASTER, 

+                    // it is held until [CYC_O] is negated. 

+output [WB_SLAVE -1:0] wbd_cyc_slave; 

+                    // CYC_O The cycle output [CYC_O], when asserted, 

+                    // indicates that a valid bus cycle is in progress. 

+                    // The signal is asserted for the duration of all bus cycles. 

+                    // For example, during a BLOCK transfer cycle there can be 

+                    // multiple data transfers. The [CYC_O] signal is asserted 

+                    // during the first data transfer, and remains asserted 

+                    // until the last data transfer. The [CYC_O] signal is useful 

+                    // for interfaces with multi-port interfaces 

+                    // (such as dual port memories). In these cases, 

+                    // the [CYC_O] signal requests use of a common bus from an 

+                    // arbiter. Once the arbiter grants the bus to the MASTER, 

+                    // it is held until [CYC_O] is negated. 

+

+input [(WB_MASTER * D_WD)-1:0] wbd_din_master;  

+                    // DAT_I(63..0) The data input array [DAT_I(63..0)] is 

+                    // used to pass binary data. The array boundaries are 

+                    // determined by the port size. Also see the [DAT_O(63..0)] 

+                    // and [SEL_O(7..0)] signal descriptions. 

+

+output [(WB_SLAVE * D_WD)-1:0] wbd_din_slave;  

+                    // DAT_I(63..0) The data input array [DAT_I(63..0)] is 

+                    // used to pass binary data. The array boundaries are 

+                    // determined by the port size. Also see the [DAT_O(63..0)] 

+                    // and [SEL_O(7..0)] signal descriptions. 

+

+output [(WB_MASTER * D_WD)-1:0] wbd_dout_master; 

+                    // DAT_O(63..0) The data output array [DAT_O(63..0)] is 

+                    // used to pass binary data. The array boundaries are 

+                    // determined by the port size. Also see the [DAT_I(63..0)] 

+                         // and [SEL_O(7..0)] signal descriptions. 

+input [(WB_SLAVE * D_WD)-1:0] wbd_dout_slave; 

+                    // DAT_O(63..0) The data output array [DAT_O(63..0)] is 

+                    // used to pass binary data. The array boundaries are 

+                    // determined by the port size. Also see the [DAT_I(63..0)] 

+                    // and [SEL_O(7..0)] signal descriptions. 

+

+output [WB_MASTER -1:0]  wbd_err_master; 

+                    // ERR_I The error input [ERR_I] indicates an abnormal 

+                    // cycle termination. The source of the error, and the 

+                    // response generated by the MASTER is defined by the IP core 

+                    // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] 

+                    // and [RTY_I] signal descriptions. 

+input [WB_SLAVE -1:0]  wbd_err_slave; 

+                    // ERR_I The error input [ERR_I] indicates an abnormal 

+                    // cycle termination. The source of the error, and the 

+                    // response generated by the MASTER is defined by the IP core 

+                    // supplier in the WISHBONE DATASHEET. Also see the [ACK_I] 

+                    // and [RTY_I] signal descriptions. 

+

+output [WB_MASTER -1:0]   wbd_rty_master; 

+                    // RTY_I The retry input [RTY_I] indicates that the indicates 

+                    // that the interface is not ready to accept or send data, and 

+                    // that the cycle should be retried. When and how the cycle is 

+                    // retried is defined by the IP core supplier in the WISHBONE 

+                    // DATASHEET. Also see the [ERR_I] and [RTY_I] signal 

+                    // descriptions. 

+input [WB_SLAVE -1:0]   wbd_rty_slave; 

+                    // RTY_I The retry input [RTY_I] indicates that the indicates 

+                    // that the interface is not ready to accept or send data, and 

+                    // that the cycle should be retried. When and how the cycle is 

+                    // retried is defined by the IP core supplier in the WISHBONE 

+                    // DATASHEET. Also see the [ERR_I] and [RTY_I] signal 

+                    // descriptions. 

+

+

+reg  [WB_MASTER-1:0]  wbd_ack_master; 

+reg  [WB_MASTER-1:0]  wbd_err_master; 

+reg  [WB_MASTER-1:0]  wbd_rty_master; 

+

+

+reg  [WB_MASTER-1:0]  master_busy; // master busy flag

+reg  [WB_SLAVE-1:0]   slave_busy;  // slave busy flag

+reg  [TAR_WD -1:0]     master_mx_id[WB_MASTER-1:0];

+reg  [TAR_WD -1:0]     slave_mx_id [WB_SLAVE-1:0];

+

+wire  [TAR_WD-1:0]     wbd_taddr_master_t[WB_MASTER-1:0]; // target address from master 

+wire  [D_WD-1:0]       wbd_din_master_t[WB_MASTER-1:0]; // target address from master 

+reg   [D_WD-1:0]       wbd_dout_master_t[WB_MASTER-1:0]; // target address from master 

+wire  [ADR_WD-1:0]     wbd_adr_master_t[WB_MASTER-1:0]; // target address from master 

+wire  [BE_WD-1:0]      wbd_be_master_t[WB_MASTER-1:0]; // target address from master 

+

+

+reg  [WB_SLAVE-1:0]  wbd_stb_slave; 

+reg  [WB_SLAVE-1:0]  wbd_we_slave; 

+reg  [WB_SLAVE-1:0]  wbd_cyc_slave; 

+wire [D_WD-1:0]      wbd_dout_slave_t[WB_SLAVE-1:0]; // target data towards master 

+

+

+reg   [D_WD-1:0]     wbd_din_slave_t[WB_SLAVE-1:0]; // target address from master 

+reg   [ADR_WD-1:0]    wbd_adr_slave_t[WB_SLAVE-1:0]; // target address from master 

+reg   [BE_WD-1:0]     wbd_be_slave_t[WB_SLAVE-1:0]; // target address from master 

+

+integer i,k,l,n;

+

+  

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

+   Re-Arraging the array in seperate two dimensional information

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

+

+genvar j,m; 

+generate        

+

+  // Connect the Master Mux

+  for(j=0; j < WB_MASTER ; j = j + 1) begin : master_expand

+     assign wbd_taddr_master_t[j] = wbd_taddr_master[((j+1)*TAR_WD)-1:j * TAR_WD];

+     assign wbd_din_master_t[j]  = wbd_din_master[((j+1)*D_WD)-1:j * D_WD];

+     assign wbd_adr_master_t[j]  = wbd_adr_master[((j+1)*ADR_WD)-1:j * ADR_WD];

+     assign wbd_be_master_t[j]   = wbd_be_master[((j+1)*BE_WD)-1:j * BE_WD];

+

+     assign wbd_dout_master[((j+1)*D_WD)-1:j * D_WD] = wbd_dout_master_t[j];

+  end

+

+  // Connect the Slave Mux

+  for(m=0; m < WB_SLAVE ; m = m + 1) begin : slave_expand

+     assign wbd_din_slave[((m+1)*D_WD)-1:m * D_WD]        = wbd_din_slave_t[m];

+     assign wbd_adr_slave[((m+1)*ADR_WD)-1:m * ADR_WD]   = wbd_adr_slave_t[m];

+     assign wbd_be_slave[((m+1)*BE_WD)-1:m * BE_WD]      = wbd_be_slave_t[m];

+

+     assign wbd_dout_slave_t[m]   = wbd_dout_slave[((m+1)*D_WD)-1:m * D_WD];

+

+  end

+endgenerate

+

+always @*   begin

+   for(k = 0; k < WB_MASTER; k = k + 1) begin

+      if(master_busy[k] == 1) begin

+         wbd_dout_master_t[k] = wbd_dout_slave_t[master_mx_id[k]];

+         wbd_ack_master[k]    = wbd_ack_slave[master_mx_id[k]];

+         wbd_err_master[k]    = wbd_err_slave[master_mx_id[k]];

+         wbd_rty_master[k]    = wbd_rty_slave[master_mx_id[k]];

+      end else begin

+         wbd_dout_master_t[k] = 0;

+         wbd_ack_master[k]    = 0;

+         wbd_err_master[k]    = 0;

+         wbd_rty_master[k]    = 0;

+      end

+   end

+   for(l = 0; l < WB_SLAVE; l = l + 1) begin

+      if(slave_busy[l] == 1) begin

+         wbd_din_slave_t[l]  = wbd_din_master_t[slave_mx_id[l]];

+         wbd_adr_slave_t[l]  = wbd_adr_master_t[slave_mx_id[l]];

+         wbd_be_slave_t[l]   = wbd_be_master_t[slave_mx_id[l]];

+         wbd_stb_slave[l]    = wbd_stb_master[slave_mx_id[l]];

+         wbd_we_slave[l]     = wbd_we_master[slave_mx_id[l]];

+         wbd_cyc_slave[l]    = wbd_cyc_master[slave_mx_id[l]];

+      end else begin

+         wbd_din_slave_t[l]  = 0;

+         wbd_adr_slave_t[l]  = 0;

+         wbd_be_slave_t[l]   = 0;

+         wbd_stb_slave[l]    = 0;

+         wbd_we_slave[l]     = 0;

+         wbd_cyc_slave[l]    = 0;

+      end

+   end

+end

+

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

+   Parsing through the master and deciding on mux connectio

+   Step-1: analysis the master from 0 to total master

+   Step-2: If the previously master is not busy, 

+           Then check for any new request from the master and

+           check corresponding slave is free or not. If there is 

+           master request and requesting slave is free. 

+           Then set the master max id to slave id &

+           requesting slave to master number & set the master

+           and slave busy flag

+   Step-3: If the previous state of master is busy and bus-cycle

+           is de-asserted, then reset the master and corresponding

+           slave busy flag

+

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

+

+always @(negedge rst_n or posedge clk) begin

+   if(rst_n == 0) begin

+      master_busy   <= 0;

+      slave_busy    <= 0;

+   end else begin

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

+         if(master_busy[i] == 0) begin

+            if(wbd_stb_master[i] & slave_busy[wbd_taddr_master_t[i]] == 0) begin

+               slave_busy[wbd_taddr_master_t[i]]   <= 1;

+               master_busy[i]              <= 1;

+            end

+         end else if(wbd_cyc_master[i] == 0) begin

+            master_busy[i]            <= 0;

+            slave_busy[wbd_taddr_master_t[i]] <= 0;

+         end

+      end

+   end

+end

+

+// Seperated non resetable two dimensional reg

+always @(posedge clk) begin

+      for(n = 0; n < WB_MASTER; n = n + 1) begin

+         if(master_busy[n] == 0) begin

+            if(wbd_stb_master[n] & slave_busy[wbd_taddr_master_t[n]] == 0) begin

+               master_mx_id[n] <= wbd_taddr_master_t[n];

+               slave_mx_id [wbd_taddr_master_t[n]] <= n;

+               // synopsys translate_off

+               // $display("%m:%t: Locking Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]);

+               // synopsys translate_on

+            end

+         end else if(wbd_cyc_master[n] == 0) begin

+	    if(master_busy[n] == 1) begin

+            // synopsys translate_off

+            //  $display("%m:%t: Releasing Master : %d with Slave : %d",$time,i,wbd_taddr_master_t[n]);

+            // synopsys translate_on

+            end

+         end

+      end

+end

+

+

+endmodule

diff --git a/verilog/rtl/lib/wb_interface.v b/verilog/rtl/lib/wb_interface.v
new file mode 100644
index 0000000..aae1695
--- /dev/null
+++ b/verilog/rtl/lib/wb_interface.v
@@ -0,0 +1,383 @@
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+////  OMS 8051 cores common library Module                        ////
+////                                                              ////
+////  This file is part of the OMS 8051 cores project             ////
+////  http://www.opencores.org/cores/oms8051mini/                 ////
+////                                                              ////
+////  Description                                                 ////
+////  OMS 8051 definitions.                                       ////
+////                                                              ////
+////  To Do:                                                      ////
+////    nothing                                                   ////
+////                                                              ////
+////  Author(s):                                                  ////
+////      - Dinesh Annayya, dinesha@opencores.org                 ////
+////                                                              ////
+////  Revision : Nov 26, 2016                                     //// 
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+////                                                              ////
+//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
+////                                                              ////
+//// This source file may be used and distributed without         ////
+//// restriction provided that this copyright statement is not    ////
+//// removed from the file and that any derivative work contains  ////
+//// the original copyright notice and the associated disclaimer. ////
+////                                                              ////
+//// This source file is free software; you can redistribute it   ////
+//// and/or modify it under the terms of the GNU Lesser General   ////
+//// Public License as published by the Free Software Foundation; ////
+//// either version 2.1 of the License, or (at your option) any   ////
+//// later version.                                               ////
+////                                                              ////
+//// This source is distributed in the hope that it will be       ////
+//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
+//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
+//// PURPOSE.  See the GNU Lesser General Public License for more ////
+//// details.                                                     ////
+////                                                              ////
+//// You should have received a copy of the GNU Lesser General    ////
+//// Public License along with this source; if not, download it   ////
+//// from http://www.opencores.org/lgpl.shtml                     ////
+////                                                              ////
+//////////////////////////////////////////////////////////////////////
+
+module wb_interface (
+          rst          , 
+          clk          ,
+
+          dma_req_i    ,
+          dma_write_i  ,
+          dma_addr_i   ,
+          dma_length_i ,
+          dma_ack_o    ,
+          dma_done_o   ,
+
+          dma_start_o  ,
+          dma_wr_o     ,
+          dma_rd_o     ,
+          dma_last_o   ,
+          dma_wdata_i  ,
+          dma_rdata_o  ,
+
+    // external memory
+          wbd_dat_i    , 
+          wbd_dat_o    ,
+          wbd_adr_o    , 
+          wbd_be_o     , 
+          wbd_we_o     , 
+          wbd_ack_i    ,
+          wbd_stb_o    , 
+          wbd_cyc_o    , 
+          wbd_err_i    
+
+
+     );
+
+
+
+input            rst             ; 
+input            clk             ;
+
+input            dma_req_i       ;
+input            dma_write_i     ;
+input [25:0]     dma_addr_i      ;
+input [7:0]      dma_length_i    ;
+output           dma_ack_o       ;
+output           dma_done_o      ; // indicates end of DMA transaction
+
+output           dma_start_o     ;
+output           dma_wr_o        ;
+output           dma_rd_o        ;
+output           dma_last_o      ;
+input  [31:0]    dma_wdata_i     ;
+output [31:0]    dma_rdata_o     ;
+
+//--------------------------------
+// WB interface
+//--------------------------------
+input  [31:0]    wbd_dat_i       ; // data input
+output [31:0]    wbd_dat_o       ; // data output
+output [23:0]    wbd_adr_o       ; // address
+output  [3:0]    wbd_be_o        ; // byte enable
+output           wbd_we_o        ; // write 
+input            wbd_ack_i       ; // acknowlegement
+output           wbd_stb_o       ; // strobe/request
+output           wbd_cyc_o       ; // wb cycle
+input            wbd_err_i       ; // we error
+
+//------------------------------------
+// Reg Declaration
+//--------------------------------
+reg [2:0]        state           ;
+reg [2:0]        state_d         ;
+reg [7:0]        preq_len        ; // pending request length in bytes
+reg              wbd_we_o        ; // westbone write req
+reg [23:0]       wbd_adr_o       ; // westnone address
+reg              dma_ack_o       ; // dma ack
+reg [7:0]        twbtrans        ; // total westbone transaction
+reg              dma_wr_o        ; // dma write request
+reg              dma_rd_o        ; // dma read request
+reg [31:0]       temp_data       ; // temp holding data
+reg [1:0]        be_sof          ; // Byte enable starting alignment
+reg [31:0]       wbd_dat_o       ; // westbone data out
+reg [3:0]        wbd_be_o        ; // west bone byte enable 
+reg [31:0]       dma_rdata_o     ; // dma read data
+reg              wbd_stb_o       ; 
+reg              dma_start_o     ; // dma first transfer
+reg              dma_last_o      ; // dma last transfer
+
+parameter WB_IDLE           = 3'b000;
+parameter WB_REQ            = 3'b001;
+parameter WB_WR_PHASE       = 3'b010;
+parameter WB_RD_PHASE_SOF   = 3'b011;
+parameter WB_RD_PHASE_CONT  = 3'b100;
+
+assign dma_done_o = (state == WB_IDLE) && (state_d !=  WB_IDLE);
+
+always @(posedge rst or posedge clk)
+begin
+   if(rst) begin
+      state         <= WB_IDLE;
+      state_d       <= WB_IDLE;
+      wbd_we_o      <= 0;
+      wbd_adr_o     <= 0;
+      preq_len      <= 0;
+      dma_ack_o     <= 0;
+      twbtrans      <= 0;
+      dma_wr_o      <= 0;
+      dma_rd_o      <= 0;
+      temp_data     <= 0;
+      be_sof        <= 0;
+      wbd_dat_o     <= 0; 
+      wbd_be_o      <= 0; 
+      dma_rdata_o   <= 0;
+      wbd_stb_o     <= 0;
+      dma_start_o   <= 0;
+      dma_last_o    <= 0;
+   end
+   else begin
+      state_d       <= state;
+      case(state)
+      WB_IDLE : 
+         begin
+            if(dma_req_i)
+            begin
+               dma_ack_o  <= 1;
+               wbd_we_o   <= dma_write_i;
+               wbd_adr_o  <= dma_addr_i[25:2];
+               be_sof     <= dma_addr_i[1] << 1 + dma_addr_i[0];
+               preq_len   <= dma_length_i;
+               // total wb transfer
+               twbtrans   <= dma_length_i[7:2] + 
+                             |(dma_length_i[1:0]) + 
+                             |(dma_addr_i[1:0]);
+               state       <= WB_REQ;
+            end 
+            dma_wr_o   <= 0;
+            dma_rd_o   <= 0;
+            wbd_stb_o  <= 0;
+            dma_start_o  <= 0;
+         end
+      WB_REQ :
+         begin
+            dma_ack_o      <= 0;
+            wbd_stb_o      <= 1;
+            if(wbd_we_o) begin
+               dma_wr_o    <= 1;
+               dma_start_o <= 1;
+               temp_data   <= dma_wdata_i; 
+               if(be_sof == 0) begin
+                  wbd_dat_o  <= dma_wdata_i; 
+                  wbd_be_o   <= 4'b1111; 
+                  preq_len    <= preq_len - 4;
+               end 
+               else if(be_sof == 1) begin
+                  wbd_dat_o  <= {dma_wdata_i[23:0],8'h0}; 
+                  wbd_be_o   <= 4'b1110; 
+                  preq_len    <= preq_len - 3;
+               end
+               else if(be_sof == 2) begin
+                  wbd_dat_o  <= {dma_wdata_i[15:0],16'h0}; 
+                  wbd_be_o   <= 4'b1100; 
+                  preq_len    <= preq_len - 2;
+               end
+               else begin
+                  wbd_dat_o  <= {dma_wdata_i[7:0],23'h0}; 
+                  wbd_be_o   <= 4'b1000; 
+                  preq_len    <= preq_len - 1;
+               end
+               twbtrans   <= twbtrans -1;
+               state      <= WB_WR_PHASE;
+               if(twbtrans == 1) 
+                   dma_last_o <= 1;
+            end
+            else begin
+               state   <= WB_RD_PHASE_SOF;
+            end
+         end
+      WB_WR_PHASE :
+         begin
+            dma_start_o       <= 0;
+            if(wbd_ack_i) begin
+               if(twbtrans == 1) 
+                   dma_last_o <= 1;
+               else
+                   dma_last_o <= 0;
+               if(twbtrans > 0) begin
+                  temp_data   <= dma_wdata_i; 
+                  twbtrans    <= twbtrans -1;
+                  if(be_sof == 0) begin
+                     wbd_dat_o  <= dma_wdata_i; 
+                  end 
+                  else if(be_sof == 1) begin
+                     wbd_dat_o  <= {dma_wdata_i[23:0],temp_data[31:24]}; 
+                  end
+                  else if(be_sof == 2) begin
+                     wbd_dat_o  <= {dma_wdata_i[15:0],temp_data[31:16]}; 
+                  end
+                  else begin
+                     wbd_dat_o  <= {dma_wdata_i[7:0],temp_data[31:8]}; 
+                  end
+
+                  if(twbtrans > 1) begin // If the Pending Transfer is more than 1
+                     dma_wr_o   <= 1;
+                     wbd_be_o   <= 4'b1111; 
+                     preq_len   <= preq_len - 4;
+                  end
+                  else begin // for last write access
+                     wbd_be_o   <= preq_len[1:0] == 2'b00 ? 4'b1111:
+                                   preq_len[1:0] == 2'b01 ? 4'b0001:
+                                   preq_len[1:0] == 2'b10 ? 4'b0011: 4'b0111;
+
+                     case({be_sof[1:0],preq_len[1:0]})
+                        // Start alignment = 0
+                        4'b0001 : dma_wr_o   <= 1;
+                        4'b0010 : dma_wr_o   <= 1;
+                        4'b0011 : dma_wr_o   <= 1;
+                        4'b0000 : dma_wr_o   <= 1;
+                        // Start alignment = 1
+                        4'b0101 : dma_wr_o   <= 0;
+                        4'b0110 : dma_wr_o   <= 1;
+                        4'b0111 : dma_wr_o   <= 1;
+                        4'b0100 : dma_wr_o   <= 1;
+                        // Start alignment = 2
+                        4'b1001 : dma_wr_o   <= 0;
+                        4'b1010 : dma_wr_o   <= 0;
+                        4'b1011 : dma_wr_o   <= 1;
+                        4'b1000 : dma_wr_o   <= 1;
+                        // Start alignment = 3
+                        4'b1101 : dma_wr_o   <= 0;
+                        4'b1110 : dma_wr_o   <= 0;
+                        4'b1111 : dma_wr_o   <= 0;
+                        4'b1100 : dma_wr_o   <= 1;
+                     endcase
+                  end
+               end
+               else begin
+                  dma_wr_o  <= 0;
+                  wbd_stb_o <= 0;
+                  state     <= WB_IDLE;
+               end 
+            end
+            else begin
+               dma_last_o <= 0;
+               dma_wr_o   <= 0;
+            end
+         end
+      WB_RD_PHASE_SOF :
+         begin
+            if(wbd_ack_i) begin
+               twbtrans    <= twbtrans -1;
+               if(twbtrans == 1) begin // If the Pending Transfer is 1
+                   dma_rd_o   <= 1;
+                   dma_start_o<= 1;
+                   if(be_sof == 0) begin
+                       dma_rdata_o  <= wbd_dat_i; 
+                       preq_len     <= preq_len - 4;
+                   end 
+                   else if(be_sof == 1) begin
+                       dma_rdata_o  <= {8'h0,wbd_dat_i[31:24]}; 
+                       preq_len     <= preq_len - 3;
+                   end
+                   else if(be_sof == 2) begin
+                       dma_rdata_o  <= {16'h0,wbd_dat_i[31:16]}; 
+                       preq_len     <= preq_len - 2;
+                   end
+                   else begin
+                       dma_rdata_o  <= {23'h0,wbd_dat_i[31:8]}; 
+                       preq_len     <= preq_len - 0;
+                   end
+                   dma_last_o <= 1;
+                   state      <= WB_IDLE;
+               end
+               else begin // pending transction is more than 1
+                  if(be_sof == 0) begin
+                      dma_rdata_o  <= wbd_dat_i; 
+                      dma_rd_o     <= 1;
+                      dma_start_o  <= 1;
+                      preq_len     <= preq_len - 4;
+                  end 
+                  else if(be_sof == 1) begin
+                      temp_data    <= {8'h0,wbd_dat_i[31:24]}; 
+                      dma_rd_o     <= 0;
+                      preq_len     <= preq_len - 3;
+                  end
+                  else if(be_sof == 2) begin
+                      temp_data   <= {16'h0,wbd_dat_i[31:16]}; 
+                      preq_len    <= preq_len - 2;
+                  end
+                  else begin
+                      temp_data   <= {23'h0,wbd_dat_i[31:8]}; 
+                      preq_len    <= preq_len - 0;
+                  end
+                  state     <= WB_RD_PHASE_CONT;
+               end
+            end
+            else begin
+               dma_rd_o  <= 0;
+            end
+         end
+      WB_RD_PHASE_CONT:
+         begin
+            dma_start_o  <= 0;
+            if(wbd_ack_i) begin
+               dma_rd_o         <= 1;
+               twbtrans         <= twbtrans -1;
+               if(be_sof == 0) begin
+                  dma_rdata_o   <= wbd_dat_i; 
+                  preq_len      <= preq_len - 4;
+               end 
+               else if(be_sof == 1) begin
+                  dma_rdata_o   <= {wbd_dat_i[7:0],temp_data[23:0]}; 
+                  temp_data     <= {8'h0,wbd_dat_i[31:8]};
+                  preq_len      <= preq_len - 3;
+               end
+               else if(be_sof == 2) begin
+                  dma_rdata_o   <= {wbd_dat_i[15:0],temp_data[15:0]}; 
+                  temp_data     <= {16'h0,wbd_dat_i[31:16]};
+                  preq_len      <= preq_len - 2;
+               end
+               else begin
+                  dma_rdata_o   <= {wbd_dat_i[23:0],temp_data[7:0]}; 
+                  temp_data     <= {24'h0,wbd_dat_i[31:23]};
+                  preq_len      <= preq_len - 1;
+               end
+               if(twbtrans == 1) begin  // If the it's last transfer
+                  dma_last_o <= 1;
+                  state      <= WB_IDLE;
+               end
+            end
+            else begin
+               dma_last_o <= 0;
+               dma_rd_o   <= 0;
+            end
+         end
+      endcase
+   end
+end 
+
+
+
+endmodule
diff --git a/verilog/rtl/syntacore_scr1/.gitignore b/verilog/rtl/syntacore_scr1/.gitignore
new file mode 100644
index 0000000..7a71ac8
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/.gitignore
@@ -0,0 +1,2 @@
+build/**
+sim/tests/benchmarks/coremark/src/**
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/.gitmodules b/verilog/rtl/syntacore_scr1/.gitmodules
new file mode 100644
index 0000000..937d721
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/.gitmodules
@@ -0,0 +1,9 @@
+[submodule "dependencies/riscv-tests"]
+	path = dependencies/riscv-tests
+	url = https://github.com/riscv/riscv-tests
+[submodule "dependencies/riscv-compliance"]
+	path = dependencies/riscv-compliance
+	url = https://github.com/riscv/riscv-compliance
+[submodule "dependencies/coremark"]
+	path = dependencies/coremark
+	url = https://github.com/eembc/coremark
diff --git a/verilog/rtl/syntacore_scr1/LICENSE b/verilog/rtl/syntacore_scr1/LICENSE
new file mode 100644
index 0000000..0d753ad
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/LICENSE
@@ -0,0 +1,23 @@
+# Solderpad Hardware Licence Version 2.0
+
+This licence (the “Licence”) operates as a wraparound licence to the Apache License Version 2.0 (the “Apache License”) and grants to You the rights, and imposes the obligations, set out in the Apache License (which can be found here: http://apache.org/licenses/LICENSE-2.0), with the following extensions. It must be read in conjunction with the Apache License. Section 1 below modifies definitions in the Apache License, and section 2 below replaces sections 2 of the Apache License. You may, at your option, choose to treat any Work released under this License as released under the Apache License (thus ignoring all sections written below entirely). Words in italics indicate changes rom the Apache License, but are indicative and not to be taken into account in interpretation.
+
+1. The definitions set out in the Apache License are modified as follows:
+
+Copyright any reference to ‘copyright’ (whether capitalised or not) includes ‘Rights’ (as defined below).
+
+Contribution also includes any design, as well as any work of authorship.
+
+Derivative Works shall not include works that remain reversibly separable from, or merely link (or bind by name) or physically connect to or interoperate with the interfaces of the Work and Derivative Works thereof.
+
+Object form shall mean any form resulting from mechanical transformation or translation of a Source form or the application of a Source form to physical material, including but not limited to compiled object code, generated documentation, the instantiation of a hardware design or physical object and conversions to other media types, including intermediate forms such as bytecodes, FPGA bitstreams, moulds, artwork and semiconductor topographies (mask works).
+
+Rights means copyright and any similar right including design right (whether registered or unregistered), semiconductor topography (mask) rights and database rights (but excluding Patents and Trademarks).
+
+Source form shall mean the preferred form for making modifications, including but not limited to source code, net lists, board layouts, CAD files, documentation source, and configuration files.
+
+Work also includes a design or work of authorship, whether in Source form or other Object form.
+
+2. Grant of Licence
+
+2.1 Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under the Rights to reproduce, prepare Derivative Works of, make, adapt, repair, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form and do anything in relation to the Work as if the Rights did not exist.
diff --git a/verilog/rtl/syntacore_scr1/Makefile b/verilog/rtl/syntacore_scr1/Makefile
new file mode 100644
index 0000000..adb33c5
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/Makefile
@@ -0,0 +1,293 @@
+#------------------------------------------------------------------------------
+# Makefile for SCR1
+#------------------------------------------------------------------------------
+
+# PARAMETERS
+
+# CFG = <MAX, BASE, MIN, CUSTOM>
+# BUS = <AHB, AXI>
+
+export CFG      ?= MAX
+export BUS      ?= AHB
+
+ifeq ($(CFG), MAX)
+# Predefined configuration SCR1_CFG_RV32IMC_MAX
+    override ARCH         := IMC
+    override VECT_IRQ     := 1
+    override IPIC         := 1
+    override TCM          := 1
+    override SIM_CFG_DEF  := SCR1_CFG_RV32IMC_MAX
+else
+    ifeq ($(CFG), BASE)
+    # Predefined configuration SCR1_CFG_RV32IC_BASE
+        override ARCH         := IC
+        override VECT_IRQ     := 1
+        override IPIC         := 1
+        override TCM          := 1
+        override SIM_CFG_DEF  := SCR1_CFG_RV32IC_BASE
+    else
+        ifeq ($(CFG), MIN)
+        # Predefined configuration SCR1_CFG_RV32EC_MIN
+            override ARCH         := EC
+            override VECT_IRQ     := 0
+            override IPIC         := 0
+            override TCM          := 1
+            override SIM_CFG_DEF  := SCR1_CFG_RV32EC_MIN
+        else
+        # CUSTOM configuration. Parameters can be overwritten
+            # These options are for compiling tests only. Set the corresponding RTL parameters manually in the file scr1_arch_description.svh.
+            # ARCH = <IMC, IC, IM, I, EMC, EM, EC, E>
+            # VECT_IRQ = <0, 1>
+            # IPIC = <0, 1>
+            # TCM = <0, 1>
+            ARCH      ?= IMC
+            VECT_IRQ  ?= 0
+            IPIC      ?= 0
+            TCM       ?= 0
+            SIM_CFG_DEF  = SCR1_CFG_$(CFG)
+        endif
+    endif
+endif
+
+# export all overrided variables
+export ARCH
+export VECT_IRQ
+export IPIC
+export TCM
+export SIM_CFG_DEF
+
+ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z)
+BUS_lowercase  = $(shell echo $(BUS)  | tr A-Z a-z)
+
+ifeq ($(ARCH_lowercase),)
+    ARCH_tmp = imc
+else
+    ifneq (,$(findstring e,$(ARCH_lowercase)))
+        ARCH_tmp   += e
+        EXT_CFLAGS += -D__RVE_EXT
+    else
+        ARCH_tmp   += i
+    endif
+    ifneq (,$(findstring m,$(ARCH_lowercase)))
+        ARCH_tmp   := $(ARCH_tmp)m
+    endif
+    ifneq (,$(findstring c,$(ARCH_lowercase)))
+        ARCH_tmp   := $(ARCH_tmp)c
+        EXT_CFLAGS += -D__RVC_EXT
+    endif
+endif
+
+override ARCH=$(ARCH_tmp)
+
+# Use this parameter to enable tracelog
+TRACE ?= 0
+
+ifeq ($(TRACE), 1)
+    export SIM_TRACE_DEF = SCR1_TRACE_LOG_EN
+else
+    export SIM_TRACE_DEF = SCR1_TRACE_LOG_DIS
+endif
+
+
+# Use this parameter to pass additional options for simulation build command
+SIM_BUILD_OPTS ?=
+
+# Use this parameter to set the list of tests to run
+# TARGETS = <riscv_isa, riscv_compliance, coremark, dhrystone21, hello, isr_sample>
+export TARGETS :=
+
+
+export ABI   ?= ilp32
+# Testbench memory delay patterns\
+  (FFFFFFFF - no delay, 00000000 - random delay, 00000001 - max delay)
+imem_pattern ?= FFFFFFFF
+dmem_pattern ?= FFFFFFFF
+
+VCS_OPTS       ?=
+MODELSIM_OPTS  ?=
+NCSIM_OPTS     ?=
+VERILATOR_OPTS ?=
+
+current_goal := $(MAKECMDGOALS:run_%=%)
+ifeq ($(current_goal),)
+    current_goal := verilator
+endif
+
+# Paths
+export root_dir := $(shell pwd)
+export tst_dir  := $(root_dir)/sim/tests
+export inc_dir  := $(tst_dir)/common
+export bld_dir  := $(root_dir)/build/$(current_goal)_$(BUS)_$(CFG)_$(ARCH)_IPIC_$(IPIC)_TCM_$(TCM)_VIRQ_$(VECT_IRQ)_TRACE_$(TRACE)
+
+test_results := $(bld_dir)/test_results.txt
+test_info    := $(bld_dir)/test_info
+sim_results  := $(bld_dir)/sim_results.txt
+
+todo_list    := $(bld_dir)/todo.txt
+# Environment
+export CROSS_PREFIX  ?= riscv64-unknown-elf-
+export RISCV_GCC     ?= $(CROSS_PREFIX)gcc
+export RISCV_OBJDUMP ?= $(CROSS_PREFIX)objdump -D
+export RISCV_OBJCOPY ?= $(CROSS_PREFIX)objcopy -O verilog
+export RISCV_READELF ?= $(CROSS_PREFIX)readelf -s
+#--
+ifneq (,$(findstring axi,$(BUS_lowercase)))
+export rtl_top_files := axi_top.files
+export rtl_tb_files  := axi_tb.files
+export top_module    := scr1_top_tb_axi
+else
+export rtl_top_files := ahb_top.files
+export rtl_tb_files  := ahb_tb.files
+export top_module    := scr1_top_tb_ahb
+endif
+
+ifneq (,$(findstring e,$(ARCH_lowercase)))
+# Tests can be compiled for RVE only if gcc version 8.0.0 or higher
+    GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7)
+    ifeq "$(GCCVERSIONGT7)" "1"
+        ABI := ilp32e
+    endif
+endif
+
+#--
+ifeq (,$(findstring e,$(ARCH_lowercase)))
+# These tests cannot be compiled for RVE
+
+    # Comment this target if you don't want to run the riscv_isa
+    TARGETS += riscv_isa
+
+    # Comment this target if you don't want to run the riscv_compliance
+    TARGETS += riscv_compliance
+endif
+
+# Comment this target if you don't want to run the isr_sample
+TARGETS += isr_sample
+
+# Comment this target if you don't want to run the coremark
+TARGETS += coremark
+
+# Comment this target if you don't want to run the dhrystone
+TARGETS += dhrystone21
+
+# Comment this target if you don't want to run the hello test
+TARGETS += hello
+
+# Targets
+.PHONY: tests run_modelsim run_vcs run_ncsim run_verilator run_verilator_wf
+
+default: clean_test_list run_verilator
+
+clean_test_list:
+	rm -f $(test_info)
+
+echo_out: tests
+	@echo "                          Test               | build | simulation " ;
+	@echo "$$(cat $(test_results))"
+
+tests: $(TARGETS)
+
+$(test_info): clean_hex tests
+	cd $(bld_dir)
+
+isr_sample: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/isr_sample ARCH=$(ARCH) IPIC=$(IPIC) VECT_IRQ=$(VECT_IRQ)
+
+dhrystone21: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+coremark: | $(bld_dir)
+	-$(MAKE) -C $(tst_dir)/benchmarks/coremark EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+riscv_isa: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/riscv_isa ARCH=$(ARCH)
+
+riscv_compliance: | $(bld_dir)
+	$(MAKE) -C $(tst_dir)/riscv_compliance ARCH=$(ARCH)
+
+hello: | $(bld_dir)
+	-$(MAKE) -C $(tst_dir)/hello EXT_CFLAGS="$(EXT_CFLAGS)" ARCH=$(ARCH)
+
+clean_hex: | $(bld_dir)
+	$(RM) $(bld_dir)/*.hex
+
+$(bld_dir):
+	mkdir -p $(bld_dir)
+
+run_vcs: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_vcs SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	$(bld_dir)/simv  -V \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VCS_OPTS) | tee $(sim_results)  ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+run_modelsim: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_modelsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS); \
+	printf "" > $(test_results); \
+	cd $(bld_dir); \
+	vsim -c -do "run -all" +nowarn3691 \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	work.$(top_module) \
+	$(MODELSIM_OPTS) | tee $(sim_results)  ;\
+	printf "Simulation performed on $$(vsim -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_ncsim: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_ncsim SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	irun \
+	-R \
+	-64bit \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(NCSIM_OPTS) | tee $(sim_results)  ;\
+	printf "Simulation performed on $$(irun -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_verilator: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_verilator SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	echo $(top_module) | tee $(sim_results); \
+	$(bld_dir)/verilator/V$(top_module) \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VERILATOR_OPTS) | tee -a $(sim_results) ;\
+	printf "Simulation performed on $$(verilator -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+
+run_verilator_wf: $(test_info)
+	$(MAKE) -C $(root_dir)/sim build_verilator_wf SIM_CFG_DEF=$(SIM_CFG_DEF) SIM_TRACE_DEF=$(SIM_TRACE_DEF) SIM_BUILD_OPTS=$(SIM_BUILD_OPTS);
+	printf "" > $(test_results);
+	cd $(bld_dir); \
+	echo $(top_module) | tee $(sim_results); \
+	$(bld_dir)/verilator/V$(top_module) \
+	+test_info=$(test_info) \
+	+test_results=$(test_results) \
+	+imem_pattern=$(imem_pattern) \
+	+dmem_pattern=$(dmem_pattern) \
+	$(VERILATOR_OPTS) | tee -a $(sim_results)  ;\
+	printf "Simulation performed on $$(verilator -version) \n" ;\
+	printf "                          Test               | build | simulation \n" ; \
+	printf "$$(cat $(test_results)) \n"
+clean:
+	$(MAKE) -C $(tst_dir)/benchmarks/dhrystone21 clean
+	$(MAKE) -C $(tst_dir)/riscv_isa clean
+	$(MAKE) -C $(tst_dir)/riscv_compliance clean
+	$(RM) -R $(root_dir)/build/*
+	$(RM) $(test_info)
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/README.md b/verilog/rtl/syntacore_scr1/README.md
new file mode 100644
index 0000000..0fb6648
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/README.md
@@ -0,0 +1,197 @@
+# SCR1 RISC-V Core
+
+SCR1 is an open-source and free to use RISC-V compatible MCU-class core, designed and maintained by Syntacore. It is industry-grade and silicon-proven (including full-wafer production), works out of the box in all major EDA flows and Verilator, and comes with extensive collateral and documentation.
+
+![SCR1 cluster](./docs/img/scr1_cluster.svg)
+
+## Key features
+
+* Open sourced under SHL-license (see LICENSE file) - unrestricted commercial use allowed
+* RV32I or RV32E ISA base + optional RVM and RVC standard extensions
+* Machine privilege mode only
+* 2 to 4 stage pipeline
+* Optional Integrated Programmable Interrupt Controller with 16 IRQ lines
+* Optional RISC-V Debug subsystem with JTAG interface
+* Optional on-chip Tightly-Coupled Memory
+* 32-bit AXI4/AHB-Lite external interface
+* Written in SystemVerilog
+* Optimized for area and power
+* 3 predefined recommended configurations
+* A number of fine-tuning options for custom configuration
+* Verification suite provided
+* Extensive documentation
+
+For more information on core architecture, see [SCR1 External Architecture Specification](https://github.com/syntacore/scr1/blob/master/docs/scr1_eas.pdf).
+
+For more information on project usage, see [SCR1 User Manual](https://github.com/syntacore/scr1/blob/master/docs/scr1_um.pdf).
+
+## Repository contents
+
+|Folder | Description
+|------ | -----------
+|**dependencies**                  | **Dependent submodules**
+|├─ riscv-tests                    | Common source files for RISC-V ISA tests
+|├─ riscv-compliance               | Common source files for RISC-V Compliance tests
+|└─ coremark                       | Common source files for EEMBC's CoreMark® benchmark
+|**docs**                          | **SCR1 documentation**
+|├─ scr1_eas.pdf                   | SCR1 External Architecture Specification
+|└─ scr1_um.pdf                    | SCR1 User Manual
+|**sim**                           | **Tests and scripts for simulation**
+|├─ tests/common                   | Common source files for tests
+|├─ tests/riscv_isa                | RISC-V ISA tests platform specific source files
+|├─ tests/riscv_compliance         | RISC-V Compliance platform specific source files
+|├─ tests/benchmarks/dhrystone21   | Dhrystone 2.1 benchmark source files
+|├─ tests/benchmarks/coremark      | EEMBC's CoreMark® benchmark platform specific source files
+|├─ tests/isr_sample               | Sample program "Interrupt Service Routine"
+|├─ tests/hello                    | Sample program "Hello"
+|└─ verilator_wrap                 | Wrappers for Verilator simulation
+|**src**                           | **SCR1 RTL source and testbench files**
+|├─ includes                       | Header files
+|├─ core                           | Core top source files
+|├─ top                            | Cluster source files
+|└─ tb                             | Testbench files
+
+## SCR1 source file lists
+
+SCR1 source file lists of SCR1 can be found in [./src](https://github.com/syntacore/scr1/tree/master/src):
+
+* **core.files**    - all synthesized file sources of the SCR1 core
+* **ahb_top.files** - synthesized file sources of AHB cluster
+* **axi_top.files** - synthesized file sources of AXI cluster
+* **ahb_tb.files**  - testbench file sources for AHB cluster (for simulation only)
+* **axi_tb.files**  - testbench file sources for AXI cluster (for simulation only)
+
+Library with header files to include is [./src/includes/](https://github.com/syntacore/scr1/tree/master/src/includes)
+
+## Simulation quick start guide
+
+The project contains testbenches, test sources and scripts to quickly start the SCR1 simulation. Before starting the simulation, make sure you have:
+
+* installed RISC-V GCC toolchain,
+* installed one of the supported simulators,
+* initialized submodules with test sources.
+
+### Requirements
+
+#### Operating system
+
+GCC toolchain and make-scripts are supported by most popular Linux-like operating systems.
+
+To run from Windows you can use an additional compatibility layer, such as WSL or Cygwin.
+
+#### RISC-V GCC toolchain
+
+RISC-V GCC toolchain is required to compile the software. You can use pre-built binaries or build the toolchain from scratch.
+
+##### Using pre-built binary tools
+
+Pre-built RISC-V GCC toolchain with support for all SCR1 architectural configurations is available for download from http://syntacore.com/page/products/sw-tools.
+
+1. Download the archive for your platform.
+2. Extract the archive to preferred directory `<GCC_INSTALL_PATH>`.
+3. Add the `<GCC_INSTALL_PATH>/bin` folder to the $PATH environment variable:
+```
+    export PATH=<GCC_INSTALL_PATH>/bin:$PATH
+```
+
+##### Building tools from source
+
+You can build the RISC-V GCC toolchain from sources, stored in official repo https://github.com/riscv/riscv-gnu-toolchain
+
+Instructions on how to prepare and build the toolchain can be found on https://github.com/riscv/riscv-gnu-toolchain/blob/master/README.md
+
+We recommend using the multilib compiler. Please note that RV32IC, RV32E, RV32EM, RV32EMC, RV32EC architectural configurations are not included in the compiler by default. If you plan to use them, you will need to include the appropriate libraries by yourself before building.
+
+After the building, be sure to add the `<GCC_INSTALL_PATH>/bin` folder to the $PATH environment variable
+
+
+#### HDL simulators
+
+Currently supported simulators:
+
+* Verilator (last verified version: v4.102)
+* Intel ModelSim (last verified version: INTEL FPGA STARTER EDITION vsim 2020.1_3)
+* Mentor Graphics ModelSim (last verified version: Modelsim PE Student Edition 10.4a)
+* Synopsys VCS (last verified version: vcs-mx_vL-2016.06)
+* Cadence NCSim
+
+Please note that RTL simulator executables should be in your $PATH variable.
+
+#### Tests preparation
+
+The simulation package includes the following tests:
+
+* **hello** - "Hello" sample program
+* **isr_sample** - "Interrupt Service Routine" sample program
+* **riscv_isa** - RISC-V ISA tests (submodule)
+* **riscv_compliance** - RISC-V Compliance tests (submodule)
+* **dhrystone21** - Dhrystone 2.1 benchmark
+* **coremark** - EEMBC's CoreMark® benchmark (submodule)
+
+After the main SCR1 repository has been cloned execute the following command:
+```
+    git submodule update --init --recursive
+```
+
+This command will initialized submodules with test sources.
+
+### Running simulation
+
+To build RTL, compile and run tests from the repo root folder you have to call Makefile.
+By default, you may simply call Makefile without any parameters:
+``` sh
+    make
+```
+
+In this case simulation will run on Verilator with following parameters: `CFG=MAX BUS=AHB TRACE=0 TARGETS="hello isr_sample riscv_isa riscv_compliance dhrystone21 coremark"`.
+
+Makefile supports:
+
+* choice of simulator - `run_<SIMULATOR> = <run_vcs, run_modelsim, run_ncsim, run_verilator, run_verilator_wf>`
+* selection of external interface - `BUS = <AHB, AXI>`,
+* configuration setup - `CFG = <MAX, BASE, MIN, CUSTOM>`,
+* parameters for CUSTOM configuration - `ARCH = <IMC, IC, IM, I, EMC, EM, EC, E>, VECT_IRQ = <0, 1>, IPIC = <0, 1>, TCM = <0, 1>`
+* tests subset to run - `TARGETS = <hello, isr_sample, riscv_isa, riscv_compliance, dhrystone21, coremark>`
+* enabling tracelog - `TRACE = <0, 1>`
+* and any additional options to pass to the simulator - `SIM_BUILD_OPTS`.
+
+Examples:
+``` sh
+    make run_verilator_wf CFG=MAX BUS=AXI TARGETS="riscv_isa riscv_compliance" TRACE=1
+    make run_vcs CFG=BASE BUS=AHB TARGETS="dhrystone21 coremark" SIM_BUILD_OPTS="-gui"
+    make run_modelsim CFG=CUSTOM BUS=AXI ARCH=I VECT_IRQ=1 IPIC=1 TCM=0 TARGETS=isr_sample
+```
+
+Build and run parameters can be configured in the `./Makefile`.
+
+After all the tests have finished, the results can be found in `build/<SIM_CFG>/test_results.txt`.
+
+**IMPORTANT:** To ensure correct rebuild, please clean build directory between simulation runs:
+``` sh
+    make clean
+```
+
+Please refer to the *"Simulation environment"* chapter of the [SCR1 User Manual](https://github.com/syntacore/scr1/blob/master/docs/scr1_um.pdf) for more information on setting up a simulation run.
+
+## SCR1 SDKs
+
+FPGA-based SDKs are available at the <https://github.com/syntacore/scr1-sdk>.
+
+Repo contains:
+
+* Pre-build images and open designs for several standard FPGAs boards:
+  * Digilent Arty (Xilinx)
+  * Digilent Nexys 4 DDR (Xilinx)
+  * Arria V GX Starter (Intel)
+  * Terasic DE10-Lite (Intel)
+* Software package:
+  * Bootloader
+  * Zephyr RTOS
+  * Tests\SW samples
+* User Guides for SDKs and tools
+
+## Contacts
+
+Report an issue: <https://github.com/syntacore/scr1/issues>
+
+Ask a question: scr1@syntacore.com
diff --git a/verilog/rtl/syntacore_scr1/docs/img/scr1_cluster.svg b/verilog/rtl/syntacore_scr1/docs/img/scr1_cluster.svg
new file mode 100644
index 0000000..15af238
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/docs/img/scr1_cluster.svg
@@ -0,0 +1,619 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>

+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">

+<!-- Создано Microsoft Visio, экспорт SVG scr1_cluster.svg scr1_cluster -->

+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:ev="http://www.w3.org/2001/xml-events"

+		xmlns:v="http://schemas.microsoft.com/visio/2003/SVGExtensions/" width="5.73958in" height="5.11458in"

+		viewBox="0 0 413.25 368.25" xml:space="preserve" color-interpolation-filters="sRGB" class="st12">

+	<v:documentProperties v:langID="2057" v:viewMarkup="false"/>

+

+	<style type="text/css">

+	<![CDATA[

+		.st1 {fill:#dcedfa;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}

+		.st2 {fill:#b1ddf0;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}

+		.st3 {fill:#b0e3e6;stroke:#243740;stroke-linecap:butt;stroke-width:0.75}

+		.st4 {fill:none}

+		.st5 {stroke:#243740;stroke-linecap:butt;stroke-width:1.5}

+		.st6 {fill:#243740;stroke:#243740;stroke-linecap:butt;stroke-width:1.5}

+		.st7 {fill:none;stroke:none;stroke-linecap:butt;stroke-width:0.75}

+		.st8 {fill:#243740;font-family:Calibri;font-size:0.75em;font-weight:bold}

+		.st9 {fill:#243740;font-family:Calibri;font-size:0.833336em;font-weight:bold}

+		.st10 {fill:#0c0c0c;font-family:Calibri;font-size:0.833336em;font-weight:bold}

+		.st11 {font-size:1em}

+		.st12 {fill:none;fill-rule:evenodd;font-size:12px;overflow:visible;stroke-linecap:square;stroke-miterlimit:3}

+	]]>

+	</style>

+

+	<g v:mID="0" v:index="1" v:groupContext="foregroundPage">

+		<title>scr1_cluster</title>

+		<v:pageProperties v:drawingScale="1" v:pageScale="1" v:drawingUnits="19" v:shadowOffsetX="9" v:shadowOffsetY="-9"/>

+		<g id="shape2-1" v:mID="2" v:groupContext="shape" transform="translate(60.375,-30.375)">

+			<title>Лист.2</title>

+			<path d="M0 356.55 A11.7003 11.7003 -180 0 0 11.7 368.25 L280.8 368.25 A11.7003 11.7003 -180 0 0 292.5 356.55 L292.5

+						 42.45 A11.7003 11.7003 -180 0 0 280.8 30.75 L11.7 30.75 A11.7003 11.7003 -180 0 0 0 42.45 L0 356.55 Z"

+					class="st1"/>

+		</g>

+		<g id="shape3-3" v:mID="3" v:groupContext="shape" transform="translate(67.875,-210.375)">

+			<title>Лист.3</title>

+			<path d="M0 362.85 A5.40013 5.40013 -180 0 0 5.4 368.25 L272.1 368.25 A5.40013 5.40013 -180 0 0 277.5 362.85 L277.5 238.65

+						 A5.40013 5.40013 -180 0 0 272.1 233.25 L5.4 233.25 A5.40013 5.40013 -180 0 0 0 238.65 L0 362.85 Z"

+					class="st2"/>

+		</g>

+		<g id="shape4-5" v:mID="4" v:groupContext="shape" transform="translate(75.375,-217.875)">

+			<title>Лист.4</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape5-7" v:mID="5" v:groupContext="shape" transform="translate(142.875,-217.875)">

+			<title>Лист.5</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape6-9" v:mID="6" v:groupContext="shape" transform="translate(210.375,-217.875)">

+			<title>Лист.6</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape7-11" v:mID="7" v:groupContext="shape" transform="translate(277.875,-217.875)">

+			<title>Лист.7</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape8-13" v:mID="8" v:groupContext="shape" transform="translate(142.875,-255.375)">

+			<title>Лист.8</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape9-15" v:mID="9" v:groupContext="shape" transform="translate(75.375,-255.375)">

+			<title>Лист.9</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape10-17" v:mID="10" v:groupContext="shape" transform="translate(210.375,-255.375)">

+			<title>Лист.10</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape11-19" v:mID="11" v:groupContext="shape" transform="translate(52.305,-307.635)">

+			<title>Лист.11</title>

+			<path d="M16.14 368.01 L8.07 368.01 L8.07 368.23 L0 368.25 L16.14 368.01 Z" class="st4"/>

+			<path d="M16.14 368.01 L8.07 368.01 L8.07 368.23 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape12-22" v:mID="12" v:groupContext="shape" transform="translate(68.445,-305.25)">

+			<title>Лист.12</title>

+			<path d="M5.25 365.62 L0 368.25 L0 363 L5.25 365.62 Z" class="st6"/>

+		</g>

+		<g id="shape13-24" v:mID="13" v:groupContext="shape" transform="translate(47.055,-305.01)">

+			<title>Лист.13</title>

+			<path d="M0 365.63 L5.24 363 L5.25 368.25 L0 365.63 Z" class="st6"/>

+		</g>

+		<g id="shape14-26" v:mID="14" v:groupContext="shape" transform="translate(75.375,-292.875)">

+			<title>Лист.14</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape15-28" v:mID="15" v:groupContext="shape" transform="translate(277.875,-255.375)">

+			<title>Лист.15</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape16-30" v:mID="16" v:groupContext="shape" transform="translate(142.875,-292.875)">

+			<title>Лист.16</title>

+			<path d="M0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape17-32" v:mID="17" v:groupContext="shape" transform="translate(344.805,-307.635)">

+			<title>Лист.17</title>

+			<path d="M0 368.01 L8.07 368.01 L8.07 368.23 L16.14 368.25 L0 368.01 Z" class="st4"/>

+			<path d="M0 368.01 L8.07 368.01 L8.07 368.23 L16.14 368.25" class="st5"/>

+		</g>

+		<g id="shape18-35" v:mID="18" v:groupContext="shape" transform="translate(339.555,-305.25)">

+			<title>Лист.18</title>

+			<path d="M0 365.62 L5.25 363 L5.25 368.25 L0 365.62 Z" class="st6"/>

+		</g>

+		<g id="shape19-37" v:mID="19" v:groupContext="shape" transform="translate(360.945,-305.01)">

+			<title>Лист.19</title>

+			<path d="M5.25 365.63 L0 368.25 L0.01 363 L5.25 365.63 Z" class="st6"/>

+		</g>

+		<g id="shape20-39" v:mID="20" v:groupContext="shape" transform="translate(277.875,-292.875)">

+			<title>Лист.20</title>

+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape21-41" v:mID="21" v:groupContext="shape" transform="translate(210.375,-292.875)">

+			<title>Лист.21</title>

+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L55.5 368.25 A4.5001 4.5001 -180 0 0 60 363.75 L60 342.75 A4.5001

+						 4.5001 -180 0 0 55.5 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st3"/>

+		</g>

+		<g id="shape22-43" v:mID="22" v:groupContext="shape" transform="translate(150.375,-123.375)">

+			<title>Лист.22</title>

+			<path d="M0 360.37 A7.87518 7.87518 -180 0 0 7.87 368.25 L104.62 368.25 A7.87518 7.87518 -180 0 0 112.5 360.37 L112.5

+						 323.63 A7.87518 7.87518 -180 0 0 104.62 315.75 L7.87 315.75 A7.87518 7.87518 -180 0 0 0 323.63 L0 360.37

+						 Z" class="st2"/>

+		</g>

+		<g id="shape23-45" v:mID="23" v:groupContext="shape" transform="translate(195.375,-85.875)">

+			<title>Лист.23</title>

+			<path d="M-0 363.75 A4.5001 4.5001 -180 0 0 4.5 368.25 L63 368.25 A4.5001 4.5001 -180 0 0 67.5 363.75 L67.5 342.75 A4.5001

+						 4.5001 -180 0 0 63 338.25 L4.5 338.25 A4.5001 4.5001 -180 0 0 -0 342.75 L0 363.75 Z" class="st2"/>

+		</g>

+		<g id="shape24-47" v:mID="24" v:groupContext="shape" transform="translate(120.375,-149.625)">

+			<title>Лист.24</title>

+			<path d="M0 359.43 L0 368.25 L23.07 368.25 L0 359.43 Z" class="st4"/>

+			<path d="M0 359.43 L0 368.25 L23.07 368.25" class="st5"/>

+		</g>

+		<g id="shape25-50" v:mID="25" v:groupContext="shape" transform="translate(117.75,-158.445)">

+			<title>Лист.25</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape26-52" v:mID="26" v:groupContext="shape" transform="translate(143.445,-147)">

+			<title>Лист.26</title>

+			<path d="M5.25 365.63 L0 368.25 L0 363 L5.25 365.63 Z" class="st6"/>

+		</g>

+		<g id="shape27-54" v:mID="27" v:groupContext="shape" transform="translate(105.375,-202.305)">

+			<title>Лист.27</title>

+			<path d="M0 368.25 L0 359.61 L0 368.25 Z" class="st4"/>

+			<path d="M0 368.25 L0 359.61" class="st5"/>

+		</g>

+		<g id="shape28-57" v:mID="28" v:groupContext="shape" transform="translate(102.75,-197.055)">

+			<title>Лист.28</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape29-59" v:mID="29" v:groupContext="shape" transform="translate(102.75,-210.945)">

+			<title>Лист.29</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape30-61" v:mID="30" v:groupContext="shape" transform="translate(75.375,-165.375)">

+			<title>Лист.30</title>

+			<path d="M0 368.25 L12 338.25 L48 338.25 L60 368.25 L0 368.25 Z" class="st2"/>

+		</g>

+		<g id="shape31-63" v:mID="31" v:groupContext="shape" transform="translate(269.805,-149.625)">

+			<title>Лист.31</title>

+			<path d="M23.07 359.43 L23.07 368.25 L0 368.25 L23.07 359.43 Z" class="st4"/>

+			<path d="M23.07 359.43 L23.07 368.25 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape32-66" v:mID="32" v:groupContext="shape" transform="translate(290.25,-158.445)">

+			<title>Лист.32</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape33-68" v:mID="33" v:groupContext="shape" transform="translate(264.555,-147)">

+			<title>Лист.33</title>

+			<path d="M0 365.63 L5.25 363 L5.25 368.25 L0 365.63 Z" class="st6"/>

+		</g>

+		<g id="shape34-70" v:mID="34" v:groupContext="shape" transform="translate(277.875,-165.375)">

+			<title>Лист.34</title>

+			<path d="M0 368.25 L12 338.25 L48 338.25 L60 368.25 L0 368.25 Z" class="st2"/>

+		</g>

+		<g id="shape35-72" v:mID="35" v:groupContext="shape" transform="translate(307.875,-202.305)">

+			<title>Лист.35</title>

+			<path d="M0 359.61 L0 368.25 L0 359.61 Z" class="st4"/>

+			<path d="M0 359.61 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape36-75" v:mID="36" v:groupContext="shape" transform="translate(305.25,-210.945)">

+			<title>Лист.36</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape37-77" v:mID="37" v:groupContext="shape" transform="translate(305.25,-197.055)">

+			<title>Лист.37</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape38-79" v:mID="38" v:groupContext="shape" transform="translate(269.805,-100.875)">

+			<title>Лист.38</title>

+			<path d="M0 368.25 L38.07 368.25 L38.07 310.68 L0 368.25 Z" class="st4"/>

+			<path d="M0 368.25 L38.07 368.25 L38.07 310.68" class="st5"/>

+		</g>

+		<g id="shape39-82" v:mID="39" v:groupContext="shape" transform="translate(264.555,-98.25)">

+			<title>Лист.39</title>

+			<path d="M0 365.62 L5.25 363 L5.25 368.25 L0 365.62 Z" class="st6"/>

+		</g>

+		<g id="shape40-84" v:mID="40" v:groupContext="shape" transform="translate(305.25,-158.445)">

+			<title>Лист.40</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape41-86" v:mID="41" v:groupContext="shape" transform="translate(90.375,-89.805)">

+			<title>Лист.41</title>

+			<path d="M0 368.25 L0 299.61 L0 368.25 Z" class="st4"/>

+			<path d="M0 368.25 L0 299.61" class="st5"/>

+		</g>

+		<g id="shape42-89" v:mID="42" v:groupContext="shape" transform="translate(87.75,-84.555)">

+			<title>Лист.42</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape43-91" v:mID="43" v:groupContext="shape" transform="translate(87.75,-158.445)">

+			<title>Лист.43</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape44-93" v:mID="44" v:groupContext="shape" transform="translate(75.375,-45.375)">

+			<title>Лист.44</title>

+			<path d="M0 362.62 A5.62513 5.62513 -180 0 0 5.63 368.25 L54.38 368.25 A5.62513 5.62513 -180 0 0 60 362.62 L60 336.38

+						 A5.62513 5.62513 -180 0 0 54.38 330.75 L5.62 330.75 A5.62513 5.62513 -180 0 0 0 336.38 L0 362.62 Z"

+					class="st2"/>

+		</g>

+		<g id="shape45-95" v:mID="45" v:groupContext="shape" transform="translate(277.875,-45.375)">

+			<title>Лист.45</title>

+			<path d="M0 362.62 A5.62513 5.62513 -180 0 0 5.63 368.25 L54.38 368.25 A5.62513 5.62513 -180 0 0 60 362.62 L60 336.38

+						 A5.62513 5.62513 -180 0 0 54.38 330.75 L5.62 330.75 A5.62513 5.62513 -180 0 0 0 336.38 L0 362.62 Z"

+					class="st2"/>

+		</g>

+		<g id="shape46-97" v:mID="46" v:groupContext="shape" transform="translate(322.875,-89.805)">

+			<title>Лист.46</title>

+			<path d="M0 299.61 L0 368.25 L0 299.61 Z" class="st4"/>

+			<path d="M0 299.61 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape47-100" v:mID="47" v:groupContext="shape" transform="translate(320.25,-158.445)">

+			<title>Лист.47</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape48-102" v:mID="48" v:groupContext="shape" transform="translate(320.25,-84.555)">

+			<title>Лист.48</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape49-104" v:mID="49" v:groupContext="shape" transform="translate(367.875,-300.375)">

+			<title>Лист.49</title>

+			<rect x="0" y="353.25" width="45" height="15" class="st7"/>

+		</g>

+		<g id="shape50-106" v:mID="50" v:groupContext="shape" transform="translate(354.35,-302.925)">

+			<title>Лист.50</title>

+			<desc>JTAG I/F</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="36.025" cy="362.85" width="72.06" height="10.8"/>

+			<rect x="0" y="357.45" width="72.05" height="10.8" class="st7"/>

+			<text x="20.5" y="365.55" class="st8" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>JTAG I/F</text>		</g>

+		<g id="shape51-109" v:mID="51" v:groupContext="shape" transform="translate(0.375,-300.375)">

+			<title>Лист.51</title>

+			<rect x="0" y="353.25" width="45" height="15" class="st7"/>

+		</g>

+		<g id="shape52-111" v:mID="52" v:groupContext="shape" transform="translate(-8.65,-302.925)">

+			<title>Лист.52</title>

+			<desc>IRQ I/F</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>

+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>

+			<text x="18.49" y="365.55" class="st8" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IRQ I/F</text>		</g>

+		<g id="shape53-114" v:mID="53" v:groupContext="shape" transform="translate(67.875,-0.375)">

+			<title>Лист.53</title>

+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>

+		</g>

+		<g id="shape54-116" v:mID="54" v:groupContext="shape" transform="translate(55.85,-2.925)">

+			<title>Лист.54</title>

+			<desc>AHB/AXI I/F</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="49.525" cy="362.85" width="99.05" height="10.8"/>

+			<rect x="0" y="357.45" width="99.05" height="10.8" class="st7"/>

+			<text x="24.37" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI I/F</text>		</g>

+		<g id="shape55-119" v:mID="55" v:groupContext="shape" transform="translate(105.375,-22.305)">

+			<title>Лист.55</title>

+			<path d="M0 352.11 L0 368.25 L0 352.11 Z" class="st4"/>

+			<path d="M0 352.11 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape56-122" v:mID="56" v:groupContext="shape" transform="translate(102.75,-38.445)">

+			<title>Лист.56</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape57-124" v:mID="57" v:groupContext="shape" transform="translate(102.75,-17.055)">

+			<title>Лист.57</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape58-126" v:mID="58" v:groupContext="shape" transform="translate(270.375,-0.375)">

+			<title>Лист.58</title>

+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>

+		</g>

+		<g id="shape59-128" v:mID="59" v:groupContext="shape" transform="translate(258.35,-2.925)">

+			<title>Лист.59</title>

+			<desc>AHB/AXI I/F</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="49.525" cy="362.85" width="99.06" height="10.8"/>

+			<rect x="0" y="357.45" width="99.05" height="10.8" class="st7"/>

+			<text x="24.37" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI I/F</text>		</g>

+		<g id="shape60-131" v:mID="60" v:groupContext="shape" transform="translate(307.875,-22.305)">

+			<title>Лист.60</title>

+			<path d="M0 352.11 L0 368.25 L0 352.11 Z" class="st4"/>

+			<path d="M0 352.11 L0 368.25" class="st5"/>

+		</g>

+		<g id="shape61-134" v:mID="61" v:groupContext="shape" transform="translate(305.25,-38.445)">

+			<title>Лист.61</title>

+			<path d="M2.63 363 L5.25 368.25 L0 368.25 L2.63 363 Z" class="st6"/>

+		</g>

+		<g id="shape62-136" v:mID="62" v:groupContext="shape" transform="translate(305.25,-17.055)">

+			<title>Лист.62</title>

+			<path d="M2.63 368.25 L0 363 L5.25 363 L2.63 368.25 Z" class="st6"/>

+		</g>

+		<g id="shape63-138" v:mID="63" v:groupContext="shape" transform="translate(67.875,-349.125)">

+			<title>Лист.63</title>

+			<rect x="0" y="353.25" width="82.5" height="15" class="st7"/>

+		</g>

+		<g id="shape64-140" v:mID="64" v:groupContext="shape" transform="translate(82.675,-351.45)">

+			<title>Лист.64</title>

+			<desc>SCR1 cluster</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="43.325" cy="362.85" width="86.65" height="10.8"/>

+			<rect x="0" y="357.45" width="86.65" height="10.8" class="st7"/>

+			<text x="0" y="365.85" class="st10" v:langID="2057"><v:paragraph/><v:tabList/>SCR1 cluster</text>		</g>

+		<g id="shape65-143" v:mID="65" v:groupContext="shape" transform="translate(75.375,-326.625)">

+			<title>Лист.65</title>

+			<rect x="0" y="353.25" width="75" height="15" class="st7"/>

+		</g>

+		<g id="shape66-145" v:mID="66" v:groupContext="shape" transform="translate(76.85,-329.175)">

+			<title>Лист.66</title>

+			<desc>SCR1 core</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="0" y="365.85" class="st10" v:langID="2057"><v:paragraph/><v:tabList/>SCR1 core</text>		</g>

+		<g id="shape67-148" v:mID="67" v:groupContext="shape" transform="translate(90.375,-300.375)">

+			<title>Лист.67</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape68-150" v:mID="68" v:groupContext="shape" transform="translate(64.125,-301.95)">

+			<title>Лист.68</title>

+			<desc>Interrupt Controller</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="23.5" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Interrupt <v:lf/><tspan

+						x="21.65" dy="1.2em" class="st11">Controller</tspan></text>		</g>

+		<g id="shape69-154" v:mID="69" v:groupContext="shape" transform="translate(157.875,-300.375)">

+			<title>Лист.69</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape70-156" v:mID="70" v:groupContext="shape" transform="translate(132.35,-302.925)">

+			<title>Лист.70</title>

+			<desc>System Control Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="26.99" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>System <v:lf/><tspan

+						x="17.59" dy="1.2em" class="st11">Control Unit</tspan></text>		</g>

+		<g id="shape71-160" v:mID="71" v:groupContext="shape" transform="translate(225.375,-300.375)">

+			<title>Лист.71</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape72-162" v:mID="72" v:groupContext="shape" transform="translate(204.35,-302.925)">

+			<title>Лист.72</title>

+			<desc>Debug Module</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="36.025" cy="362.85" width="72.06" height="10.8"/>

+			<rect x="0" y="357.45" width="72.05" height="10.8" class="st7"/>

+			<text x="23.96" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Debug <v:lf/><tspan

+						x="21.47" dy="1.2em" class="st11">Module</tspan></text>		</g>

+		<g id="shape73-166" v:mID="73" v:groupContext="shape" transform="translate(292.875,-300.375)">

+			<title>Лист.73</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape74-168" v:mID="74" v:groupContext="shape" transform="translate(267.35,-302.925)">

+			<title>Лист.74</title>

+			<desc>TAP Controller</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="33.18" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>TAP<v:lf/><tspan

+						x="21.65" dy="1.2em" class="st11">Controller</tspan></text>		</g>

+		<g id="shape75-172" v:mID="75" v:groupContext="shape" transform="translate(90.375,-262.875)">

+			<title>Лист.75</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape76-174" v:mID="76" v:groupContext="shape" transform="translate(64.85,-265.425)">

+			<title>Лист.76</title>

+			<desc>Control-Status Register File</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="13.57" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Control-Status <v:lf/><tspan

+						x="17.71" dy="1.2em" class="st11">Register File</tspan></text>		</g>

+		<g id="shape77-178" v:mID="77" v:groupContext="shape" transform="translate(191.625,-142.125)">

+			<title>Лист.77</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape78-180" v:mID="78" v:groupContext="shape" transform="translate(162,-144)">

+			<title>Лист.78</title>

+			<desc>Tightly-Coupled Memory</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="45" cy="362.85" width="90" height="10.8"/>

+			<rect x="0" y="357.45" width="90" height="10.8" class="st7"/>

+			<text x="12.25" y="359.85" class="st9" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Tightly-Coupled <tspan

+						x="27.21" dy="1.2em" class="st11">Memory</tspan></text>		</g>

+		<g id="shape79-184" v:mID="79" v:groupContext="shape" transform="translate(214.125,-93.375)">

+			<title>Лист.79</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape80-186" v:mID="80" v:groupContext="shape" transform="translate(206.6,-95.925)">

+			<title>Лист.80</title>

+			<desc>Timer</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="22.525" cy="362.85" width="45.05" height="10.8"/>

+			<rect x="0" y="357.45" width="45.05" height="10.8" class="st7"/>

+			<text x="10.46" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>Timer</text>		</g>

+		<g id="shape81-189" v:mID="81" v:groupContext="shape" transform="translate(157.875,-225.375)">

+			<title>Лист.81</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape82-191" v:mID="82" v:groupContext="shape" transform="translate(132.35,-227.925)">

+			<title>Лист.82</title>

+			<desc>Instruction Decode Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="20.16" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Instruction <v:lf/><tspan

+						x="17.41" dy="1.2em" class="st11">Decode Unit</tspan></text>		</g>

+		<g id="shape83-195" v:mID="83" v:groupContext="shape" transform="translate(225.375,-225.375)">

+			<title>Лист.83</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape84-197" v:mID="84" v:groupContext="shape" transform="translate(199.85,-227.925)">

+			<title>Лист.84</title>

+			<desc>Execution Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="22.2" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Execution <v:lf/><tspan

+						x="32.51" dy="1.2em" class="st11">Unit</tspan></text>		</g>

+		<g id="shape85-201" v:mID="85" v:groupContext="shape" transform="translate(292.875,-225.375)">

+			<title>Лист.85</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape86-203" v:mID="86" v:groupContext="shape" transform="translate(267.35,-227.925)">

+			<title>Лист.86</title>

+			<desc>Load-Store Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="20.22" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Load-Store <v:lf/><tspan

+						x="32.51" dy="1.2em" class="st11">Unit</tspan></text>		</g>

+		<g id="shape87-207" v:mID="87" v:groupContext="shape" transform="translate(225.375,-262.875)">

+			<title>Лист.87</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape88-209" v:mID="88" v:groupContext="shape" transform="translate(199.85,-265.425)">

+			<title>Лист.88</title>

+			<desc>Trigger Debug Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="27.46" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Trigger <v:lf/><tspan

+						x="19.42" dy="1.2em" class="st11">Debug Unit</tspan></text>		</g>

+		<g id="shape89-213" v:mID="89" v:groupContext="shape" transform="translate(90.375,-67.875)">

+			<title>Лист.89</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape90-215" v:mID="90" v:groupContext="shape" transform="translate(87.35,-66.675)">

+			<title>Лист.90</title>

+			<desc>IMEM</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>

+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>

+			<text x="5.51" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IMEM</text>		</g>

+		<g id="shape91-218" v:mID="91" v:groupContext="shape" transform="translate(90.375,-58.875)">

+			<title>Лист.91</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape92-220" v:mID="92" v:groupContext="shape" transform="translate(73.85,-57.675)">

+			<title>Лист.92</title>

+			<desc>AHB/AXI</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>

+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>

+			<text x="13.27" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI</text>		</g>

+		<g id="shape93-223" v:mID="93" v:groupContext="shape" transform="translate(90.375,-49.875)">

+			<title>Лист.93</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape94-225" v:mID="94" v:groupContext="shape" transform="translate(78.35,-48.675)">

+			<title>Лист.94</title>

+			<desc>bridge</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>

+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>

+			<text x="13.77" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>bridge</text>		</g>

+		<g id="shape95-228" v:mID="95" v:groupContext="shape" transform="translate(292.875,-67.875)">

+			<title>Лист.95</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape96-230" v:mID="96" v:groupContext="shape" transform="translate(289.85,-66.675)">

+			<title>Лист.96</title>

+			<desc>DMEM</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>

+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>

+			<text x="3.69" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>DMEM</text>		</g>

+		<g id="shape97-233" v:mID="97" v:groupContext="shape" transform="translate(292.875,-58.875)">

+			<title>Лист.97</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape98-235" v:mID="98" v:groupContext="shape" transform="translate(276.35,-57.675)">

+			<title>Лист.98</title>

+			<desc>AHB/AXI</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="31.525" cy="362.85" width="63.05" height="10.8"/>

+			<rect x="0" y="357.45" width="63.05" height="10.8" class="st7"/>

+			<text x="13.27" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>AHB/AXI</text>		</g>

+		<g id="shape99-238" v:mID="99" v:groupContext="shape" transform="translate(292.875,-49.875)">

+			<title>Лист.99</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape100-240" v:mID="100" v:groupContext="shape" transform="translate(280.85,-48.675)">

+			<title>Лист.100</title>

+			<desc>bridge</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>

+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>

+			<text x="13.77" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>bridge</text>		</g>

+		<g id="shape101-243" v:mID="101" v:groupContext="shape" transform="translate(90.375,-180.375)">

+			<title>Лист.101</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape102-245" v:mID="102" v:groupContext="shape" transform="translate(87.35,-179.175)">

+			<title>Лист.102</title>

+			<desc>IMEM</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>

+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>

+			<text x="5.51" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>IMEM</text>		</g>

+		<g id="shape103-248" v:mID="103" v:groupContext="shape" transform="translate(90.375,-171.375)">

+			<title>Лист.103</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape104-250" v:mID="104" v:groupContext="shape" transform="translate(78.35,-170.175)">

+			<title>Лист.104</title>

+			<desc>router</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>

+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>

+			<text x="13.85" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>router</text>		</g>

+		<g id="shape105-253" v:mID="105" v:groupContext="shape" transform="translate(292.875,-180.375)">

+			<title>Лист.105</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape106-255" v:mID="106" v:groupContext="shape" transform="translate(289.85,-179.175)">

+			<title>Лист.106</title>

+			<desc>DMEM</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="18.025" cy="362.85" width="36.05" height="10.8"/>

+			<rect x="0" y="357.45" width="36.05" height="10.8" class="st7"/>

+			<text x="3.69" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>DMEM</text>		</g>

+		<g id="shape107-258" v:mID="107" v:groupContext="shape" transform="translate(292.875,-171.375)">

+			<title>Лист.107</title>

+			<rect x="0" y="360.75" width="30" height="7.5" class="st7"/>

+		</g>

+		<g id="shape108-260" v:mID="108" v:groupContext="shape" transform="translate(280.85,-170.175)">

+			<title>Лист.108</title>

+			<desc>router</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="27.025" cy="362.85" width="54.05" height="10.8"/>

+			<rect x="0" y="357.45" width="54.05" height="10.8" class="st7"/>

+			<text x="13.85" y="365.85" class="st9" v:langID="2057"><v:paragraph v:horizAlign="1"/><v:tabList/>router</text>		</g>

+		<g id="shape109-263" v:mID="109" v:groupContext="shape" transform="translate(157.875,-262.875)">

+			<title>Лист.109</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape110-265" v:mID="110" v:groupContext="shape" transform="translate(132.35,-265.425)">

+			<title>Лист.110</title>

+			<desc>Multi-Port Register File</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="21.06" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Multi-Port <v:lf/><tspan

+						x="17.71" dy="1.2em" class="st11">Register File</tspan></text>		</g>

+		<g id="shape111-269" v:mID="111" v:groupContext="shape" transform="translate(292.875,-262.875)">

+			<title>Лист.111</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape112-271" v:mID="112" v:groupContext="shape" transform="translate(267.35,-265.425)">

+			<title>Лист.112</title>

+			<desc>Hart Debug Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.06" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="32.31" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Hart <v:lf/><tspan

+						x="19.42" dy="1.2em" class="st11">Debug Unit</tspan></text>		</g>

+		<g id="shape113-275" v:mID="113" v:groupContext="shape" transform="translate(90.375,-225.375)">

+			<title>Лист.113</title>

+			<rect x="0" y="353.25" width="30" height="15" class="st7"/>

+		</g>

+		<g id="shape114-277" v:mID="114" v:groupContext="shape" transform="translate(64.85,-227.925)">

+			<title>Лист.114</title>

+			<desc>Instruction Fetch Unit</desc>

+			<v:textBlock v:margins="rect(0,0,0,0)"/>

+			<v:textRect cx="40.525" cy="362.85" width="81.05" height="10.8"/>

+			<rect x="0" y="357.45" width="81.05" height="10.8" class="st7"/>

+			<text x="20.16" y="360.15" class="st8" v:langID="1033"><v:paragraph v:horizAlign="1"/><v:tabList/>Instruction<v:newlineChar/><tspan

+						x="21.3" dy="1.2em" class="st11">Fetch Unit</tspan></text>		</g>

+	</g>

+</svg>

diff --git a/verilog/rtl/syntacore_scr1/docs/scr1_eas.pdf b/verilog/rtl/syntacore_scr1/docs/scr1_eas.pdf
new file mode 100644
index 0000000..e436e1c
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/docs/scr1_eas.pdf
Binary files differ
diff --git a/verilog/rtl/syntacore_scr1/docs/scr1_um.pdf b/verilog/rtl/syntacore_scr1/docs/scr1_um.pdf
new file mode 100644
index 0000000..07a69d1
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/docs/scr1_um.pdf
Binary files differ
diff --git a/verilog/rtl/syntacore_scr1/src/ahb_top.files b/verilog/rtl/syntacore_scr1/src/ahb_top.files
new file mode 100644
index 0000000..603839e
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/ahb_top.files
@@ -0,0 +1,8 @@
+top/scr1_dmem_router.sv
+top/scr1_imem_router.sv
+top/scr1_dp_memory.sv
+top/scr1_tcm.sv
+top/scr1_timer.sv
+top/scr1_dmem_ahb.sv
+top/scr1_imem_ahb.sv
+top/scr1_top_ahb.sv
diff --git a/verilog/rtl/syntacore_scr1/src/axi_tb.files b/verilog/rtl/syntacore_scr1/src/axi_tb.files
new file mode 100644
index 0000000..383dc9b
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/axi_tb.files
@@ -0,0 +1,3 @@
+core/pipeline/scr1_tracelog.sv
+tb/scr1_memory_tb_axi.sv
+tb/scr1_top_tb_axi.sv
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/axi_top.files b/verilog/rtl/syntacore_scr1/src/axi_top.files
new file mode 100644
index 0000000..24f4b8e
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/axi_top.files
@@ -0,0 +1,7 @@
+top/scr1_dmem_router.sv
+top/scr1_imem_router.sv
+top/scr1_dp_memory.sv
+top/scr1_tcm.sv
+top/scr1_timer.sv
+top/scr1_mem_axi.sv
+top/scr1_top_axi.sv
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/core.files b/verilog/rtl/syntacore_scr1/src/core.files
new file mode 100644
index 0000000..ca5de45
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core.files
@@ -0,0 +1,21 @@
+core/pipeline/scr1_pipe_hdu.sv
+core/pipeline/scr1_pipe_tdu.sv
+core/pipeline/scr1_ipic.sv
+core/pipeline/scr1_pipe_csr.sv
+core/pipeline/scr1_pipe_exu.sv
+core/pipeline/scr1_pipe_ialu.sv
+core/pipeline/scr1_pipe_idu.sv
+core/pipeline/scr1_pipe_ifu.sv
+core/pipeline/scr1_pipe_lsu.sv
+core/pipeline/scr1_pipe_mprf.sv
+core/pipeline/scr1_pipe_top.sv
+core/primitives/scr1_reset_cells.sv
+core/primitives/scr1_cg.sv
+core/scr1_clk_ctrl.sv
+core/scr1_tapc_shift_reg.sv
+core/scr1_tapc.sv
+core/scr1_tapc_synchronizer.sv
+core/scr1_core_top.sv
+core/scr1_dm.sv
+core/scr1_dmi.sv
+core/scr1_scu.sv
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_ipic.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_ipic.sv
new file mode 100644
index 0000000..312dc4c
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_ipic.sv
@@ -0,0 +1,605 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_ipic.sv>
+/// @brief      Integrated Programmable Interrupt Controller (IPIC)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Synchronizes IRQ lines (optional)
+ // - Detects level and edge (with optional lines inversion) of IRQ lines
+ // - Setups interrupts handling (mode, inversion, enable)
+ // - Provides information about pending interrupts and interrupts currently in
+ //   service
+ // - Generates interrupt request to CSR
+ //
+ // Structure:
+ // - IRQ lines handling (synchronization, level and edge detection) logic
+ // - IPIC registers:
+ //   - CISV
+ //   - CICSR
+ //   - EOI
+ //   - SOI
+ //   - IDX
+ //   - IPR
+ //   - ISVR
+ //   - IER
+ //   - IMR
+ //   - IINVR
+ //   - ICSR
+ // - Priority interrupt generation logic
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_IPIC_EN
+
+`include "scr1_ipic.svh"
+
+module scr1_ipic
+(
+    // Common
+    input   logic                                   rst_n,                  // IPIC reset
+    input   logic                                   clk,                    // IPIC clock
+
+    // External Interrupt lines
+    input   logic [SCR1_IRQ_LINES_NUM-1:0]          soc2ipic_irq_lines_i,   // External IRQ lines
+
+    // CSR <-> IPIC interface
+    input   logic                                   csr2ipic_r_req_i,       // IPIC read request
+    input   logic                                   csr2ipic_w_req_i,       // IPIC write request
+    input   logic [2:0]                             csr2ipic_addr_i,        // IPIC address
+    input   logic [`SCR1_XLEN-1:0]                  csr2ipic_wdata_i,       // IPIC write data
+    output  logic [`SCR1_XLEN-1:0]                  ipic2csr_rdata_o,       // IPIC read data
+    output  logic                                   ipic2csr_irq_m_req_o    // IRQ request from IPIC
+);
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef struct {
+    logic                                   vd;
+    logic                                   idx;
+} type_scr1_search_one_2_s;
+
+typedef struct {
+    logic                                   vd;
+    logic   [SCR1_IRQ_VECT_WIDTH-1:0]       idx;
+} type_scr1_search_one_16_s;
+
+typedef struct packed {
+    logic                                   ip;
+    logic                                   ie;
+    logic                                   im;
+    logic                                   inv;
+    logic                                   is;
+    logic   [SCR1_IRQ_LINES_WIDTH-1:0]      line;
+} type_scr1_icsr_m_s;
+
+typedef struct packed {
+    logic                                   ip;
+    logic                                   ie;
+} type_scr1_cicsr_s;
+
+//-------------------------------------------------------------------------------
+// Local functions declaration
+//-------------------------------------------------------------------------------
+
+function automatic type_scr1_search_one_2_s scr1_search_one_2(
+    input   logic   [1:0] din
+);
+    type_scr1_search_one_2_s tmp;
+begin
+    tmp.vd  = |din;
+    tmp.idx = ~din[0];
+    return  tmp;
+end
+endfunction : scr1_search_one_2
+
+function automatic type_scr1_search_one_16_s scr1_search_one_16(
+    input   logic [15:0]    din
+);
+begin
+    logic [7:0]         stage1_vd;
+    logic [3:0]         stage2_vd;
+    logic [1:0]         stage3_vd;
+
+    logic               stage1_idx [7:0];
+    logic [1:0]         stage2_idx [3:0];
+    logic [2:0]         stage3_idx [1:0];
+    type_scr1_search_one_16_s result;
+
+    // Stage 1
+    for (int unsigned i=0; i<8; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_search_one_2(din[(i+1)*2-1-:2]);
+        stage1_vd[i]  = tmp.vd;
+        stage1_idx[i] = tmp.idx;
+    end
+
+    // Stage 2
+    for (int unsigned i=0; i<4; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_search_one_2(stage1_vd[(i+1)*2-1-:2]);
+        stage2_vd[i]  = tmp.vd;
+        stage2_idx[i] = (~tmp.idx) ? {tmp.idx, stage1_idx[2*i]} : {tmp.idx, stage1_idx[2*i+1]};
+    end
+
+    // Stage 3
+    for (int unsigned i=0; i<2; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_search_one_2(stage2_vd[(i+1)*2-1-:2]);
+        stage3_vd[i]  = tmp.vd;
+        stage3_idx[i] = (~tmp.idx) ? {tmp.idx, stage2_idx[2*i]} : {tmp.idx, stage2_idx[2*i+1]};
+    end
+
+    // Stage 4
+    result.vd = |stage3_vd;
+    result.idx = (stage3_vd[0]) ? {1'b0, stage3_idx[0]} : {1'b1, stage3_idx[1]};
+
+    return result;
+end
+endfunction : scr1_search_one_16
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// IRQ lines handling signals
+//------------------------------------------------------------------------------
+
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_lines;              // Internal IRQ lines
+`ifdef SCR1_IPIC_SYNC_EN
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_lines_sync;
+`endif // SCR1_IPIC_SYNC_EN
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_lines_dly;          // Internal IRQ lines delayed for 1 cycle
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_edge_detected;      // IRQ lines edge detected flags
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_lvl;                // IRQ lines level
+
+// IPIC registers
+//------------------------------------------------------------------------------
+
+// CISV register
+logic                                   ipic_cisv_upd;          // Current Interrupt Vecotr in Service register update
+logic [SCR1_IRQ_VECT_WIDTH-1:0]         ipic_cisv_ff;           // Current Interrupt Vector in Service register
+logic [SCR1_IRQ_VECT_WIDTH-1:0]         ipic_cisv_next;         // Current Interrupt Vector in Service register next value
+
+// CICS register (CICSR)
+logic                                   cicsr_wr_req;           // Write request to Current Interrupt Control Status register
+type_scr1_cicsr_s                       ipic_cicsr;             // Current Interrupt Control Status register
+
+// EOI register
+logic                                   eoi_wr_req;             // Write request to End of Interrupt register
+logic                                   ipic_eoi_req;           // Request to end the interrupt that is currently in service
+
+// SOI register
+logic                                   soi_wr_req;             // Write request to Start of Interrupt register
+logic                                   ipic_soi_req;           // Request to start the interrupt
+
+// IDX register (IDXR)
+logic                                   idxr_wr_req;            // Write request to Index register
+logic [SCR1_IRQ_IDX_WIDTH-1:0]          ipic_idxr_ff;           // Index register
+
+// IP register (IPR)
+logic                                   ipic_ipr_upd;           // Interrupt pending register update
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ipr_ff;            // Interrupt pending register
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ipr_next;          // Interrupt pending register next value
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ipr_clr_cond;      // Interrupt pending clear condition
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ipr_clr_req;       // Interrupt pending clear request
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ipr_clr;           // Interrupt pending clear operation
+
+// ISV register (ISVR)
+logic                                   ipic_isvr_upd;          // Interrupt Serviced register update
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_isvr_ff;           // Interrupt Serviced register
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_isvr_next;         // Interrupt Serviced register next value
+
+// IE register (IER)
+logic                                   ipic_ier_upd;           // Interrupt enable register update
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ier_ff;            // Interrupt enable register
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_ier_next;          // Interrupt enable register next value
+
+// IM register (IMR)
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_imr_ff;            // Interrupt mode register
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_imr_next;          // Interrupt mode register next value
+
+// IINV register (IINVR)
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_iinvr_ff;          // Interrupt Inversion register
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_iinvr_next;        // Interrupt Inversion register next value
+
+// ICS register (ICSR)
+logic                                   icsr_wr_req;            // Write request to Interrupt Control Status register
+type_scr1_icsr_m_s                      ipic_icsr;              // Interrupt Control Status register
+
+// Priority interrupt generation signals
+//------------------------------------------------------------------------------
+
+// Serviced interrupt signals
+logic                                   irq_serv_vd;            // There is an interrupt in service
+logic [SCR1_IRQ_VECT_WIDTH-1:0]         irq_serv_idx;           // Index of an interrupt that is currently in service
+
+// Requested interrupt signals
+logic                                   irq_req_vd;             // There is a requested interrupt
+logic [SCR1_IRQ_VECT_WIDTH-1:0]         irq_req_idx;            // Index of a requested interrupt
+
+// Interrupt requested on "end of the previous interrupt" signals
+logic                                   irq_eoi_req_vd;         // There is a requested interrupt when the previous one has ended
+logic [SCR1_IRQ_VECT_WIDTH-1:0]         irq_eoi_req_idx;        // Index of an interrupt requested when the previous one has ended
+
+logic [SCR1_IRQ_VECT_NUM-1:0]           irq_req_v;              // Vector of interrupts that are pending and enabled
+
+logic                                   irq_start_vd;           // Request to start an interrupt is valid
+logic                                   irq_hi_prior_pnd;       // There is a pending IRQ with a priority higher than of the interrupt that is currently in service
+
+type_scr1_search_one_16_s               irr_priority;           // Structure for vd and idx of the requested interrupt
+type_scr1_search_one_16_s               isvr_priority_eoi;      // Structure for vd and idx of the interrupt requested when the previous interrupt has ended
+logic [SCR1_IRQ_VECT_NUM-1:0]           ipic_isvr_eoi;          // Interrupt Serviced register when the previous interrupt has ended
+
+//------------------------------------------------------------------------------
+// IRQ lines handling
+//------------------------------------------------------------------------------
+
+`ifdef SCR1_IPIC_SYNC_EN
+// IRQ lines synchronization
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        irq_lines_sync <= '0;
+        irq_lines      <= '0;
+    end else begin
+        irq_lines_sync <= soc2ipic_irq_lines_i;
+        irq_lines      <= irq_lines_sync;
+    end
+end
+`else // SCR1_IPIC_SYNC_EN
+assign irq_lines = soc2ipic_irq_lines_i;
+`endif // SCR1_IPIC_SYNC_EN
+
+// IRQ lines level detection
+//------------------------------------------------------------------------------
+
+assign irq_lvl = irq_lines ^ ipic_iinvr_next;
+
+// IRQ lines edge detection
+//------------------------------------------------------------------------------
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        irq_lines_dly <= '0;
+    end else begin
+        irq_lines_dly <= irq_lines;
+    end
+end
+
+assign irq_edge_detected = (irq_lines_dly ^ irq_lines) & irq_lvl;
+
+//------------------------------------------------------------------------------
+// IPIC registers read/write interface
+//------------------------------------------------------------------------------
+
+// Read Logic
+//------------------------------------------------------------------------------
+
+// Read data multiplexer
+always_comb begin
+    ipic2csr_rdata_o  = '0;
+
+    if (csr2ipic_r_req_i) begin
+        case (csr2ipic_addr_i)
+            SCR1_IPIC_CISV : begin
+                ipic2csr_rdata_o[SCR1_IRQ_VECT_WIDTH-1:0] = irq_serv_vd
+                                                          ? ipic_cisv_ff
+                                                          : SCR1_IRQ_VOID_VECT_NUM;
+            end
+            SCR1_IPIC_CICSR : begin
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IP]  = ipic_cicsr.ip;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IE]  = ipic_cicsr.ie;
+            end
+            SCR1_IPIC_IPR : begin
+                ipic2csr_rdata_o = `SCR1_XLEN'(ipic_ipr_ff);
+            end
+            SCR1_IPIC_ISVR : begin
+                ipic2csr_rdata_o = `SCR1_XLEN'(ipic_isvr_ff);
+            end
+            SCR1_IPIC_EOI,
+            SCR1_IPIC_SOI : begin
+                ipic2csr_rdata_o = '0;
+            end
+            SCR1_IPIC_IDX : begin
+                ipic2csr_rdata_o = `SCR1_XLEN'(ipic_idxr_ff);
+            end
+            SCR1_IPIC_ICSR : begin
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IP]      = ipic_icsr.ip;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IE]      = ipic_icsr.ie;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IM]      = ipic_icsr.im;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_INV]     = ipic_icsr.inv;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_PRV_MSB:
+                                 SCR1_IPIC_ICSR_PRV_LSB] = SCR1_IPIC_PRV_M;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_IS]      = ipic_icsr.is;
+                ipic2csr_rdata_o[SCR1_IPIC_ICSR_LN_MSB-1:
+                                 SCR1_IPIC_ICSR_LN_LSB]  = ipic_icsr.line;
+            end
+            default : begin
+                ipic2csr_rdata_o = 'x;
+            end
+        endcase
+    end
+end
+
+// Write logic
+//------------------------------------------------------------------------------
+
+// Register selection
+always_comb begin
+    cicsr_wr_req = 1'b0;
+    eoi_wr_req   = 1'b0;
+    soi_wr_req   = 1'b0;
+    idxr_wr_req  = 1'b0;
+    icsr_wr_req  = 1'b0;
+    if (csr2ipic_w_req_i) begin
+        case (csr2ipic_addr_i)
+            SCR1_IPIC_CISV : begin end // Quiet Read-Only
+            SCR1_IPIC_CICSR: cicsr_wr_req = 1'b1;
+            SCR1_IPIC_IPR  : begin end
+            SCR1_IPIC_ISVR : begin end // Quiet Read-Only
+            SCR1_IPIC_EOI  : eoi_wr_req   = 1'b1;
+            SCR1_IPIC_SOI  : soi_wr_req   = 1'b1;
+            SCR1_IPIC_IDX  : idxr_wr_req  = 1'b1;
+            SCR1_IPIC_ICSR : icsr_wr_req  = 1'b1;
+            default : begin // Illegal IPIC register address
+                cicsr_wr_req = 'x;
+                eoi_wr_req   = 'x;
+                soi_wr_req   = 'x;
+                idxr_wr_req  = 'x;
+                icsr_wr_req  = 'x;
+            end
+        endcase
+    end
+end
+
+//------------------------------------------------------------------------------
+// IPIC registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - Current Interrupt Vector in Service (CISV) register
+ // - Current Interrupt Control Status (CICSR) register
+ // - End of Interrupt (EOI) register
+ // - Start of Interrupt (SOI) register
+ // - Index (IDX) register
+ // - Interrupt Pending Register (IPR)
+ // - Interrupt Serviced Register (ISVR)
+ // - Interrupt Enable Register (IER)
+ // - Interrupt Mode Register (IMR)
+ // - Interrupt Inversion Register (IINVR)
+ // - Interrupt Control Status Register (ICSR)
+//
+
+// CISV register
+//------------------------------------------------------------------------------
+// Contains number of the interrupt vector currently in service. When no
+// interrupts are in service, contains number of the void interrupt vector (0x10).
+// The register cannot contain all 0's
+
+assign ipic_cisv_upd = irq_start_vd | ipic_eoi_req;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_cisv_ff <= SCR1_IRQ_VOID_VECT_NUM;
+    end else if (ipic_cisv_upd) begin
+        ipic_cisv_ff <= ipic_cisv_next;
+    end
+end
+
+assign ipic_cisv_next = irq_start_vd ? irq_req_idx
+                      : ipic_eoi_req ? irq_eoi_req_vd ? irq_eoi_req_idx
+                                                      : SCR1_IRQ_VOID_VECT_NUM
+                                     : 1'b0;
+
+assign irq_serv_idx = ipic_cisv_ff[SCR1_IRQ_VECT_WIDTH-2:0];
+assign irq_serv_vd  = ~ipic_cisv_ff[SCR1_IRQ_VECT_WIDTH-1];
+
+// CICSR register
+//------------------------------------------------------------------------------
+// Shows whether the interrupt currently in service is pending and enabled
+
+assign ipic_cicsr.ip = ipic_ipr_ff[irq_serv_idx] & irq_serv_vd;
+assign ipic_cicsr.ie = ipic_ier_ff[irq_serv_idx] & irq_serv_vd;
+
+// EOI register
+//------------------------------------------------------------------------------
+// Writing any value to EOI register ends the interrupt which is currently in service
+
+assign ipic_eoi_req = eoi_wr_req & irq_serv_vd;
+
+// SOI register
+//------------------------------------------------------------------------------
+// Writing any value to SOI activates start of interrupt if one of the following
+// conditions is true:
+// - There is at least one pending interrupt with IE and ISR is zero
+// - There is at least one pending interrupt with IE and higher priority than the
+// interrupts currently in service
+
+assign ipic_soi_req = soi_wr_req & irq_req_vd;
+
+// IDX register
+//------------------------------------------------------------------------------
+// Defines the number of interrupt vector which is accessed through the IPIC_ICSR
+// register
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_idxr_ff <= '0;
+    end else if (idxr_wr_req) begin
+        ipic_idxr_ff <= csr2ipic_wdata_i[SCR1_IRQ_IDX_WIDTH-1:0];
+    end
+end
+
+// IPR
+//------------------------------------------------------------------------------
+// For every IRQ line shows whether there is a pending interrupt
+
+assign ipic_ipr_upd = (ipic_ipr_next != ipic_ipr_ff);
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_ipr_ff <= '0;
+    end else if (ipic_ipr_upd) begin
+        ipic_ipr_ff <= ipic_ipr_next;
+    end
+end
+
+always_comb begin
+    ipic_ipr_clr_req = '0;
+    if (csr2ipic_w_req_i) begin
+        case (csr2ipic_addr_i)
+            SCR1_IPIC_CICSR: ipic_ipr_clr_req[irq_serv_idx] = csr2ipic_wdata_i[SCR1_IPIC_ICSR_IP]
+                                                            & irq_serv_vd;
+            SCR1_IPIC_IPR  : ipic_ipr_clr_req               = csr2ipic_wdata_i[SCR1_IRQ_VECT_NUM-1:0];
+            SCR1_IPIC_SOI  : ipic_ipr_clr_req[irq_req_idx]  = irq_req_vd;
+            SCR1_IPIC_ICSR : ipic_ipr_clr_req[ipic_idxr_ff] = csr2ipic_wdata_i[SCR1_IPIC_ICSR_IP];
+            default        : begin end
+        endcase
+    end
+end
+
+assign ipic_ipr_clr_cond = ~irq_lvl | ipic_imr_next;
+assign ipic_ipr_clr      = ipic_ipr_clr_req & ipic_ipr_clr_cond;
+
+always_comb begin
+    ipic_ipr_next = '0;
+    for (int unsigned i=0; i<SCR1_IRQ_VECT_NUM; ++i) begin
+        ipic_ipr_next[i] = ipic_ipr_clr[i] ? 1'b0
+                         : ~ipic_imr_ff[i] ? irq_lvl[i]
+                                           : ipic_ipr_ff[i] | irq_edge_detected[i];
+    end
+end
+
+// ISVR
+//------------------------------------------------------------------------------
+// For every IRQ line shows whether the interrupt is in service or not
+
+assign ipic_isvr_upd = irq_start_vd | ipic_eoi_req;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_isvr_ff <= '0;
+    end else if (ipic_isvr_upd) begin
+        ipic_isvr_ff <= ipic_isvr_next;
+    end
+end
+
+always_comb begin
+    ipic_isvr_eoi = ipic_isvr_ff;
+    if (irq_serv_vd) begin
+        ipic_isvr_eoi[irq_serv_idx] = 1'b0;
+    end
+end
+
+always_comb begin
+    ipic_isvr_next = ipic_isvr_ff;
+    if (irq_start_vd) begin
+        ipic_isvr_next[irq_req_idx] = 1'b1;
+    end else if (ipic_eoi_req) begin
+        ipic_isvr_next = ipic_isvr_eoi;
+    end
+end
+
+// IER
+//------------------------------------------------------------------------------
+// Enables/disables interrupt for every IRQ line
+
+assign ipic_ier_upd = cicsr_wr_req | icsr_wr_req;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_ier_ff <= '0;
+    end else if (ipic_ier_upd) begin
+        ipic_ier_ff <= ipic_ier_next;
+    end
+end
+
+always_comb begin
+    ipic_ier_next = ipic_ier_ff;
+    if (cicsr_wr_req) begin
+        ipic_ier_next[irq_serv_idx] = irq_serv_vd
+                                    ? csr2ipic_wdata_i[SCR1_IPIC_ICSR_IE]
+                                    : ipic_ier_ff[irq_serv_idx];
+    end else if (icsr_wr_req) begin
+        ipic_ier_next[ipic_idxr_ff] = csr2ipic_wdata_i[SCR1_IPIC_ICSR_IE];
+    end
+end
+
+// IMR
+//------------------------------------------------------------------------------
+// For every IRQ line sets either Level (0) or Edge (1) detection
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_imr_ff <= '0;
+    end else if (icsr_wr_req) begin
+        ipic_imr_ff <= ipic_imr_next;
+    end
+end
+
+always_comb begin
+    ipic_imr_next = ipic_imr_ff;
+    if (icsr_wr_req) begin
+        ipic_imr_next[ipic_idxr_ff] = csr2ipic_wdata_i[SCR1_IPIC_ICSR_IM];
+    end
+end
+
+// IINVR
+//------------------------------------------------------------------------------
+// For every IRQ line defines whether it should be inverted or not
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        ipic_iinvr_ff <= '0;
+    end else if (icsr_wr_req) begin
+        ipic_iinvr_ff <= ipic_iinvr_next;
+    end
+end
+
+always_comb begin
+    ipic_iinvr_next = ipic_iinvr_ff;
+    if (icsr_wr_req) begin
+        ipic_iinvr_next[ipic_idxr_ff] = csr2ipic_wdata_i[SCR1_IPIC_ICSR_INV];
+    end
+end
+
+// ICSR
+//------------------------------------------------------------------------------
+// Holds control and status information about the interrupt defined by Index Register
+
+assign ipic_icsr.ip    = ipic_ipr_ff  [ipic_idxr_ff];
+assign ipic_icsr.ie    = ipic_ier_ff  [ipic_idxr_ff];
+assign ipic_icsr.im    = ipic_imr_ff  [ipic_idxr_ff];
+assign ipic_icsr.inv   = ipic_iinvr_ff[ipic_idxr_ff];
+assign ipic_icsr.is    = ipic_isvr_ff [ipic_idxr_ff];
+assign ipic_icsr.line  = SCR1_IRQ_LINES_WIDTH'(ipic_idxr_ff);
+
+//------------------------------------------------------------------------------
+// Priority IRQ generation logic
+//------------------------------------------------------------------------------
+
+assign irq_req_v = ipic_ipr_ff & ipic_ier_ff;
+
+assign irr_priority        = scr1_search_one_16(irq_req_v);
+assign irq_req_vd          = irr_priority.vd;
+assign irq_req_idx         = irr_priority.idx;
+
+assign isvr_priority_eoi   = scr1_search_one_16(ipic_isvr_eoi);
+assign irq_eoi_req_vd      = isvr_priority_eoi.vd;
+assign irq_eoi_req_idx     = isvr_priority_eoi.idx;
+
+assign irq_hi_prior_pnd     = irq_req_idx < irq_serv_idx;
+
+assign ipic2csr_irq_m_req_o = irq_req_vd & (~irq_serv_vd | irq_hi_prior_pnd);
+
+assign irq_start_vd         = ipic2csr_irq_m_req_o & ipic_soi_req;
+
+endmodule : scr1_ipic
+
+`endif // SCR1_IPIC_EN
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_csr.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_csr.sv
new file mode 100644
index 0000000..183887d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_csr.sv
@@ -0,0 +1,1167 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_csr.sv>
+/// @brief      Control Status Registers (CSR)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Provides access to RISC-V CSR Machine registers
+ // - Handles events (EXC, IRQ and MRET):
+ //   - Setups handling configuration
+ //   - Displays events statuses and information
+ //   - Generates new PC
+ // - Provides information about the number of executed instructions and elapsed
+ //   cycles
+ // - Provides interfaces for IPIC, HDU and TDU registers access
+ //
+ // Structure:
+ // - Events (EXC, IRQ, MRET) logic
+ // - CSR read/write interface
+ // - CSR registers:
+ //   - Machine Trap Setup registers
+ //   - Machine Trap Handling registers
+ //   - Machine Counters/Timers registers
+ //   - Non-standard CSRs (MCOUNTEN)
+ // - CSR <-> EXU i/f
+ // - CSR <-> IPIC i/f
+ // - CSR <-> HDU i/f
+ // - CSR <-> TDU i/f
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+`include "scr1_csr.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`ifdef SCR1_IPIC_EN
+`include "scr1_ipic.svh"
+`endif // SCR1_IPIC_EN
+`ifdef SCR1_DBG_EN
+`include "scr1_hdu.svh"
+`endif // SCR1_DBG_EN
+`ifdef SCR1_TDU_EN
+`include "scr1_tdu.svh"
+`endif // SCR1_TDU_EN
+
+module scr1_pipe_csr (
+    // Common
+    input   logic                                       rst_n,                      // CSR reset
+    input   logic                                       clk,                        // Gated CSR clock
+`ifdef SCR1_CLKCTRL_EN
+    input   logic                                       clk_alw_on,                 // Not-gated CSR clock
+`endif // SCR1_CLKCTRL_EN
+
+    // SOC signals
+    // IRQ
+    input   logic                                       soc2csr_irq_ext_i,          // External interrupt request
+    input   logic                                       soc2csr_irq_soft_i,         // Software interrupt request
+    input   logic                                       soc2csr_irq_mtimer_i,       // External timer interrupt request
+
+    // Memory-mapped external timer
+    input   logic [63:0]                                soc2csr_mtimer_val_i,       // External timer value
+
+    // MHARTID fuse
+    input   logic [`SCR1_XLEN-1:0]                      soc2csr_fuse_mhartid_i,     // MHARTID fuse
+
+    // CSR <-> EXU read/write interface
+    input   logic                                       exu2csr_r_req_i,            // CSR read/write address
+    input   logic [SCR1_CSR_ADDR_WIDTH-1:0]             exu2csr_rw_addr_i,          // CSR read request
+    output  logic [`SCR1_XLEN-1:0]                      csr2exu_r_data_o,           // CSR read data
+    input   logic                                       exu2csr_w_req_i,            // CSR write request
+    input   type_scr1_csr_cmd_sel_e                     exu2csr_w_cmd_i,            // CSR write command
+    input   logic [`SCR1_XLEN-1:0]                      exu2csr_w_data_i,           // CSR write data
+    output  logic                                       csr2exu_rw_exc_o,           // CSR read/write access exception
+
+    // CSR <-> EXU event interface
+    input   logic                                       exu2csr_take_irq_i,         // Take IRQ trap
+    input   logic                                       exu2csr_take_exc_i,         // Take exception trap
+    input   logic                                       exu2csr_mret_update_i,      // MRET update CSR
+    input   logic                                       exu2csr_mret_instr_i,       // MRET instruction
+    input   type_scr1_exc_code_e                        exu2csr_exc_code_i,         // Exception code (see scr1_arch_types.svh)
+    input   logic [`SCR1_XLEN-1:0]                      exu2csr_trap_val_i,         // Trap value
+    output  logic                                       csr2exu_irq_o,              // IRQ request
+    output  logic                                       csr2exu_ip_ie_o,            // Some IRQ pending and locally enabled
+    output  logic                                       csr2exu_mstatus_mie_up_o,   // MSTATUS or MIE update in the current cycle
+
+`ifdef SCR1_IPIC_EN
+    // CSR <-> IPIC interface
+    output  logic                                       csr2ipic_r_req_o,           // IPIC read request
+    output  logic                                       csr2ipic_w_req_o,           // IPIC write request
+    output  logic [2:0]                                 csr2ipic_addr_o,            // IPIC address
+    output  logic [`SCR1_XLEN-1:0]                      csr2ipic_wdata_o,           // IPIC write data
+    input   logic [`SCR1_XLEN-1:0]                      ipic2csr_rdata_i,           // IPIC read data
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_DBG_EN
+    // CSR <-> HDU interface
+    output  logic                                       csr2hdu_req_o,              // Request to HDU
+    output  type_scr1_csr_cmd_sel_e                     csr2hdu_cmd_o,              // HDU command
+    output  logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0]    csr2hdu_addr_o,             // HDU address
+    output  logic [`SCR1_XLEN-1:0]                      csr2hdu_wdata_o,            // HDU write data
+    input   logic [`SCR1_XLEN-1:0]                      hdu2csr_rdata_i,            // HDU read data
+    input   type_scr1_csr_resp_e                        hdu2csr_resp_i,             // HDU response
+    input   logic                                       hdu2csr_no_commit_i,        // Forbid instruction commitment
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+    // CSR <-> TDU interface
+    output  logic                                       csr2tdu_req_o,              // Request to TDU
+    output  type_scr1_csr_cmd_sel_e                     csr2tdu_cmd_o,              // TDU command
+    output  logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]        csr2tdu_addr_o,             // TDU address
+    output  logic [`SCR1_XLEN-1:0]                      csr2tdu_wdata_o,            // TDU write data
+    input   logic [`SCR1_XLEN-1:0]                      tdu2csr_rdata_i,            // TDU read data
+    input   type_scr1_csr_resp_e                        tdu2csr_resp_i,             // TDU response
+`endif // SCR1_TDU_EN
+
+    // CSR <-> EXU PC interface
+`ifndef SCR1_CSR_REDUCED_CNT
+    input   logic                                       exu2csr_instret_no_exc_i,   // Instruction retired (without exception)
+`endif // SCR1_CSR_REDUCED_CNT
+    input   logic [`SCR1_XLEN-1:0]                      exu2csr_pc_curr_i,          // Current PC
+    input   logic [`SCR1_XLEN-1:0]                      exu2csr_pc_next_i,          // Next PC
+    output  logic [`SCR1_XLEN-1:0]                      csr2exu_new_pc_o            // Exception/IRQ/MRET new PC
+);
+
+//------------------------------------------------------------------------------
+// Local parameters
+//------------------------------------------------------------------------------
+
+`ifdef SCR1_RVC_EXT
+    localparam PC_LSB = 1;
+`else
+    localparam PC_LSB = 2;
+`endif
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// Machine Trap Setup registers
+//------------------------------------------------------------------------------
+
+// MSTATUS register
+logic                                               csr_mstatus_upd;        // MSTATUS update enable
+logic [`SCR1_XLEN-1:0]                              csr_mstatus;            // Aggregated MSTATUS
+logic                                               csr_mstatus_mie_ff;     // MSTATUS: Global interrupt enable
+logic                                               csr_mstatus_mie_next;   // MSTATUS: Global interrupt enable next value
+logic                                               csr_mstatus_mpie_ff;    // MSTATUS: Global interrupt enable prior to the trap
+logic                                               csr_mstatus_mpie_next;  // MSTATUS: Global interrupt enable prior to the trap next value
+
+// MIE register
+logic                                               csr_mie_upd;            // MIE update enable
+logic [`SCR1_XLEN-1:0]                              csr_mie;                // Aggregated MIE
+logic                                               csr_mie_mtie_ff;        // MIE: Machine timer interrupt enable
+logic                                               csr_mie_meie_ff;        // MIE: Machine external interrupt enable
+logic                                               csr_mie_msie_ff;        // MIE: Machine software interrupt enable
+
+// MTVEC register
+logic                                               csr_mtvec_upd;          // MTVEC update enable
+logic [`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS]  csr_mtvec_base;         // MTVEC: Base (upper 26 bits)
+logic                                               csr_mtvec_mode;         // MTVEC: Mode (0-direct, 1-vectored) (wired)
+`ifdef SCR1_MTVEC_MODE_EN
+logic                                               csr_mtvec_mode_ff;      // MTVEC: Mode (0-direct, 1-vectored) (registered)
+logic                                               csr_mtvec_mode_vect;
+`endif
+
+// Machine Trap Handling registers
+//------------------------------------------------------------------------------
+
+// MSCRATCH register
+logic                                               csr_mscratch_upd;       // MSCRATCH update enable
+logic [`SCR1_XLEN-1:0]                              csr_mscratch_ff;        // MSCRATCH
+
+// MEPC register
+logic                                               csr_mepc_upd;           // MEPC update enable
+logic [`SCR1_XLEN-1:PC_LSB]                         csr_mepc_ff;            // MEPC registered value
+logic [`SCR1_XLEN-1:PC_LSB]                         csr_mepc_next;          // MEPC next value
+logic [`SCR1_XLEN-1:0]                              csr_mepc;               // MEPC registered value extended to XLEN
+
+// MCAUSE register
+logic                                               csr_mcause_upd;         // MCAUSE update enable
+logic                                               csr_mcause_i_ff;        // MCAUSE: Interrupt
+logic                                               csr_mcause_i_next;      // MCAUSE: Interrupt next value
+type_scr1_exc_code_e                                csr_mcause_ec_ff;       // MCAUSE: Exception code
+type_scr1_exc_code_e                                csr_mcause_ec_next;     // MCAUSE: Exception code next value
+type_scr1_exc_code_e                                csr_mcause_ec_new;      // MCAUSE: Exception code new value (IRQs)
+
+// MTVAL register
+logic                                               csr_mtval_upd;          // MTVAL update enable
+logic [`SCR1_XLEN-1:0]                              csr_mtval_ff;           // MTVAL registered value
+logic [`SCR1_XLEN-1:0]                              csr_mtval_next;         // MTVAL next value
+
+// MIP register
+logic [`SCR1_XLEN-1:0]                              csr_mip;                // Aggregated MIP
+logic                                               csr_mip_mtip;           // MIP: Machine timer interrupt pending
+logic                                               csr_mip_meip;           // MIP: Machine external interrupt pending
+logic                                               csr_mip_msip;           // MIP: Machine software interrupt pending
+
+// Machine Counters/Timers registers
+//------------------------------------------------------------------------------
+
+`ifndef SCR1_CSR_REDUCED_CNT
+// MINSTRET register
+logic [1:0]                                         csr_minstret_upd;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:0]                 csr_minstret;
+logic                                               csr_minstret_lo_inc;
+logic                                               csr_minstret_lo_upd;
+logic [7:0]                                         csr_minstret_lo_ff;
+logic [7:0]                                         csr_minstret_lo_next;
+logic                                               csr_minstret_hi_inc;
+logic                                               csr_minstret_hi_upd;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_minstret_hi_ff;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_minstret_hi_next;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_minstret_hi_new;
+
+// MCYCLE register
+logic [1:0]                                         csr_mcycle_upd;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:0]                 csr_mcycle;
+logic                                               csr_mcycle_lo_inc;
+logic                                               csr_mcycle_lo_upd;
+logic [7:0]                                         csr_mcycle_lo_ff;
+logic [7:0]                                         csr_mcycle_lo_next;
+logic                                               csr_mcycle_hi_inc;
+logic                                               csr_mcycle_hi_upd;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_mcycle_hi_ff;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_mcycle_hi_next;
+logic [SCR1_CSR_COUNTERS_WIDTH-1:8]                 csr_mcycle_hi_new;
+`endif // ~SCR1_CSR_REDUCED_CNT
+
+// Non-standard CSRs
+//------------------------------------------------------------------------------
+
+// MCOUNTEN register
+`ifdef SCR1_MCOUNTEN_EN
+logic                                               csr_mcounten_upd;       // MCOUNTEN update enable
+logic [`SCR1_XLEN-1:0]                              csr_mcounten;           // Aggregated MCOUNTEN
+logic                                               csr_mcounten_cy_ff;     // Cycle count enable
+logic                                               csr_mcounten_ir_ff;     // Instret count enable
+`endif // SCR1_MCOUNTEN_EN
+
+// CSR read/write i/f
+//------------------------------------------------------------------------------
+
+logic [`SCR1_XLEN-1:0]                              csr_r_data;
+logic [`SCR1_XLEN-1:0]                              csr_w_data;
+
+// Events (exceptions, interrupts, mret) signals
+//------------------------------------------------------------------------------
+
+// Event flags
+logic                                               e_exc;              // Successful exception trap
+logic                                               e_irq;              // Successful IRQ trap
+logic                                               e_mret;             // MRET instruction
+logic                                               e_irq_nmret;        // IRQ trap without MRET instruction
+
+// Interrupt pending & enable signals
+logic                                               csr_eirq_pnd_en;    // External IRQ pending and locally enabled
+logic                                               csr_sirq_pnd_en;    // Software IRQ pending and locally enabled
+logic                                               csr_tirq_pnd_en;    // Timer IRQ pending and locally enabled
+
+// Exception flags
+logic                                               csr_w_exc;
+logic                                               csr_r_exc;
+logic                                               exu_req_no_exc;
+
+// Requests to other modules
+logic                                               csr_ipic_req;
+`ifdef SCR1_DBG_EN
+logic                                               csr_hdu_req;
+`endif // SCR1_DBG_EN
+`ifdef SCR1_TDU_EN
+logic                                               csr_brkm_req;
+`endif // SCR1_TDU_EN
+
+//------------------------------------------------------------------------------
+// Events (IRQ, EXC, MRET)
+//------------------------------------------------------------------------------
+
+// Events priority
+assign e_exc    = exu2csr_take_exc_i
+`ifdef SCR1_DBG_EN
+                & ~hdu2csr_no_commit_i
+`endif // SCR1_DBG_EN
+                ;
+assign e_irq    = exu2csr_take_irq_i & ~exu2csr_take_exc_i
+`ifdef SCR1_DBG_EN
+                & ~hdu2csr_no_commit_i
+`endif // SCR1_DBG_EN
+                ;
+assign e_mret   = exu2csr_mret_update_i
+`ifdef SCR1_DBG_EN
+                & ~hdu2csr_no_commit_i
+`endif // SCR1_DBG_EN
+                ;
+assign e_irq_nmret = e_irq & ~exu2csr_mret_instr_i;
+
+// IRQ pending & enable signals
+assign csr_eirq_pnd_en = csr_mip_meip & csr_mie_meie_ff;
+assign csr_sirq_pnd_en = csr_mip_msip & csr_mie_msie_ff;
+assign csr_tirq_pnd_en = csr_mip_mtip & csr_mie_mtie_ff;
+
+// IRQ exception codes priority
+always_comb begin
+    case (1'b1)
+        csr_eirq_pnd_en: csr_mcause_ec_new = type_scr1_exc_code_e'(SCR1_EXC_CODE_IRQ_M_EXTERNAL);
+        csr_sirq_pnd_en: csr_mcause_ec_new = type_scr1_exc_code_e'(SCR1_EXC_CODE_IRQ_M_SOFTWARE);
+        csr_tirq_pnd_en: csr_mcause_ec_new = type_scr1_exc_code_e'(SCR1_EXC_CODE_IRQ_M_TIMER);
+        default        : csr_mcause_ec_new = type_scr1_exc_code_e'(SCR1_EXC_CODE_IRQ_M_EXTERNAL);
+    endcase
+end
+
+assign exu_req_no_exc = ((exu2csr_r_req_i & ~csr_r_exc)
+                      |  (exu2csr_w_req_i & ~csr_w_exc));
+
+//------------------------------------------------------------------------------
+// CSR read/write interface
+//------------------------------------------------------------------------------
+
+// CSR read logic
+//------------------------------------------------------------------------------
+
+always_comb begin
+    csr_r_data     = '0;
+    csr_r_exc      = 1'b0;
+`ifdef SCR1_DBG_EN
+    csr_hdu_req    = 1'b0;
+`endif // SCR1_DBG_EN
+`ifdef SCR1_TDU_EN
+    csr_brkm_req   = 1'b0;
+`endif // SCR1_TDU_EN
+`ifdef SCR1_IPIC_EN
+    csr2ipic_r_req_o = 1'b0;
+`endif // SCR1_IPIC_EN
+
+    casez (exu2csr_rw_addr_i)
+        // Machine Information Registers (read-only)
+        SCR1_CSR_ADDR_MVENDORID : csr_r_data    = SCR1_CSR_MVENDORID;
+        SCR1_CSR_ADDR_MARCHID   : csr_r_data    = SCR1_CSR_MARCHID;
+        SCR1_CSR_ADDR_MIMPID    : csr_r_data    = SCR1_CSR_MIMPID;
+        SCR1_CSR_ADDR_MHARTID   : csr_r_data    = soc2csr_fuse_mhartid_i;
+
+        // Machine Trap Setup (read-write)
+        SCR1_CSR_ADDR_MSTATUS   : csr_r_data    = csr_mstatus;
+        SCR1_CSR_ADDR_MISA      : csr_r_data    = SCR1_CSR_MISA;
+        SCR1_CSR_ADDR_MIE       : csr_r_data    = csr_mie;
+        SCR1_CSR_ADDR_MTVEC     : csr_r_data    = {csr_mtvec_base, 4'd0, 2'(csr_mtvec_mode)};
+
+        // Machine Trap Handling (read-write)
+        SCR1_CSR_ADDR_MSCRATCH  : csr_r_data    = csr_mscratch_ff;
+        SCR1_CSR_ADDR_MEPC      : csr_r_data    = csr_mepc;
+        SCR1_CSR_ADDR_MCAUSE    : csr_r_data    = {csr_mcause_i_ff, type_scr1_csr_mcause_ec_v'(csr_mcause_ec_ff)};
+        SCR1_CSR_ADDR_MTVAL     : csr_r_data    = csr_mtval_ff;
+        SCR1_CSR_ADDR_MIP       : csr_r_data    = csr_mip;
+
+        // User Counters/Timers (read-only)
+        {SCR1_CSR_ADDR_HPMCOUNTER_MASK, 5'b?????}   : begin
+            case (exu2csr_rw_addr_i[4:0])
+                5'd1        : csr_r_data    = soc2csr_mtimer_val_i[31:0];
+`ifndef SCR1_CSR_REDUCED_CNT
+                5'd0        : csr_r_data    = csr_mcycle[31:0];
+                5'd2        : csr_r_data    = csr_minstret[31:0];
+`endif // SCR1_CSR_REDUCED_CNT
+                default     : begin
+                    // return 0
+                end
+            endcase
+        end
+
+        {SCR1_CSR_ADDR_HPMCOUNTERH_MASK, 5'b?????}  : begin
+            case (exu2csr_rw_addr_i[4:0])
+                5'd1        : csr_r_data    = soc2csr_mtimer_val_i[63:32];
+`ifndef SCR1_CSR_REDUCED_CNT
+                5'd0        : csr_r_data    = csr_mcycle[63:32];
+                5'd2        : csr_r_data    = csr_minstret[63:32];
+`endif // SCR1_CSR_REDUCED_CNT
+                default     : begin
+                    // return 0
+                end
+            endcase
+        end
+
+        // Machine Counters/Timers (read-write)
+        {SCR1_CSR_ADDR_MHPMCOUNTER_MASK, 5'b?????}  : begin
+            case (exu2csr_rw_addr_i[4:0])
+                5'd1        : csr_r_exc     = exu2csr_r_req_i;
+`ifndef SCR1_CSR_REDUCED_CNT
+                5'd0        : csr_r_data    = csr_mcycle[31:0];
+                5'd2        : csr_r_data    = csr_minstret[31:0];
+`endif // SCR1_CSR_REDUCED_CNT
+                default     : begin
+                    // return 0
+                end
+            endcase
+        end
+
+        {SCR1_CSR_ADDR_MHPMCOUNTERH_MASK, 5'b?????} : begin
+            case (exu2csr_rw_addr_i[4:0])
+                5'd1        : csr_r_exc     = exu2csr_r_req_i;
+`ifndef SCR1_CSR_REDUCED_CNT
+                5'd0        : csr_r_data    = csr_mcycle[63:32];
+                5'd2        : csr_r_data    = csr_minstret[63:32];
+`endif // SCR1_CSR_REDUCED_CNT
+                default     : begin
+                    // return 0
+                end
+            endcase
+        end
+
+        {SCR1_CSR_ADDR_MHPMEVENT_MASK, 5'b?????}    : begin
+            case (exu2csr_rw_addr_i[4:0])
+                5'd0,
+                5'd1,
+                5'd2        : csr_r_exc = exu2csr_r_req_i;
+                default     : begin
+                    // return 0
+                end
+            endcase
+        end
+
+`ifdef SCR1_MCOUNTEN_EN
+        SCR1_CSR_ADDR_MCOUNTEN      : csr_r_data    = csr_mcounten;
+`endif // SCR1_MCOUNTEN_EN
+
+`ifdef SCR1_IPIC_EN
+        // IPIC registers
+        SCR1_CSR_ADDR_IPIC_CISV,
+        SCR1_CSR_ADDR_IPIC_CICSR,
+        SCR1_CSR_ADDR_IPIC_IPR,
+        SCR1_CSR_ADDR_IPIC_ISVR,
+        SCR1_CSR_ADDR_IPIC_EOI,
+        SCR1_CSR_ADDR_IPIC_SOI,
+        SCR1_CSR_ADDR_IPIC_IDX,
+        SCR1_CSR_ADDR_IPIC_ICSR     : begin
+            csr_r_data       = ipic2csr_rdata_i;
+            csr2ipic_r_req_o = exu2csr_r_req_i;
+        end
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_DBG_EN
+        // HDU registers
+        SCR1_HDU_DBGCSR_ADDR_DCSR,
+        SCR1_HDU_DBGCSR_ADDR_DPC,
+        SCR1_HDU_DBGCSR_ADDR_DSCRATCH0,
+        SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 : begin
+            csr_hdu_req = 1'b1;
+            csr_r_data  = hdu2csr_rdata_i;
+        end
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+        // TDU registers
+        SCR1_CSR_ADDR_TDU_TSELECT,
+        SCR1_CSR_ADDR_TDU_TDATA1,
+        SCR1_CSR_ADDR_TDU_TDATA2,
+        SCR1_CSR_ADDR_TDU_TINFO: begin
+            csr_brkm_req    = 1'b1;
+            csr_r_data      = tdu2csr_rdata_i;
+        end
+`endif // SCR1_TDU_EN
+
+        default     : begin
+            csr_r_exc   = exu2csr_r_req_i;
+        end
+    endcase // exu2csr_rw_addr_i
+end
+
+assign csr2exu_r_data_o = csr_r_data;
+
+// CSR write logic
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (exu2csr_w_cmd_i)
+        SCR1_CSR_CMD_WRITE  : csr_w_data =  exu2csr_w_data_i;
+        SCR1_CSR_CMD_SET    : csr_w_data =  exu2csr_w_data_i | csr_r_data;
+        SCR1_CSR_CMD_CLEAR  : csr_w_data = ~exu2csr_w_data_i & csr_r_data;
+        default             : csr_w_data = '0;
+    endcase
+end
+
+always_comb begin
+    csr_mstatus_upd     = 1'b0;
+    csr_mie_upd         = 1'b0;
+    csr_mscratch_upd    = 1'b0;
+    csr_mepc_upd        = 1'b0;
+    csr_mcause_upd      = 1'b0;
+    csr_mtval_upd       = 1'b0;
+    csr_mtvec_upd       = 1'b0;
+
+`ifndef SCR1_CSR_REDUCED_CNT
+    csr_mcycle_upd      = 2'b00;
+    csr_minstret_upd    = 2'b00;
+`endif // SCR1_CSR_REDUCED_CNT
+
+`ifdef SCR1_MCOUNTEN_EN
+    csr_mcounten_upd    = 1'b0;
+`endif // SCR1_MCOUNTEN_EN
+    csr_w_exc           = 1'b0;
+`ifdef SCR1_IPIC_EN
+    csr2ipic_w_req_o    = 1'b0;
+`endif // SCR1_IPIC_EN
+
+    if (exu2csr_w_req_i) begin
+        casez (exu2csr_rw_addr_i)
+            // Machine Trap Setup (read-write)
+            SCR1_CSR_ADDR_MSTATUS   : csr_mstatus_upd   = 1'b1;
+            SCR1_CSR_ADDR_MISA      : begin end
+            SCR1_CSR_ADDR_MIE       : csr_mie_upd       = 1'b1;
+            SCR1_CSR_ADDR_MTVEC     : csr_mtvec_upd     = 1'b1;
+
+            // Machine Trap Handling (read-write)
+            SCR1_CSR_ADDR_MSCRATCH  : csr_mscratch_upd  = 1'b1;
+            SCR1_CSR_ADDR_MEPC      : csr_mepc_upd      = 1'b1;
+            SCR1_CSR_ADDR_MCAUSE    : csr_mcause_upd    = 1'b1;
+            SCR1_CSR_ADDR_MTVAL     : csr_mtval_upd     = 1'b1;
+            SCR1_CSR_ADDR_MIP       : begin end
+
+            // Machine Counters/Timers (read-write)
+            {SCR1_CSR_ADDR_MHPMCOUNTER_MASK, 5'b?????}  : begin
+                case (exu2csr_rw_addr_i[4:0])
+                    5'd1        : csr_w_exc           = 1'b1;
+`ifndef SCR1_CSR_REDUCED_CNT
+                    5'd0        : csr_mcycle_upd[0]   = 1'b1;
+                    5'd2        : csr_minstret_upd[0] = 1'b1;
+`endif // SCR1_CSR_REDUCED_CNT
+                    default     : begin
+                        // no exception
+                    end
+                endcase
+            end
+
+            {SCR1_CSR_ADDR_MHPMCOUNTERH_MASK, 5'b?????} : begin
+                case (exu2csr_rw_addr_i[4:0])
+                    5'd1        : csr_w_exc           = 1'b1;
+`ifndef SCR1_CSR_REDUCED_CNT
+                    5'd0        : csr_mcycle_upd[1]   = 1'b1;
+                    5'd2        : csr_minstret_upd[1] = 1'b1;
+`endif // SCR1_CSR_REDUCED_CNT
+                    default     : begin
+                        // no exception
+                    end
+                endcase
+            end
+
+            {SCR1_CSR_ADDR_MHPMEVENT_MASK, 5'b?????}    : begin
+                case (exu2csr_rw_addr_i[4:0])
+                    5'd0,
+                    5'd1,
+                    5'd2        : csr_w_exc = 1'b1;
+                    default     : begin
+                        // no exception
+                    end
+                endcase
+            end
+
+`ifdef SCR1_MCOUNTEN_EN
+            SCR1_CSR_ADDR_MCOUNTEN      : csr_mcounten_upd = 1'b1;
+`endif // SCR1_MCOUNTEN_EN
+
+`ifdef SCR1_IPIC_EN
+            // IPIC registers
+            SCR1_CSR_ADDR_IPIC_CICSR,
+            SCR1_CSR_ADDR_IPIC_IPR,
+            SCR1_CSR_ADDR_IPIC_EOI,
+            SCR1_CSR_ADDR_IPIC_SOI,
+            SCR1_CSR_ADDR_IPIC_IDX,
+            SCR1_CSR_ADDR_IPIC_ICSR     : begin
+                csr2ipic_w_req_o  = 1'b1;
+            end
+            SCR1_CSR_ADDR_IPIC_CISV,
+            SCR1_CSR_ADDR_IPIC_ISVR     : begin
+                // no exception on write
+            end
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_DBG_EN
+            SCR1_HDU_DBGCSR_ADDR_DCSR,
+            SCR1_HDU_DBGCSR_ADDR_DPC,
+            SCR1_HDU_DBGCSR_ADDR_DSCRATCH0,
+            SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 : begin
+            end
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+            // TDU registers
+            SCR1_CSR_ADDR_TDU_TSELECT,
+            SCR1_CSR_ADDR_TDU_TDATA1,
+            SCR1_CSR_ADDR_TDU_TDATA2,
+            SCR1_CSR_ADDR_TDU_TINFO: begin
+            end
+`endif // SCR1_TDU_EN
+
+            default : begin
+                csr_w_exc   = 1'b1;
+            end
+        endcase
+    end
+end
+
+//------------------------------------------------------------------------------
+// Machine Trap Setup registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - MSTATUS
+ // - MIE
+ // - MTVEC
+//
+
+// MSTATUS register
+//------------------------------------------------------------------------------
+// Consists of 2 bits - current and previous (before trap) global interrupt
+// enable bits (MIE & MPIE)
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mstatus_mie_ff  <= SCR1_CSR_MSTATUS_MIE_RST_VAL;
+        csr_mstatus_mpie_ff <= SCR1_CSR_MSTATUS_MPIE_RST_VAL;
+    end else begin
+        csr_mstatus_mie_ff  <= csr_mstatus_mie_next;
+        csr_mstatus_mpie_ff <= csr_mstatus_mpie_next;
+    end
+end
+
+always_comb begin
+    case (1'b1)
+        e_exc, e_irq  : begin
+            csr_mstatus_mie_next  = 1'b0;
+            csr_mstatus_mpie_next = csr_mstatus_mie_ff;
+        end
+        e_mret        : begin
+            csr_mstatus_mie_next  = csr_mstatus_mpie_ff;
+            csr_mstatus_mpie_next = 1'b1;
+        end
+        csr_mstatus_upd: begin
+            csr_mstatus_mie_next  = csr_w_data[SCR1_CSR_MSTATUS_MIE_OFFSET];
+            csr_mstatus_mpie_next = csr_w_data[SCR1_CSR_MSTATUS_MPIE_OFFSET];
+        end
+        default       : begin
+            csr_mstatus_mie_next  = csr_mstatus_mie_ff;
+            csr_mstatus_mpie_next = csr_mstatus_mpie_ff;
+        end
+    endcase
+end
+
+always_comb begin
+    csr_mstatus                                                            = '0;
+    csr_mstatus[SCR1_CSR_MSTATUS_MIE_OFFSET]                               = csr_mstatus_mie_ff;
+    csr_mstatus[SCR1_CSR_MSTATUS_MPIE_OFFSET]                              = csr_mstatus_mpie_ff;
+    csr_mstatus[SCR1_CSR_MSTATUS_MPP_OFFSET+1:SCR1_CSR_MSTATUS_MPP_OFFSET] = SCR1_CSR_MSTATUS_MPP;
+end
+
+// MIE register
+//------------------------------------------------------------------------------
+// Contains interrupt enable bits (external, software, timer IRQs)
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mie_mtie_ff <= SCR1_CSR_MIE_MTIE_RST_VAL;
+        csr_mie_meie_ff <= SCR1_CSR_MIE_MEIE_RST_VAL;
+        csr_mie_msie_ff <= SCR1_CSR_MIE_MSIE_RST_VAL;
+    end else if (csr_mie_upd) begin
+        csr_mie_mtie_ff <= csr_w_data[SCR1_CSR_MIE_MTIE_OFFSET];
+        csr_mie_meie_ff <= csr_w_data[SCR1_CSR_MIE_MEIE_OFFSET];
+        csr_mie_msie_ff <= csr_w_data[SCR1_CSR_MIE_MSIE_OFFSET];
+    end
+end
+
+always_comb begin
+    csr_mie                           = '0;
+    csr_mie[SCR1_CSR_MIE_MSIE_OFFSET] = csr_mie_msie_ff;
+    csr_mie[SCR1_CSR_MIE_MTIE_OFFSET] = csr_mie_mtie_ff;
+    csr_mie[SCR1_CSR_MIE_MEIE_OFFSET] = csr_mie_meie_ff;
+end
+
+// MTVEC register
+//------------------------------------------------------------------------------
+// Holds trap vector configuation. Consists of base and mode parts
+
+// MTVEC BASE part
+//------------------------------------------------------------------------------
+// Holds trap vector base address
+generate
+    // All bits of MTVEC base are Read-Only and hardwired to 0's
+    if (SCR1_MTVEC_BASE_WR_BITS == 0) begin : mtvec_base_ro
+
+        assign csr_mtvec_base   = SCR1_CSR_MTVEC_BASE_RST_VAL;
+
+    // All bits of MTVEC base are RW
+    end else if (SCR1_MTVEC_BASE_WR_BITS == SCR1_CSR_MTVEC_BASE_VAL_BITS) begin : mtvec_base_rw
+
+        always_ff @(negedge rst_n, posedge clk) begin
+            if (~rst_n) begin
+                csr_mtvec_base  <= SCR1_CSR_MTVEC_BASE_RST_VAL;
+            end else if (csr_mtvec_upd) begin
+                csr_mtvec_base  <= csr_w_data[`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS];
+            end
+        end
+
+    // Lower bits of MTVEC base are RO, higher - RW
+    end else begin : mtvec_base_ro_rw
+
+        logic [(`SCR1_XLEN-1):(`SCR1_XLEN-SCR1_MTVEC_BASE_WR_BITS)]   csr_mtvec_base_reg;
+
+        always_ff @(negedge rst_n, posedge clk) begin
+            if (~rst_n) begin
+                csr_mtvec_base_reg <= SCR1_CSR_MTVEC_BASE_RST_VAL[(`SCR1_XLEN-1)-:SCR1_MTVEC_BASE_WR_BITS] ;
+            end else if (csr_mtvec_upd) begin
+                csr_mtvec_base_reg <= csr_w_data[(`SCR1_XLEN-1)-:SCR1_MTVEC_BASE_WR_BITS];
+            end
+        end
+
+        assign csr_mtvec_base = {csr_mtvec_base_reg, SCR1_CSR_MTVEC_BASE_RST_VAL[SCR1_CSR_MTVEC_BASE_ZERO_BITS+:SCR1_CSR_MTVEC_BASE_RO_BITS]};
+    end
+endgenerate
+
+// MTVEC MODE part
+//------------------------------------------------------------------------------
+// Chooses between direct (all exceptions set PC to BASE) or vectored
+// (asynchronous interrupts set PC to BASE+4xcause) interrupt modes
+
+`ifdef SCR1_MTVEC_MODE_EN
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mtvec_mode_ff <= SCR1_CSR_MTVEC_MODE_DIRECT;
+    end else if (csr_mtvec_upd) begin
+        csr_mtvec_mode_ff <= csr_w_data[0];
+    end
+end
+
+assign csr_mtvec_mode      = csr_mtvec_mode_ff;
+assign csr_mtvec_mode_vect = (csr_mtvec_mode_ff == SCR1_CSR_MTVEC_MODE_VECTORED);
+`else // SCR1_MTVEC_MODE_EN
+assign csr_mtvec_mode = SCR1_CSR_MTVEC_MODE_DIRECT;
+`endif // SCR1_MTVEC_MODE_EN
+
+//------------------------------------------------------------------------------
+// Machine Trap Handling registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - MSCRATCH
+ // - MEPC
+ // - MCAUSE
+ // - MTVAL
+ // - MIP
+//
+
+// MSCRATCH register
+//------------------------------------------------------------------------------
+// Holds a pointer to a machine-mode hart-local context space
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mscratch_ff <= '0;
+    end else if (csr_mscratch_upd) begin
+        csr_mscratch_ff <= csr_w_data;
+    end
+end
+
+// MEPC register
+//------------------------------------------------------------------------------
+// When a trap is taken into M-mode saves the virtual address of instruction that
+// was interrupted or that encountered the exception
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mepc_ff <= '0;
+    end else begin
+        csr_mepc_ff <= csr_mepc_next;
+    end
+end
+
+always_comb begin
+    case (1'b1)
+        e_exc       : csr_mepc_next = exu2csr_pc_curr_i[`SCR1_XLEN-1:PC_LSB];
+        e_irq_nmret : csr_mepc_next = exu2csr_pc_next_i[`SCR1_XLEN-1:PC_LSB];
+        csr_mepc_upd: csr_mepc_next = csr_w_data[`SCR1_XLEN-1:PC_LSB];
+        default     : csr_mepc_next = csr_mepc_ff;
+    endcase
+end
+
+`ifdef SCR1_RVC_EXT
+    assign csr_mepc = {csr_mepc_ff, 1'b0};
+`else
+    assign csr_mepc = {csr_mepc_ff, 2'b00};
+`endif
+
+// MCAUSE register
+//------------------------------------------------------------------------------
+// When a trap is taken into M-mode saves a code indicating the event that caused
+// the trap
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mcause_i_ff  <= 1'b0;
+        csr_mcause_ec_ff <= type_scr1_exc_code_e'(SCR1_EXC_CODE_RESET);
+    end else begin
+        csr_mcause_i_ff  <= csr_mcause_i_next;
+        csr_mcause_ec_ff <= csr_mcause_ec_next;
+    end
+end
+
+always_comb begin
+    case (1'b1)
+        e_exc         : begin
+            csr_mcause_i_next  = 1'b0;
+            csr_mcause_ec_next = exu2csr_exc_code_i;
+        end
+        e_irq         : begin
+            csr_mcause_i_next  = 1'b1;
+            csr_mcause_ec_next = csr_mcause_ec_new;
+        end
+        csr_mcause_upd: begin
+            csr_mcause_i_next  = csr_w_data[`SCR1_XLEN-1];
+            csr_mcause_ec_next = type_scr1_exc_code_e'(csr_w_data[SCR1_EXC_CODE_WIDTH_E-1:0]);
+        end
+        default       : begin
+            csr_mcause_i_next  = csr_mcause_i_ff;
+            csr_mcause_ec_next = csr_mcause_ec_ff;
+        end
+    endcase
+end
+
+// MTVAL register
+//------------------------------------------------------------------------------
+// When a trap is taken into M-mode is either set to zero or written with exception-
+// specific information
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mtval_ff <= '0;
+    end else begin
+        csr_mtval_ff <= csr_mtval_next;
+    end
+end
+
+always_comb begin
+    case (1'b1)
+        e_exc        : csr_mtval_next = exu2csr_trap_val_i;
+        e_irq        : csr_mtval_next = '0;
+        csr_mtval_upd: csr_mtval_next = csr_w_data;
+        default      : csr_mtval_next = csr_mtval_ff;
+    endcase
+end
+
+// MIP register
+//------------------------------------------------------------------------------
+// Contains information on pending interrupts (external, software, timer IRQs)
+
+assign csr_mip_mtip = soc2csr_irq_mtimer_i;
+assign csr_mip_meip = soc2csr_irq_ext_i;
+assign csr_mip_msip = soc2csr_irq_soft_i;
+
+always_comb begin
+    csr_mip                           = '0;
+    csr_mip[SCR1_CSR_MIE_MSIE_OFFSET] = csr_mip_msip;
+    csr_mip[SCR1_CSR_MIE_MTIE_OFFSET] = csr_mip_mtip;
+    csr_mip[SCR1_CSR_MIE_MEIE_OFFSET] = csr_mip_meip;
+end
+
+//------------------------------------------------------------------------------
+// Machine Counters/Timers registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - MCYCLE
+ // - MINSTRET
+//
+
+`ifndef SCR1_CSR_REDUCED_CNT
+// MCYCLE register
+//------------------------------------------------------------------------------
+// Holds the number of clock cycles since some arbitrary point of time in the
+// past at which MCYCLE was zero
+
+assign csr_mcycle_lo_inc = 1'b1
+ `ifdef SCR1_MCOUNTEN_EN
+                         & csr_mcounten_cy_ff
+ `endif // SCR1_MCOUNTEN_EN
+                         ;
+assign csr_mcycle_hi_inc = csr_mcycle_lo_inc & (&csr_mcycle_lo_ff);
+
+assign csr_mcycle_lo_upd = csr_mcycle_lo_inc | csr_mcycle_upd[0];
+assign csr_mcycle_hi_upd = csr_mcycle_hi_inc | (|csr_mcycle_upd);
+
+ `ifndef SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk) begin
+ `else // SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk_alw_on) begin
+ `endif // SCR1_CLKCTRL_EN
+    if (~rst_n) begin
+        csr_mcycle_lo_ff <= '0;
+        csr_mcycle_hi_ff <= '0;
+    end else begin
+        if (csr_mcycle_lo_upd) csr_mcycle_lo_ff <= csr_mcycle_lo_next;
+        if (csr_mcycle_hi_upd) csr_mcycle_hi_ff <= csr_mcycle_hi_next;
+    end
+end
+
+assign csr_mcycle_hi_new  = csr_mcycle_hi_ff + 1'b1;
+
+assign csr_mcycle_lo_next = csr_mcycle_upd[0] ? csr_w_data[7:0]
+                          : csr_mcycle_lo_inc ? csr_mcycle_lo_ff + 1'b1
+                                              : csr_mcycle_lo_ff;
+assign csr_mcycle_hi_next = csr_mcycle_upd[0] ? {csr_mcycle_hi_new[63:32], csr_w_data[31:8]}
+                          : csr_mcycle_upd[1] ? {csr_w_data, csr_mcycle_hi_new[31:8]}
+                          : csr_mcycle_hi_inc ? csr_mcycle_hi_new
+                                              : csr_mcycle_hi_ff;
+
+assign csr_mcycle = {csr_mcycle_hi_ff, csr_mcycle_lo_ff};
+
+// MINSTRET register
+//------------------------------------------------------------------------------
+// Holds the number of instructions executed by the core from some arbitrary time
+// in the past at which MINSTRET was equal to zero
+
+assign csr_minstret_lo_inc = exu2csr_instret_no_exc_i
+ `ifdef SCR1_MCOUNTEN_EN
+                           & csr_mcounten_ir_ff
+ `endif // SCR1_MCOUNTEN_EN
+                           ;
+assign csr_minstret_hi_inc = csr_minstret_lo_inc & (&csr_minstret_lo_ff);
+
+assign csr_minstret_lo_upd = csr_minstret_lo_inc | csr_minstret_upd[0];
+assign csr_minstret_hi_upd = csr_minstret_hi_inc | (|csr_minstret_upd);
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_minstret_lo_ff <= '0;
+        csr_minstret_hi_ff <= '0;
+    end else begin
+        if (csr_minstret_lo_upd) csr_minstret_lo_ff <= csr_minstret_lo_next;
+        if (csr_minstret_hi_upd) csr_minstret_hi_ff <= csr_minstret_hi_next;
+    end
+end
+
+assign csr_minstret_hi_new  = csr_minstret_hi_ff + 1'b1;
+
+assign csr_minstret_lo_next = csr_minstret_upd[0] ? csr_w_data[7:0]
+                            : csr_minstret_lo_inc ? csr_minstret_lo_ff + 1'b1
+                                                  : csr_minstret_lo_ff;
+assign csr_minstret_hi_next = csr_minstret_upd[0] ? {csr_minstret_hi_new[63:32], csr_w_data[31:8]}
+                            : csr_minstret_upd[1] ? {csr_w_data, csr_minstret_hi_new[31:8]}
+                            : csr_minstret_hi_inc ? csr_minstret_hi_new
+                                                  : csr_minstret_hi_ff;
+
+assign csr_minstret = {csr_minstret_hi_ff, csr_minstret_lo_ff};
+`endif // SCR1_CSR_REDUCED_CNT
+
+//------------------------------------------------------------------------------
+// Non-standard CSR
+//------------------------------------------------------------------------------
+
+`ifdef SCR1_MCOUNTEN_EN
+// MCOUNTEN register
+//------------------------------------------------------------------------------
+// Holds Counters enable bits (CY - MCYCLE counter; IR - MINSTRET counter)
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_mcounten_cy_ff <= 1'b1;
+        csr_mcounten_ir_ff <= 1'b1;
+    end else if (csr_mcounten_upd) begin
+        csr_mcounten_cy_ff <= csr_w_data[SCR1_CSR_MCOUNTEN_CY_OFFSET];
+        csr_mcounten_ir_ff <= csr_w_data[SCR1_CSR_MCOUNTEN_IR_OFFSET];
+    end
+end
+
+always_comb begin
+    csr_mcounten    = '0;
+    csr_mcounten[SCR1_CSR_MCOUNTEN_CY_OFFSET]   = csr_mcounten_cy_ff;
+    csr_mcounten[SCR1_CSR_MCOUNTEN_IR_OFFSET]   = csr_mcounten_ir_ff;
+end
+`endif // SCR1_MCOUNTEN_EN
+
+//------------------------------------------------------------------------------
+// CSR <-> EXU interface
+//------------------------------------------------------------------------------
+
+// CSR exception
+assign csr2exu_rw_exc_o = csr_r_exc | csr_w_exc
+`ifdef SCR1_DBG_EN
+                        | (csr2hdu_req_o & (hdu2csr_resp_i != SCR1_CSR_RESP_OK))
+`endif // SCR1_DBG_EN
+`ifdef SCR1_TDU_EN
+                        | (csr2tdu_req_o & (tdu2csr_resp_i != SCR1_CSR_RESP_OK))
+`endif // SCR1_TDU_EN
+                        ;
+assign csr2exu_ip_ie_o  = csr_eirq_pnd_en | csr_sirq_pnd_en | csr_tirq_pnd_en;
+assign csr2exu_irq_o    = csr2exu_ip_ie_o & csr_mstatus_mie_ff;
+
+assign csr2exu_mstatus_mie_up_o = csr_mstatus_upd | csr_mie_upd | e_mret;
+
+// New PC multiplexer
+`ifndef SCR1_MTVEC_MODE_EN
+assign csr2exu_new_pc_o = (exu2csr_mret_instr_i & ~exu2csr_take_irq_i)
+                        ? csr_mepc
+                        : {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
+`else // SCR1_MTVEC_MODE_EN
+always_comb begin
+    if (exu2csr_mret_instr_i & ~exu2csr_take_irq_i) begin
+        csr2exu_new_pc_o  = csr_mepc;
+    end else begin
+        if (csr_mtvec_mode_vect) begin
+            case (1'b1)
+                exu2csr_take_exc_i: csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
+                csr_eirq_pnd_en   : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_EXTERNAL, 2'd0};
+                csr_sirq_pnd_en   : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_SOFTWARE, 2'd0};
+                csr_tirq_pnd_en   : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_EXC_CODE_IRQ_M_TIMER, 2'd0};
+                default           : csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
+            endcase
+        end else begin // direct mode
+            csr2exu_new_pc_o = {csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)};
+        end
+    end
+end
+`endif // SCR1_MTVEC_MODE_EN
+
+`ifdef SCR1_IPIC_EN
+//------------------------------------------------------------------------------
+// CSR <-> IPIC interface
+//------------------------------------------------------------------------------
+
+assign csr_ipic_req     = csr2ipic_r_req_o | csr2ipic_w_req_o;
+assign csr2ipic_addr_o  = csr_ipic_req     ? exu2csr_rw_addr_i[2:0] : '0;
+assign csr2ipic_wdata_o = csr2ipic_w_req_o ? exu2csr_w_data_i       : '0;
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_DBG_EN
+//------------------------------------------------------------------------------
+// CSR <-> HDU interface
+//------------------------------------------------------------------------------
+
+assign csr2hdu_req_o   = csr_hdu_req & exu_req_no_exc;
+assign csr2hdu_cmd_o   = exu2csr_w_cmd_i;
+assign csr2hdu_addr_o  = exu2csr_rw_addr_i[SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0];
+assign csr2hdu_wdata_o = exu2csr_w_data_i;
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+//------------------------------------------------------------------------------
+// CSR <-> TDU interface
+//------------------------------------------------------------------------------
+
+assign csr2tdu_req_o   = csr_brkm_req & exu_req_no_exc;
+assign csr2tdu_cmd_o   = exu2csr_w_cmd_i;
+assign csr2tdu_addr_o  = exu2csr_rw_addr_i[SCR1_CSR_ADDR_TDU_OFFS_W-1:0];
+assign csr2tdu_wdata_o = exu2csr_w_data_i;
+`endif // SCR1_TDU_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//------------------------------------------------------------------------------
+// Assertions
+//------------------------------------------------------------------------------
+
+// X checks
+
+SCR1_SVA_CSR_XCHECK_CTRL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({exu2csr_r_req_i, exu2csr_w_req_i, exu2csr_take_irq_i, exu2csr_take_exc_i, exu2csr_mret_update_i
+`ifndef SCR1_CSR_REDUCED_CNT
+    , exu2csr_instret_no_exc_i
+`endif // SCR1_CSR_REDUCED_CNT
+    })
+    ) else $error("CSR Error: unknown control values");
+
+SCR1_SVA_CSR_XCHECK_READ : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2csr_r_req_i |-> !$isunknown({exu2csr_rw_addr_i, csr2exu_r_data_o, csr2exu_rw_exc_o})
+    ) else $error("CSR Error: unknown control values");
+
+SCR1_SVA_CSR_XCHECK_WRITE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2csr_w_req_i |-> !$isunknown({exu2csr_rw_addr_i, exu2csr_w_cmd_i, exu2csr_w_data_i, csr2exu_rw_exc_o})
+    ) else $error("CSR Error: unknown control values");
+
+`ifdef SCR1_IPIC_EN
+SCR1_SVA_CSR_XCHECK_READ_IPIC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    csr2ipic_r_req_o |-> !$isunknown({csr2ipic_addr_o, ipic2csr_rdata_i})
+    ) else $error("CSR Error: unknown control values");
+
+SCR1_SVA_CSR_XCHECK_WRITE_IPIC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    csr2ipic_w_req_o |-> !$isunknown({csr2ipic_addr_o, csr2ipic_wdata_o})
+    ) else $error("CSR Error: unknown control values");
+`endif // SCR1_IPIC_EN
+
+// Behavior checks
+
+SCR1_SVA_CSR_MRET : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    e_mret |=> ($stable(csr_mepc_ff) & $stable(csr_mtval_ff))
+    ) else $error("CSR Error: MRET wrong behavior");
+
+SCR1_SVA_CSR_MRET_IRQ : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (exu2csr_mret_instr_i & e_irq)
+    |=> ($stable(csr_mepc_ff) & (exu2csr_pc_curr_i != csr_mepc))
+    ) else $error("CSR Error: MRET+IRQ wrong behavior");
+
+SCR1_SVA_CSR_EXC_IRQ : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (exu2csr_take_exc_i & exu2csr_take_irq_i
+`ifdef SCR1_DBG_EN
+    & ~hdu2csr_no_commit_i
+`endif
+    ) |=>
+    (~csr_mstatus_mie_ff & (~csr_mcause_i_ff)
+    & (exu2csr_pc_curr_i=={csr_mtvec_base, SCR1_CSR_MTVEC_BASE_ZERO_BITS'(0)}))
+    ) else $error("CSR Error: wrong EXC+IRQ");
+
+SCR1_SVA_CSR_EVENTS : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    $onehot0({e_irq, e_exc, e_mret})
+    ) else $error("CSR Error: more than one event at a time");
+
+SCR1_SVA_CSR_RW_EXC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    csr2exu_rw_exc_o |-> (exu2csr_w_req_i | exu2csr_r_req_i)
+    ) else $error("CSR Error: impossible exception");
+
+SCR1_SVA_CSR_MSTATUS_MIE_UP : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    csr2exu_mstatus_mie_up_o |=> ~csr2exu_mstatus_mie_up_o
+    ) else $error("CSR Error: csr2exu_mstatus_mie_up_o can only be high for one mcycle");
+
+
+`ifndef SCR1_CSR_REDUCED_CNT
+
+SCR1_SVA_CSR_CYCLE_INC : assert property (
+    @(
+`ifndef SCR1_CLKCTRL_EN
+negedge clk
+`else // SCR1_CLKCTRL_EN
+negedge clk_alw_on
+`endif // SCR1_CLKCTRL_EN
+    ) disable iff (~rst_n)
+    (~|csr_mcycle_upd) |=>
+`ifdef SCR1_MCOUNTEN_EN
+    ($past(csr_mcounten_cy_ff) ? (csr_mcycle == $past(csr_mcycle + 1'b1)) : $stable(csr_mcycle))
+`else //SCR1_MCOUNTEN_EN
+    (csr_mcycle == $past(csr_mcycle + 1'b1))
+`endif // SCR1_MCOUNTEN_EN
+    ) else $error("CSR Error: CYCLE increment wrong behavior");
+
+SCR1_SVA_CSR_INSTRET_INC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (exu2csr_instret_no_exc_i & ~|csr_minstret_upd) |=>
+`ifdef SCR1_MCOUNTEN_EN
+    ($past(csr_mcounten_ir_ff) ? (csr_minstret == $past(csr_minstret + 1'b1)) : $stable(csr_minstret))
+`else //SCR1_MCOUNTEN_EN
+    (csr_minstret == $past(csr_minstret + 1'b1))
+`endif // SCR1_MCOUNTEN_EN
+    ) else $error("CSR Error: INSTRET increment wrong behavior");
+
+SCR1_SVA_CSR_CYCLE_INSTRET_UP : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ~(&csr_minstret_upd | &csr_mcycle_upd)
+    ) else $error("CSR Error: INSTRET/CYCLE up illegal value");
+
+`endif // SCR1_CSR_REDUCED_CNT
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_csr
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_exu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_exu.sv
new file mode 100644
index 0000000..f518a84
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_exu.sv
@@ -0,0 +1,1061 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_exu.sv>
+/// @brief      Execution Unit (EXU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Performs instructions execution:
+ //   - Prevents instructions from execution if the HART is in WFI or Debug Halted
+ //     state
+ //   - Fetches operands for IALU
+ //   - Calculates operation results via IALU
+ //   - Stores IALU results in MPRF
+ //   - Performs LOAD/STORE operations via LSU
+ // - Handles exceptions:
+ //   - Generates exception request
+ //   - Encodes exception code
+ //   - Calculates exception trap value
+ // - Controls WFI instruction execution
+ // - Calculates PC value:
+ //   - Initializes PC on reset
+ //   - Stores the current PC value
+ //   - Calculates a New PC value and generates a New PC request to IFU
+ //
+ // Structure:
+ // - Instruction queue
+ // - Integer Arithmetic Logic Unit (IALU)
+ // - Exceptions logic
+ // - WFI logic
+ // - Program Counter logic
+ // - Load-Store Unit (LSU)
+ // - EXU status logic
+ // - EXU <-> MPRF i/f
+ // - EXU <-> CSR i/f
+ // - EXU <-> TDU i/f
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_memif.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_csr.svh"
+
+`ifdef SCR1_DBG_EN
+ `include "scr1_hdu.svh"
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+ `include "scr1_tdu.svh"
+`endif // SCR1_TDU_EN
+
+module scr1_pipe_exu (
+    // Common
+    input   logic                               rst_n,                      // EXU reset
+    input   logic                               clk,                        // Gated EXU clock
+`ifdef SCR1_CLKCTRL_EN
+    input   logic                               clk_alw_on,                 // Not-gated EXU clock
+    input   logic                               clk_pipe_en,                // EXU clock enabled flag
+`endif // SCR1_CLKCTRL_EN
+
+    // EXU <-> IDU interface
+    input   logic                               idu2exu_req_i,              // Request form IDU to EXU
+    output  logic                               exu2idu_rdy_o,              // EXU ready for new data from IDU
+    input   type_scr1_exu_cmd_s                 idu2exu_cmd_i,              // EXU command
+    input   logic                               idu2exu_use_rs1_i,          // Clock gating on rs1_addr field
+    input   logic                               idu2exu_use_rs2_i,          // Clock gating on rs2_addr field
+`ifndef SCR1_NO_EXE_STAGE
+    input   logic                               idu2exu_use_rd_i,           // Clock gating on rd_addr field
+    input   logic                               idu2exu_use_imm_i,          // Clock gating on imm field
+`endif // SCR1_NO_EXE_STAGE
+
+    // EXU <-> MPRF interface
+    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs1_addr_o,        // MPRF rs1 read address
+    input   logic [`SCR1_XLEN-1:0]              mprf2exu_rs1_data_i,        // MPRF rs1 read data
+    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs2_addr_o,        // MPRF rs2 read address
+    input   logic [`SCR1_XLEN-1:0]              mprf2exu_rs2_data_i,        // MPRF rs2 read data
+    output  logic                               exu2mprf_w_req_o,           // MPRF write request
+    output  logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rd_addr_o,         // MPRF rd write address
+    output  logic [`SCR1_XLEN-1:0]              exu2mprf_rd_data_o,         // MPRF rd write data
+
+    // EXU <-> CSR read/write interface
+    output  logic [SCR1_CSR_ADDR_WIDTH-1:0]     exu2csr_rw_addr_o,          // CSR read/write address
+    output  logic                               exu2csr_r_req_o,            // CSR read request
+    input   logic [`SCR1_XLEN-1:0]              csr2exu_r_data_i,           // CSR read data
+    output  logic                               exu2csr_w_req_o,            // CSR write request
+    output  type_scr1_csr_cmd_sel_e             exu2csr_w_cmd_o,            // CSR write command
+    output  logic [`SCR1_XLEN-1:0]              exu2csr_w_data_o,           // CSR write data
+    input   logic                               csr2exu_rw_exc_i,           // CSR read/write access exception
+
+    // EXU <-> CSR events interface
+    output  logic                               exu2csr_take_irq_o,         // Take IRQ trap
+    output  logic                               exu2csr_take_exc_o,         // Take exception trap
+    output  logic                               exu2csr_mret_update_o,      // MRET update CSR
+    output  logic                               exu2csr_mret_instr_o,       // MRET instruction
+    output  type_scr1_exc_code_e                exu2csr_exc_code_o,         // Exception code (see scr1_arch_types.svh)
+    output  logic [`SCR1_XLEN-1:0]              exu2csr_trap_val_o,         // Trap value
+    input   logic [`SCR1_XLEN-1:0]              csr2exu_new_pc_i,           // Exception/IRQ/MRET new PC
+    input   logic                               csr2exu_irq_i,              // IRQ request
+    input   logic                               csr2exu_ip_ie_i,            // Some IRQ pending and locally enabled
+    input   logic                               csr2exu_mstatus_mie_up_i,   // MSTATUS or MIE update in the current cycle
+
+    // EXU <-> DMEM interface
+    output  logic                               exu2dmem_req_o,             // Data memory request
+    output  type_scr1_mem_cmd_e                 exu2dmem_cmd_o,             // Data memory command
+    output  type_scr1_mem_width_e               exu2dmem_width_o,           // Data memory width
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]       exu2dmem_addr_o,            // Data memory address
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]       exu2dmem_wdata_o,           // Data memory write data
+    input   logic                               dmem2exu_req_ack_i,         // Data memory request acknowledge
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]       dmem2exu_rdata_i,           // Data memory read data
+    input   type_scr1_mem_resp_e                dmem2exu_resp_i,            // Data memory response
+
+    // EXU control
+    output  logic                               exu2pipe_exc_req_o,         // Exception on last instruction
+    output  logic                               exu2pipe_brkpt_o,           // Software Breakpoint (EBREAK)
+    output  logic                               exu2pipe_init_pc_o,         // Reset exit
+    output  logic                               exu2pipe_wfi_run2halt_o,    // Transition to WFI halted state
+    output  logic                               exu2pipe_instret_o,         // Instruction retired (with or without exception)
+    output  logic                               exu2csr_instret_no_exc_o,   // Instruction retired (without exception)
+    output  logic                               exu2pipe_exu_busy_o,        // EXU busy
+
+`ifdef SCR1_DBG_EN
+    // EXU <-> HDU interface
+    input   logic                               hdu2exu_no_commit_i,        // Forbid instruction commitment
+    input   logic                               hdu2exu_irq_dsbl_i,         // Disable IRQ
+    input   logic                               hdu2exu_pc_advmt_dsbl_i,    // Forbid PC advancement
+    input   logic                               hdu2exu_dmode_sstep_en_i,   // Enable single-step
+    input   logic                               hdu2exu_pbuf_fetch_i,       // Take instructions from Program Buffer
+    input   logic                               hdu2exu_dbg_halted_i,       // Debug halted state
+    input   logic                               hdu2exu_dbg_run2halt_i,     // Transition to debug halted state
+    input   logic                               hdu2exu_dbg_halt2run_i,     // Transition to run state
+    input   logic                               hdu2exu_dbg_run_start_i,    // First cycle of run state
+    input   logic [`SCR1_XLEN-1:0]              hdu2exu_dbg_new_pc_i,       // New PC as starting point for HART Resume
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+    // EXU <-> TDU interface
+    output type_scr1_brkm_instr_mon_s           exu2tdu_imon_o,             // Instruction monitor
+    input  logic [SCR1_TDU_ALLTRIG_NUM-1:0]     tdu2exu_ibrkpt_match_i,     // Instruction breakpoint(s) match
+    input  logic                                tdu2exu_ibrkpt_exc_req_i,   // Instruction breakpoint exception
+    output type_scr1_brkm_lsu_mon_s             lsu2tdu_dmon_o,             // Data monitor
+    input  logic                                tdu2lsu_ibrkpt_exc_req_i,   // Instruction breakpoint exception
+    input  logic [SCR1_TDU_MTRIG_NUM-1:0]       tdu2lsu_dbrkpt_match_i,     // Data breakpoint(s) match
+    input  logic                                tdu2lsu_dbrkpt_exc_req_i,   // Data breakpoint exception
+    output logic [SCR1_TDU_ALLTRIG_NUM-1:0]     exu2tdu_ibrkpt_ret_o,       // Instruction with breakpoint flag retire
+    output logic                                exu2hdu_ibrkpt_hw_o,        // Hardware breakpoint on current instruction
+`endif // SCR1_TDU_EN
+
+    // PC interface
+`ifdef SCR1_CLKCTRL_EN
+    output  logic                               exu2pipe_wfi_halted_o,      // WFI halted state
+`endif // SCR1_CLKCTRL_EN
+    output  logic [`SCR1_XLEN-1:0]              exu2pipe_pc_curr_o,         // Current PC
+    output  logic [`SCR1_XLEN-1:0]              exu2csr_pc_next_o,          // Next PC
+    output  logic                               exu2ifu_pc_new_req_o,       // New PC request
+    output  logic [`SCR1_XLEN-1:0]              exu2ifu_pc_new_o            // New PC data
+);
+
+//------------------------------------------------------------------------------
+// Local parameters declaration
+//------------------------------------------------------------------------------
+
+localparam SCR1_JUMP_MASK = `SCR1_XLEN'hFFFF_FFFE;
+
+//------------------------------------------------------------------------------
+// Local types declaration
+//------------------------------------------------------------------------------
+
+typedef enum logic {
+    SCR1_CSR_INIT,
+    SCR1_CSR_RDY
+} scr1_csr_access_e;
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// Instruction queue signals
+//------------------------------------------------------------------------------
+logic                               exu_queue_vd;
+type_scr1_exu_cmd_s                 exu_queue;
+logic                               exu_queue_barrier;
+
+`ifdef SCR1_DBG_EN
+logic                               dbg_run_start_npbuf;
+`endif // SCR1_DBG_EN
+logic                               exu_queue_en;
+logic [`SCR1_XLEN-1:0]              exu_illegal_instr;
+
+`ifndef SCR1_NO_EXE_STAGE
+logic                               idu2exu_use_rs1_ff;
+logic                               idu2exu_use_rs2_ff;
+
+// EXU queue valid flag register signals
+logic                               exu_queue_vd_upd;
+logic                               exu_queue_vd_ff;
+logic                               exu_queue_vd_next;
+`endif // SCR1_NO_EXE_STAGE
+
+// IALU signals
+//------------------------------------------------------------------------------
+`ifdef SCR1_RVM_EXT
+logic                               ialu_rdy;
+logic                               ialu_vd;
+`endif // SCR1_RVM_EXT
+logic [`SCR1_XLEN-1:0]              ialu_main_op1;
+logic [`SCR1_XLEN-1:0]              ialu_main_op2;
+logic [`SCR1_XLEN-1:0]              ialu_main_res;
+logic [`SCR1_XLEN-1:0]              ialu_addr_op1;
+logic [`SCR1_XLEN-1:0]              ialu_addr_op2;
+logic [`SCR1_XLEN-1:0]              ialu_addr_res;
+logic                               ialu_cmp;
+
+// Exceptions signals
+//------------------------------------------------------------------------------
+logic                               exu_exc_req;
+`ifdef SCR1_DBG_EN
+logic                               exu_exc_req_ff;
+logic                               exu_exc_req_next;
+`endif // SCR1_DBG_EN
+type_scr1_exc_code_e                exc_code;
+logic [`SCR1_XLEN-1:0]              exc_trap_val;
+logic                               instr_fault_rvi_hi;
+
+// WFI signals
+//------------------------------------------------------------------------------
+// WFI control signals
+logic                               wfi_halt_cond;
+logic                               wfi_run_req;
+logic                               wfi_halt_req;
+
+// WFI Run Start register
+logic                               wfi_run_start_ff;
+logic                               wfi_run_start_next;
+
+// WFI halted register
+logic                               wfi_halted_upd;
+logic                               wfi_halted_ff;
+logic                               wfi_halted_next;
+
+// PC signals
+//------------------------------------------------------------------------------
+logic [3:0]                         init_pc_v;
+logic                               init_pc;
+logic [`SCR1_XLEN-1:0]              inc_pc;
+
+logic                               branch_taken;
+logic                               jb_taken;
+logic [`SCR1_XLEN-1:0]              jb_new_pc;
+`ifndef SCR1_RVC_EXT
+logic                               jb_misalign;
+`endif
+
+// Current PC register
+logic                               pc_curr_upd;
+logic [`SCR1_XLEN-1:0]              pc_curr_ff;
+logic [`SCR1_XLEN-1:0]              pc_curr_next;
+
+// LSU signals
+//------------------------------------------------------------------------------
+logic                               lsu_req;
+logic                               lsu_rdy;
+logic [`SCR1_XLEN-1:0]              lsu_l_data;
+logic                               lsu_exc_req;
+type_scr1_exc_code_e                lsu_exc_code;
+
+// EXU status signals
+//------------------------------------------------------------------------------
+logic                               exu_rdy;
+
+// MPRF signals
+//------------------------------------------------------------------------------
+logic                               mprf_rs1_req;
+logic                               mprf_rs2_req;
+
+logic   [`SCR1_MPRF_AWIDTH-1:0]     mprf_rs1_addr;
+logic   [`SCR1_MPRF_AWIDTH-1:0]     mprf_rs2_addr;
+
+// CSR signals
+//------------------------------------------------------------------------------
+// CSR access register
+scr1_csr_access_e                   csr_access_ff;
+scr1_csr_access_e                   csr_access_next;
+logic                               csr_access_init;
+
+//------------------------------------------------------------------------------
+// Instruction execution queue
+//------------------------------------------------------------------------------
+//
+ // Instruction execution queue consists of the following functional units:
+ // - EXU queue control logic
+ // - EXU queue valid flag register
+ // - EXU queue register
+ // - EXU queue status logic
+//
+
+`ifdef SCR1_DBG_EN
+assign dbg_run_start_npbuf = hdu2exu_dbg_run_start_i & ~hdu2exu_pbuf_fetch_i;
+`endif // SCR1_DBG_EN
+
+`ifndef SCR1_NO_EXE_STAGE
+
+// EXU queue control logic
+//------------------------------------------------------------------------------
+
+assign exu_queue_barrier = wfi_halted_ff | wfi_halt_req | wfi_run_start_ff
+`ifdef SCR1_DBG_EN
+                         | hdu2exu_dbg_halted_i  | hdu2exu_dbg_run2halt_i
+                         | dbg_run_start_npbuf
+`endif // SCR1_DBG_EN
+;
+
+assign exu_queue_en = exu2idu_rdy_o & idu2exu_req_i;
+
+// EXU queue valid flag register
+//------------------------------------------------------------------------------
+
+assign exu_queue_vd_upd = exu_queue_barrier | exu_rdy;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        exu_queue_vd_ff <= 1'b0;
+    end else if (exu_queue_vd_upd) begin
+        exu_queue_vd_ff <= exu_queue_vd_next;
+    end
+end
+
+assign exu_queue_vd_next = ~exu_queue_barrier & idu2exu_req_i & ~exu2ifu_pc_new_req_o;
+assign exu_queue_vd      = exu_queue_vd_ff;
+
+// EXU queue register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (exu_queue_en) begin
+        exu_queue.instr_rvc      <= idu2exu_cmd_i.instr_rvc;
+        exu_queue.ialu_op        <= idu2exu_cmd_i.ialu_op;
+        exu_queue.ialu_cmd       <= idu2exu_cmd_i.ialu_cmd;
+        exu_queue.sum2_op        <= idu2exu_cmd_i.sum2_op;
+        exu_queue.lsu_cmd        <= idu2exu_cmd_i.lsu_cmd;
+        exu_queue.csr_op         <= idu2exu_cmd_i.csr_op;
+        exu_queue.csr_cmd        <= idu2exu_cmd_i.csr_cmd;
+        exu_queue.rd_wb_sel      <= idu2exu_cmd_i.rd_wb_sel;
+        exu_queue.jump_req       <= idu2exu_cmd_i.jump_req;
+        exu_queue.branch_req     <= idu2exu_cmd_i.branch_req;
+        exu_queue.mret_req       <= idu2exu_cmd_i.mret_req;
+        exu_queue.fencei_req     <= idu2exu_cmd_i.fencei_req;
+        exu_queue.wfi_req        <= idu2exu_cmd_i.wfi_req;
+        exu_queue.exc_req        <= idu2exu_cmd_i.exc_req;
+        exu_queue.exc_code       <= idu2exu_cmd_i.exc_code;
+        idu2exu_use_rs1_ff       <= idu2exu_use_rs1_i;
+        idu2exu_use_rs2_ff       <= idu2exu_use_rs2_i;
+        if (idu2exu_use_rs1_i) begin
+            exu_queue.rs1_addr   <= idu2exu_cmd_i.rs1_addr;
+        end
+        if (idu2exu_use_rs2_i) begin
+            exu_queue.rs2_addr   <= idu2exu_cmd_i.rs2_addr;
+        end
+        if (idu2exu_use_rd_i)  begin
+            exu_queue.rd_addr    <= idu2exu_cmd_i.rd_addr;
+        end
+        if (idu2exu_use_imm_i) begin
+            exu_queue.imm        <= idu2exu_cmd_i.imm;
+        end
+    end
+end
+
+`else // ~SCR1_NO_EXE_STAGE
+
+assign exu_queue_barrier = wfi_halted_ff | wfi_run_start_ff
+`ifdef SCR1_DBG_EN
+                         | hdu2exu_dbg_halted_i  | dbg_run_start_npbuf
+`endif // SCR1_DBG_EN
+;
+assign exu_queue_vd  = idu2exu_req_i & ~exu_queue_barrier;
+assign exu_queue     = idu2exu_cmd_i;
+
+`endif // ~SCR1_NO_EXE_STAGE
+
+//------------------------------------------------------------------------------
+// Integer Arithmetic Logic Unit (IALU)
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Performs addition/subtraction and arithmetic and branch comparisons
+ // - Performs logical operations (AND(I), OR(I), XOR(I))
+ // - Performs address calculation for branch, jump, DMEM load and store and AUIPC
+ //   instructions
+ // - Performs shift operations
+ // - Performs MUL/DIV operations
+ //
+//------------------------------------------------------------------------------
+
+// IALU main operands fetch
+//------------------------------------------------------------------------------
+
+`ifdef SCR1_RVM_EXT
+assign ialu_vd  = exu_queue_vd & (exu_queue.ialu_cmd != SCR1_IALU_CMD_NONE)
+`ifdef SCR1_TDU_EN
+                & ~tdu2exu_ibrkpt_exc_req_i
+`endif // SCR1_TDU_EN
+                ;
+`endif // SCR1_RVM_EXT
+
+always_comb begin
+`ifdef SCR1_RVM_EXT
+    if (~ialu_vd) begin
+        ialu_main_op1 = '0;
+        ialu_main_op2 = '0;
+    end else begin
+`endif // SCR1_RVM_EXT
+        if (exu_queue.ialu_op == SCR1_IALU_OP_REG_REG) begin
+            ialu_main_op1 = mprf2exu_rs1_data_i;
+            ialu_main_op2 = mprf2exu_rs2_data_i;
+        end else begin
+            ialu_main_op1 = mprf2exu_rs1_data_i;
+            ialu_main_op2 = exu_queue.imm;
+        end
+`ifdef SCR1_RVM_EXT
+    end
+`endif // SCR1_RVM_EXT
+end
+
+// IALU address operands fetch
+//------------------------------------------------------------------------------
+
+always_comb begin
+    if (exu_queue.sum2_op == SCR1_SUM2_OP_REG_IMM) begin
+        ialu_addr_op1 = mprf2exu_rs1_data_i;
+        ialu_addr_op2 = exu_queue.imm;
+    end else begin
+        ialu_addr_op1 = pc_curr_ff;
+        ialu_addr_op2 = exu_queue.imm;
+    end
+end
+
+// IALU module instantiation
+//------------------------------------------------------------------------------
+
+scr1_pipe_ialu i_ialu(
+`ifdef SCR1_RVM_EXT
+    // Common
+    .clk                        (clk               ),
+    .rst_n                      (rst_n             ),
+    .exu2ialu_rvm_cmd_vd_i      (ialu_vd           ),
+    .ialu2exu_rvm_res_rdy_o     (ialu_rdy          ),
+`endif // SCR1_RVM_EXT
+
+    // IALU
+    .exu2ialu_main_op1_i        (ialu_main_op1     ),
+    .exu2ialu_main_op2_i        (ialu_main_op2     ),
+    .exu2ialu_cmd_i             (exu_queue.ialu_cmd),
+    .ialu2exu_main_res_o        (ialu_main_res     ),
+    .ialu2exu_cmp_res_o         (ialu_cmp          ),
+
+    // Address adder signals
+    .exu2ialu_addr_op1_i        (ialu_addr_op1     ),
+    .exu2ialu_addr_op2_i        (ialu_addr_op2     ),
+    .ialu2exu_addr_res_o        (ialu_addr_res     )
+);
+
+//------------------------------------------------------------------------------
+// Exceptions logic
+//------------------------------------------------------------------------------
+//
+ // Exceptions logic consists of the following functional units:
+ // - Exception request logic
+ // - Exception code encoder
+ // - Exception trap value multiplexer
+ //
+//
+
+`ifndef SCR1_RVC_EXT
+assign jb_misalign  = exu_queue_vd  & jb_taken & |jb_new_pc[1:0];
+`endif // ~SCR1_RVC_EXT
+
+// Exception request
+assign exu_exc_req  = exu_queue_vd & (exu_queue.exc_req | lsu_exc_req
+                                                        | csr2exu_rw_exc_i
+`ifndef SCR1_RVC_EXT
+                                                        | jb_misalign
+`endif // ~SCR1_RVC_EXT
+`ifdef SCR1_TDU_EN
+                                                        | exu2hdu_ibrkpt_hw_o
+`endif // SCR1_TDU_EN
+                                                        );
+
+// EXU exception request register
+//------------------------------------------------------------------------------
+
+`ifdef SCR1_DBG_EN
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        exu_exc_req_ff <= 1'b0;
+    end else begin
+        exu_exc_req_ff <= exu_exc_req_next;
+    end
+end
+
+assign exu_exc_req_next = hdu2exu_dbg_halt2run_i ? 1'b0 : exu_exc_req;
+`endif // SCR1_DBG_EN
+
+// Exception code encoder
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (1'b1)
+`ifdef SCR1_TDU_EN
+        exu2hdu_ibrkpt_hw_o: exc_code = SCR1_EXC_CODE_BREAKPOINT;
+`endif // SCR1_TDU_EN
+        exu_queue.exc_req  : exc_code = exu_queue.exc_code;
+        lsu_exc_req        : exc_code = lsu_exc_code;
+        csr2exu_rw_exc_i   : exc_code = SCR1_EXC_CODE_ILLEGAL_INSTR;
+`ifndef SCR1_RVC_EXT
+        jb_misalign        : exc_code = SCR1_EXC_CODE_INSTR_MISALIGN;
+`endif // ~SCR1_RVC_EXT
+        default            : exc_code = SCR1_EXC_CODE_ECALL_M;
+    endcase // 1'b1
+end
+
+// Exception trap value multiplexer
+//------------------------------------------------------------------------------
+
+assign instr_fault_rvi_hi = exu_queue.instr_rvc;
+assign exu_illegal_instr = {exu2csr_rw_addr_o,          // CSR address
+                            5'(exu_queue.rs1_addr),     // rs1 / zimm
+                            exu_queue.imm[14:12],       // funct3
+                            5'(exu_queue.rd_addr),      // rd
+                            SCR1_OPCODE_SYSTEM,
+                            SCR1_INSTR_RVI
+                           };
+
+// If Instruction Access Fault occurred on high part of RVI instruction trap
+// value is set to point on the high part of the instruction (inc_pc=pc+2)
+always_comb begin
+    case (exc_code)
+`ifndef SCR1_RVC_EXT
+        SCR1_EXC_CODE_INSTR_MISALIGN    : exc_trap_val = jb_new_pc;
+`endif // SCR1_RVC_EXT
+        SCR1_EXC_CODE_INSTR_ACCESS_FAULT: exc_trap_val = instr_fault_rvi_hi
+                                                       ? inc_pc
+                                                       : pc_curr_ff;
+`ifdef SCR1_MTVAL_ILLEGAL_INSTR_EN
+        SCR1_EXC_CODE_ILLEGAL_INSTR     : exc_trap_val = exu_queue.exc_req
+                                                       ? exu_queue.imm
+                                                       : exu_illegal_instr;
+`else // SCR1_MTVAL_ILLEGAL_INSTR_EN
+        SCR1_EXC_CODE_ILLEGAL_INSTR     : exc_trap_val = '0;
+`endif // SCR1_MTVAL_ILLEGAL_INSTR_EN
+`ifdef SCR1_TDU_EN
+        SCR1_EXC_CODE_BREAKPOINT: begin
+            case (1'b1)
+                tdu2exu_ibrkpt_exc_req_i: exc_trap_val = pc_curr_ff;
+                tdu2lsu_dbrkpt_exc_req_i: exc_trap_val = ialu_addr_res;
+                default                 : exc_trap_val = '0;
+            endcase
+        end
+`endif // SCR1_TDU_EN
+        SCR1_EXC_CODE_LD_ADDR_MISALIGN,
+        SCR1_EXC_CODE_LD_ACCESS_FAULT,
+        SCR1_EXC_CODE_ST_ADDR_MISALIGN,
+        SCR1_EXC_CODE_ST_ACCESS_FAULT   : exc_trap_val = ialu_addr_res;
+        default                         : exc_trap_val = '0;
+    endcase // exc_code
+end
+
+//------------------------------------------------------------------------------
+// WFI logic
+//------------------------------------------------------------------------------
+//
+ // Wait for interrupt (WFI) logic consists of the following functional units:
+ // - WFI control logic
+ // - WFI Run Start register
+ // - WFI Halted flag register
+ // - WFI status signals
+//
+
+// WFI control logic
+//------------------------------------------------------------------------------
+
+assign wfi_halt_cond = ~csr2exu_ip_ie_i
+                     & ((exu_queue_vd & exu_queue.wfi_req) | wfi_run_start_ff)
+`ifdef SCR1_DBG_EN
+                     & ~hdu2exu_no_commit_i & ~hdu2exu_dmode_sstep_en_i & ~hdu2exu_dbg_run2halt_i
+`endif // SCR1_DBG_EN
+                     ;
+assign wfi_halt_req  = ~wfi_halted_ff & wfi_halt_cond;
+
+// HART will exit WFI halted state if the event that causes the HART to resume
+// execution occurs even if it doesn't cause an interrupt to be taken
+assign wfi_run_req   = wfi_halted_ff  & (csr2exu_ip_ie_i
+`ifdef SCR1_DBG_EN
+                                      | hdu2exu_dbg_halt2run_i
+`endif // SCR1_DBG_EN
+                                      );
+
+// WFI Run Start register
+//------------------------------------------------------------------------------
+
+`ifndef SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk) begin
+`else // SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk_alw_on) begin
+`endif // SCR1_CLKCTRL_EN
+    if (~rst_n) begin
+        wfi_run_start_ff <= 1'b0;
+    end else begin
+        wfi_run_start_ff <= wfi_run_start_next;
+    end
+end
+
+assign wfi_run_start_next = wfi_halted_ff & csr2exu_ip_ie_i & ~exu2csr_take_irq_o;
+
+// WFI halted flag register
+//------------------------------------------------------------------------------
+
+assign wfi_halted_upd = wfi_halt_req | wfi_run_req;
+
+`ifndef SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk) begin
+`else // SCR1_CLKCTRL_EN
+always_ff @(negedge rst_n, posedge clk_alw_on) begin
+`endif // SCR1_CLKCTRL_EN
+    if (~rst_n) begin
+        wfi_halted_ff <= 1'b0;
+    end else if (wfi_halted_upd) begin
+        wfi_halted_ff <= wfi_halted_next;
+    end
+end
+
+assign wfi_halted_next = wfi_halt_req | ~wfi_run_req;
+
+// WFI status signals
+//------------------------------------------------------------------------------
+
+assign exu2pipe_wfi_run2halt_o = wfi_halt_req;
+`ifdef SCR1_CLKCTRL_EN
+assign exu2pipe_wfi_halted_o   = wfi_halted_ff;
+`endif // SCR1_CLKCTRL_EN
+
+//------------------------------------------------------------------------------
+// Program Counter logic
+//------------------------------------------------------------------------------
+//
+ // PC logic consists of the following functional units:
+ // - PC initialization logic
+ // - Current PC register
+ // - New PC multiplexer
+
+// PC initialization logic
+//------------------------------------------------------------------------------
+// Generates a New PC request to set PC to reset value
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        init_pc_v <= '0;
+    end else begin
+        if (~&init_pc_v) begin
+            init_pc_v <= {init_pc_v[2:0], 1'b1};
+        end
+    end
+end
+
+assign init_pc = ~init_pc_v[3] & init_pc_v[2];
+
+// Current PC register
+//------------------------------------------------------------------------------
+
+assign pc_curr_upd = ((exu2pipe_instret_o | exu2csr_take_irq_o
+`ifdef SCR1_DBG_EN
+                   | dbg_run_start_npbuf) & ( ~hdu2exu_pc_advmt_dsbl_i
+                                            & ~hdu2exu_no_commit_i
+`endif // SCR1_DBG_EN
+                   ));
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        pc_curr_ff <= SCR1_RST_VECTOR;
+    end else if (pc_curr_upd) begin
+        pc_curr_ff <= pc_curr_next;
+    end
+end
+
+`ifdef SCR1_RVC_EXT
+assign inc_pc = pc_curr_ff + (exu_queue.instr_rvc ? `SCR1_XLEN'd2 : `SCR1_XLEN'd4);
+`else // ~SCR1_RVC_EXT
+assign inc_pc = pc_curr_ff + `SCR1_XLEN'd4;
+`endif // ~SCR1_RVC_EXT
+
+assign pc_curr_next = exu2ifu_pc_new_req_o        ? exu2ifu_pc_new_o
+                    : (inc_pc[6] ^ pc_curr_ff[6]) ? inc_pc
+                                                  : {pc_curr_ff[`SCR1_XLEN-1:6], inc_pc[5:0]};
+
+// New PC multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (1'b1)
+        init_pc             : exu2ifu_pc_new_o = SCR1_RST_VECTOR;
+        exu2csr_take_exc_o,
+        exu2csr_take_irq_o,
+        exu2csr_mret_instr_o: exu2ifu_pc_new_o = csr2exu_new_pc_i;
+`ifdef SCR1_DBG_EN
+        dbg_run_start_npbuf : exu2ifu_pc_new_o = hdu2exu_dbg_new_pc_i;
+`endif // SCR1_DBG_EN
+        wfi_run_start_ff    : exu2ifu_pc_new_o = pc_curr_ff;
+        exu_queue.fencei_req: exu2ifu_pc_new_o = inc_pc;
+        default             : exu2ifu_pc_new_o = ialu_addr_res & SCR1_JUMP_MASK;
+    endcase
+end
+
+assign exu2ifu_pc_new_req_o = init_pc                                        // reset
+                            | exu2csr_take_irq_o
+                            | exu2csr_take_exc_o
+                            | (exu2csr_mret_instr_o & ~csr2exu_mstatus_mie_up_i)
+                            | (exu_queue_vd & exu_queue.fencei_req)
+                            | (wfi_run_start_ff
+`ifdef SCR1_CLKCTRL_EN
+                            & clk_pipe_en
+`endif // SCR1_CLKCTRL_EN
+                            )
+`ifdef SCR1_DBG_EN
+                            | dbg_run_start_npbuf
+`endif // SCR1_DBG_EN
+                            | (exu_queue_vd & jb_taken);
+
+// Jump/branch signals
+assign branch_taken = exu_queue.branch_req & ialu_cmp;
+assign jb_taken     = exu_queue.jump_req | branch_taken;
+assign jb_new_pc    = ialu_addr_res & SCR1_JUMP_MASK;
+
+// PC to be loaded on MRET from interrupt trap
+assign exu2csr_pc_next_o  = ~exu_queue_vd ? pc_curr_ff
+                          : jb_taken      ? jb_new_pc
+                                          : inc_pc;
+assign exu2pipe_pc_curr_o = pc_curr_ff;
+
+//------------------------------------------------------------------------------
+// Load/Store Unit (LSU)
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Performs load and store operations in Data Memory
+ // - Generates DMEM address misalign and access fault exceptions
+ // - Passes DMEM operations information to TDU and generates LSU breakpoint exception
+ //
+//------------------------------------------------------------------------------
+
+assign lsu_req  = ((exu_queue.lsu_cmd != SCR1_LSU_CMD_NONE) & exu_queue_vd);
+
+scr1_pipe_lsu i_lsu(
+    .rst_n                      (rst_n                   ),
+    .clk                        (clk                     ),
+
+    // EXU <-> LSU interface
+    .exu2lsu_req_i              (lsu_req                 ),       // Request to LSU
+    .exu2lsu_cmd_i              (exu_queue.lsu_cmd       ),       // LSU command
+    .exu2lsu_addr_i             (ialu_addr_res           ),       // DMEM address
+    .exu2lsu_sdata_i            (mprf2exu_rs2_data_i     ),       // Data for store to DMEM
+    .lsu2exu_rdy_o              (lsu_rdy                 ),       // LSU ready
+    .lsu2exu_ldata_o            (lsu_l_data              ),       // Loaded data form DMEM
+    .lsu2exu_exc_o              (lsu_exc_req             ),       // LSU exception
+    .lsu2exu_exc_code_o         (lsu_exc_code            ),       // LSU exception code
+
+`ifdef SCR1_TDU_EN
+    // TDU <-> LSU interface
+    .lsu2tdu_dmon_o             (lsu2tdu_dmon_o          ),
+    .tdu2lsu_ibrkpt_exc_req_i   (tdu2lsu_ibrkpt_exc_req_i),
+    .tdu2lsu_dbrkpt_exc_req_i   (tdu2lsu_dbrkpt_exc_req_i),
+`endif // SCR1_TDU_EN
+
+    // Data memory interface
+    .lsu2dmem_req_o             (exu2dmem_req_o          ),       // DMEM request
+    .lsu2dmem_cmd_o             (exu2dmem_cmd_o          ),       // DMEM command
+    .lsu2dmem_width_o           (exu2dmem_width_o        ),       // DMEM width
+    .lsu2dmem_addr_o            (exu2dmem_addr_o         ),       // DMEM address
+    .lsu2dmem_wdata_o           (exu2dmem_wdata_o        ),       // DMEM write data
+    .dmem2lsu_req_ack_i         (dmem2exu_req_ack_i      ),       // DMEM request acknowledge
+    .dmem2lsu_rdata_i           (dmem2exu_rdata_i        ),       // DMEM read data
+    .dmem2lsu_resp_i            (dmem2exu_resp_i         )        // DMEM response
+);
+
+//------------------------------------------------------------------------------
+// EXU status logic
+//------------------------------------------------------------------------------
+
+// EXU ready flag
+always_comb begin
+    case (1'b1)
+        lsu_req                 : exu_rdy = lsu_rdy | lsu_exc_req;
+`ifdef SCR1_RVM_EXT
+        ialu_vd                 : exu_rdy = ialu_rdy;
+`endif // SCR1_RVM_EXT
+        csr2exu_mstatus_mie_up_i: exu_rdy = 1'b0;
+        default                 : exu_rdy = 1'b1;
+    endcase
+end
+
+assign exu2pipe_init_pc_o       = init_pc;
+assign exu2idu_rdy_o            = exu_rdy & ~exu_queue_barrier;
+assign exu2pipe_exu_busy_o      = exu_queue_vd & ~exu_rdy;
+assign exu2pipe_instret_o       = exu_queue_vd & exu_rdy;
+assign exu2csr_instret_no_exc_o = exu2pipe_instret_o & ~exu_exc_req;
+
+// Exceptions
+`ifdef SCR1_DBG_EN
+assign exu2pipe_exc_req_o  = exu_queue_vd ? exu_exc_req : exu_exc_req_ff;
+`else // SCR1_DBG_EN
+assign exu2pipe_exc_req_o  = exu_exc_req;
+`endif // SCR1_DBG_EN
+
+// Breakpoints
+assign exu2pipe_brkpt_o    = exu_queue_vd & (exu_queue.exc_code == SCR1_EXC_CODE_BREAKPOINT);
+`ifdef SCR1_TDU_EN
+assign exu2hdu_ibrkpt_hw_o = tdu2exu_ibrkpt_exc_req_i | tdu2lsu_dbrkpt_exc_req_i;
+`endif // SCR1_TDU_EN
+
+//------------------------------------------------------------------------------
+// EXU <-> MPRF interface
+//------------------------------------------------------------------------------
+
+// Operands fetching stage
+//------------------------------------------------------------------------------
+
+`ifdef  SCR1_NO_EXE_STAGE
+assign mprf_rs1_req = exu_queue_vd & idu2exu_use_rs1_i;
+assign mprf_rs2_req = exu_queue_vd & idu2exu_use_rs2_i;
+`else // SCR1_NO_EXE_STAGE
+ `ifdef  SCR1_MPRF_RAM
+assign mprf_rs1_req = exu_queue_en
+                    ? (exu_queue_vd_next & idu2exu_use_rs1_i)
+                    : (exu_queue_vd      & idu2exu_use_rs1_ff);
+assign mprf_rs2_req = exu_queue_en
+                    ? (exu_queue_vd_next & idu2exu_use_rs2_i)
+                    : (exu_queue_vd      & idu2exu_use_rs2_ff);
+ `else // SCR1_MPRF_RAM
+assign mprf_rs1_req = exu_queue_vd & idu2exu_use_rs1_ff;
+assign mprf_rs2_req = exu_queue_vd & idu2exu_use_rs2_ff;
+ `endif // SCR1_MPRF_RAM
+`endif // SCR1_NO_EXE_STAGE
+
+// If exu_queue isn't enabled we need previous addresses and usage flags because
+// RAM blocks read operation is SYNCHRONOUS
+`ifdef SCR1_MPRF_RAM
+assign mprf_rs1_addr = exu_queue_en ? idu2exu_cmd_i.rs1_addr : exu_queue.rs1_addr;
+assign mprf_rs2_addr = exu_queue_en ? idu2exu_cmd_i.rs2_addr : exu_queue.rs2_addr;
+`else // SCR1_MPRF_RAM
+assign mprf_rs1_addr = exu_queue.rs1_addr;
+assign mprf_rs2_addr = exu_queue.rs2_addr;
+`endif // SCR1_MPRF_RAM
+
+assign exu2mprf_rs1_addr_o = mprf_rs1_req ? `SCR1_MPRF_AWIDTH'(mprf_rs1_addr) : '0;
+assign exu2mprf_rs2_addr_o = mprf_rs2_req ? `SCR1_MPRF_AWIDTH'(mprf_rs2_addr) : '0;
+
+// Write back stage
+//------------------------------------------------------------------------------
+
+assign exu2mprf_w_req_o   = (exu_queue.rd_wb_sel != SCR1_RD_WB_NONE) & exu_queue_vd & ~exu_exc_req
+`ifdef SCR1_DBG_EN
+                          & ~hdu2exu_no_commit_i
+`endif // SCR1_DBG_EN
+                          & ((exu_queue.rd_wb_sel == SCR1_RD_WB_CSR) ? csr_access_init : exu_rdy);
+
+assign exu2mprf_rd_addr_o = `SCR1_MPRF_AWIDTH'(exu_queue.rd_addr);
+
+// MRPF RD data multiplexer
+always_comb begin
+    case (exu_queue.rd_wb_sel)
+        SCR1_RD_WB_SUM2  : exu2mprf_rd_data_o = ialu_addr_res;
+        SCR1_RD_WB_IMM   : exu2mprf_rd_data_o = exu_queue.imm;
+        SCR1_RD_WB_INC_PC: exu2mprf_rd_data_o = inc_pc;
+        SCR1_RD_WB_LSU   : exu2mprf_rd_data_o = lsu_l_data;
+        SCR1_RD_WB_CSR   : exu2mprf_rd_data_o = csr2exu_r_data_i;
+        default          : exu2mprf_rd_data_o = ialu_main_res;
+    endcase
+end
+
+//------------------------------------------------------------------------------
+// EXU <-> CSR interface
+//------------------------------------------------------------------------------
+//
+ // EXU <-> CSR interface consists of the following functional units:
+ // - CSR write/read interface
+ // - CSR access FSM
+ // - CSR events interface:
+ //   - Exceptions signals
+ //   - Interrupts signals
+ //   - MRET signals
+//
+
+// CSRs write/read interface
+//------------------------------------------------------------------------------
+
+// CSR write/read request signals calculation
+always_comb begin
+    if (~exu_queue_vd
+`ifdef SCR1_TDU_EN
+       | tdu2exu_ibrkpt_exc_req_i
+`endif // SCR1_TDU_EN
+    ) begin
+        exu2csr_r_req_o = 1'b0;
+        exu2csr_w_req_o = 1'b0;
+    end else begin
+        case (exu_queue.csr_cmd)
+            SCR1_CSR_CMD_WRITE  : begin
+                exu2csr_r_req_o = |exu_queue.rd_addr;
+                exu2csr_w_req_o = csr_access_init;
+            end
+            SCR1_CSR_CMD_SET,
+            SCR1_CSR_CMD_CLEAR  : begin
+                exu2csr_r_req_o = 1'b1;
+                exu2csr_w_req_o = |exu_queue.rs1_addr & csr_access_init;
+            end
+            default : begin
+                exu2csr_r_req_o = 1'b0;
+                exu2csr_w_req_o = 1'b0;
+            end
+        endcase
+    end
+end
+
+assign exu2csr_w_cmd_o   = exu_queue.csr_cmd;
+assign exu2csr_rw_addr_o = exu_queue.imm[SCR1_CSR_ADDR_WIDTH-1:0];
+assign exu2csr_w_data_o  = (exu_queue.csr_op == SCR1_CSR_OP_REG)
+                         ? mprf2exu_rs1_data_i
+                         : {'0, exu_queue.rs1_addr}; // zimm
+
+
+// CSR access FSM
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        csr_access_ff <= SCR1_CSR_INIT;
+    end else begin
+        csr_access_ff <= csr_access_next;
+    end
+end
+
+assign csr_access_next = (csr_access_init & csr2exu_mstatus_mie_up_i)
+                       ? SCR1_CSR_RDY
+                       : SCR1_CSR_INIT;
+
+assign csr_access_init = (csr_access_ff == SCR1_CSR_INIT);
+
+// CSR events interface
+//------------------------------------------------------------------------------
+
+// Exceptions signals
+assign exu2csr_take_exc_o = exu_exc_req
+`ifdef SCR1_DBG_EN
+                          & ~hdu2exu_dbg_halted_i
+`endif // SCR1_DBG_EN
+                          ;
+assign exu2csr_exc_code_o = exc_code;
+assign exu2csr_trap_val_o = exc_trap_val;
+
+// Interrupts signals
+assign exu2csr_take_irq_o = csr2exu_irq_i & ~exu2pipe_exu_busy_o
+`ifdef SCR1_DBG_EN
+                          & ~hdu2exu_irq_dsbl_i
+                          & ~hdu2exu_dbg_halted_i
+`endif // SCR1_DBG_EN
+`ifdef SCR1_CLKCTRL_EN
+                          & clk_pipe_en
+`endif // SCR1_CLKCTRL_EN
+                          ;
+
+// MRET signals
+// MRET instruction flag
+assign exu2csr_mret_instr_o  = exu_queue_vd & exu_queue.mret_req
+`ifdef SCR1_TDU_EN
+                             & ~tdu2exu_ibrkpt_exc_req_i
+`endif // SCR1_TDU_EN
+`ifdef SCR1_DBG_EN
+                             & ~hdu2exu_dbg_halted_i
+`endif // SCR1_DBG_EN
+                             ;
+assign exu2csr_mret_update_o = exu2csr_mret_instr_o & csr_access_init;
+
+`ifdef SCR1_TDU_EN
+//------------------------------------------------------------------------------
+// EXU <-> TDU interface
+//------------------------------------------------------------------------------
+
+// Instruction monitor
+assign exu2tdu_imon_o.vd    = exu_queue_vd;
+assign exu2tdu_imon_o.req   = exu2pipe_instret_o;
+assign exu2tdu_imon_o.addr  = pc_curr_ff;
+
+always_comb begin
+    exu2tdu_ibrkpt_ret_o = '0;
+    if (exu_queue_vd) begin
+        exu2tdu_ibrkpt_ret_o = tdu2exu_ibrkpt_match_i;
+        if (lsu_req) begin
+            exu2tdu_ibrkpt_ret_o[SCR1_TDU_MTRIG_NUM-1:0] |= tdu2lsu_dbrkpt_match_i;
+        end
+    end
+end
+`endif // SCR1_TDU_EN
+
+
+`ifdef SCR1_TRGT_SIMULATION
+//------------------------------------------------------------------------------
+// Tracelog signals
+//------------------------------------------------------------------------------
+
+logic [`SCR1_XLEN-1:0]      update_pc;
+logic                       update_pc_en;
+
+assign update_pc_en = (init_pc | exu2pipe_instret_o | exu2csr_take_irq_o)
+`ifdef SCR1_DBG_EN
+                    & ~hdu2exu_pc_advmt_dsbl_i & ~hdu2exu_no_commit_i
+`endif // SCR1_DBG_EN
+                    ;
+assign update_pc    = exu2ifu_pc_new_req_o ? exu2ifu_pc_new_o : inc_pc;
+
+
+//------------------------------------------------------------------------------
+// Assertion
+//------------------------------------------------------------------------------
+
+// X checks
+
+SCR1_SVA_EXU_XCHECK_CTRL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({idu2exu_req_i, csr2exu_irq_i, csr2exu_ip_ie_i, lsu_req, lsu_rdy, exu_exc_req})
+    ) else $error("EXU Error: unknown control values");
+
+SCR1_SVA_EXU_XCHECK_QUEUE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    idu2exu_req_i |-> !$isunknown(idu2exu_cmd_i)
+    ) else $error("EXU Error: unknown values in queue");
+
+SCR1_SVA_EXU_XCHECK_CSR_RDATA : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2csr_r_req_o |-> !$isunknown({csr2exu_r_data_i, csr2exu_rw_exc_i})
+    ) else $error("EXU Error: unknown values from CSR");
+
+// Behavior checks
+
+SCR1_SVA_EXU_ONEHOT : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    $onehot0({exu_queue.jump_req, exu_queue.branch_req, lsu_req})
+    ) else $error("EXU Error: illegal combination of control signals");
+
+SCR1_SVA_EXU_ONEHOT_EXC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu_queue_vd |->
+    $onehot0({exu_queue.exc_req, lsu_exc_req, csr2exu_rw_exc_i
+`ifndef SCR1_RVC_EXT
+    , jb_misalign
+`endif
+    })
+    ) else $error("EXU Error: exceptions $onehot0 failed");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_exu
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_hdu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_hdu.sv
new file mode 100644
index 0000000..14f421b
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_hdu.sv
@@ -0,0 +1,904 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_pipe_hdu.sv>
+/// @brief      HART Debug Unit (HDU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ //
+ // Functionality:
+ // - Controls HART state (RUN, Debug RUN, Debug HALTED)
+ // - Setups Debug Mode execution
+ // - Provides status information about Debug Mode execution
+ // - Provides Program Buffer functionality (a few instructions execution while
+ //   in Debug Mode)
+ // - Provides access to Debug CSRs
+ //
+ // Structure:
+ // - Debug state FSM
+ // - HART Control logic
+ // - HART Status logic
+ // - Program Buffer
+ // - Debug CSRs
+ // - HDU <-> DM interface
+ // - HDU <-> EXU interface
+ // - HDU <-> IFU interface
+ // - HDU <-> CSR interface
+ // - HDU <-> TDU interface
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_arch_types.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_hdu.svh"
+
+module scr1_pipe_hdu #(parameter HART_PBUF_INSTR_REGOUT_EN = 1'b1) (
+    // Common signals
+    input  logic                                        rst_n,                      // HDU reset
+    input  logic                                        clk,                        // HDU clock
+    input  logic                                        clk_en,                     // HDU clock enable
+`ifdef SCR1_CLKCTRL_EN
+    input   logic                                       clk_pipe_en,                // Pipeline clock enable
+`endif // SCR1_CLKCTRL_EN
+    input  logic                                        pipe2hdu_rdc_qlfy_i,        // Pipeline RDC qualifier
+
+    // HDU <-> CSR i/f
+    input  logic                                        csr2hdu_req_i,              // CSR i/f request
+    input  type_scr1_csr_cmd_sel_e                      csr2hdu_cmd_i,              // CSR i/f command
+    input  logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0]     csr2hdu_addr_i,             // CSR i/f address
+    input  logic [`SCR1_XLEN-1:0]                       csr2hdu_wdata_i,            // CSR i/f write data
+    output type_scr1_csr_resp_e                         hdu2csr_resp_o,             // CSR i/f response
+    output logic [`SCR1_XLEN-1:0]                       hdu2csr_rdata_o,            // CSR i/f read data
+
+    // HDU <-> DM i/f
+    // HART Run Control i/f
+    input  logic                                        dm2hdu_cmd_req_i,           // DM-HART Command request
+    input  type_scr1_hdu_dbgstates_e                    dm2hdu_cmd_i,               // DM-HART Command
+    output logic                                        hdu2dm_cmd_resp_o,          // DM-HART Command response
+    output logic                                        hdu2dm_cmd_rcode_o,         // DM-HART Command return code: 0 - Ok; 1 - Error
+    output logic                                        hdu2dm_hart_event_o,        // DM-HART Event: 1 if HART debug state changed
+    output type_scr1_hdu_hartstatus_s                   hdu2dm_hart_status_o,       // DM-HART Status
+
+    // Program Buffer i/f
+    output logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]         hdu2dm_pbuf_addr_o,         // Program Buffer address - so far request only for 1 instruction
+    input  logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]        dm2hdu_pbuf_instr_i,        // Program Buffer instruction
+
+    // HART Abstract Data regs i/f
+    output logic                                        hdu2dm_dreg_req_o,          // Abstract Data Register request
+    output logic                                        hdu2dm_dreg_wr_o,           // Abstract Data Register write
+    output logic [`SCR1_XLEN-1:0]                       hdu2dm_dreg_wdata_o,        // Abstract Data Register write data
+    input  logic                                        dm2hdu_dreg_resp_i,         // Abstract Data Register response
+    input  logic                                        dm2hdu_dreg_fail_i,         // Abstract Data Register fail
+    input  logic [`SCR1_XLEN-1:0]                       dm2hdu_dreg_rdata_i,        // Abstract Data Register read data
+
+`ifdef SCR1_TDU_EN
+    // HDU <-> TDU interface
+    output  logic                                       hdu2tdu_hwbrk_dsbl_o,       // Disables BRKM
+    input   logic                                       tdu2hdu_dmode_req_i,        // Trigger Module requests transition to debug mode
+    input   logic                                       exu2hdu_ibrkpt_hw_i,        // Hardware breakpoint on current instruction
+`endif // SCR1_TDU_EN
+
+    // HART Run Status
+    input   logic                                       pipe2hdu_exu_busy_i,        // EXU busy
+    input   logic                                       pipe2hdu_instret_i,         // Instruction retired (with or without exception)
+    input   logic                                       pipe2hdu_init_pc_i,         // Reset exit
+
+    // HART Halt Status
+    input   logic                                       pipe2hdu_exu_exc_req_i,     // Exception request
+    input   logic                                       pipe2hdu_brkpt_i,           // Software Breakpoint (EBREAK)
+
+    // HDU <-> EXU i/f
+    // HART Run Control
+    output  logic                                       hdu2exu_pbuf_fetch_o,       // Fetch instruction from Program Buffer
+    output  logic                                       hdu2exu_no_commit_o,        // Forbid instruction commitment
+    output  logic                                       hdu2exu_irq_dsbl_o,         // Disable IRQ
+    output  logic                                       hdu2exu_pc_advmt_dsbl_o,    // Forbid PC advancement
+    output  logic                                       hdu2exu_dmode_sstep_en_o,   // Enable single-step
+
+    // HART state
+    output  logic                                       hdu2exu_dbg_halted_o,       // Debug halted state
+    output  logic                                       hdu2exu_dbg_run2halt_o,     // Transition to debug halted state
+    output  logic                                       hdu2exu_dbg_halt2run_o,     // Transition to run state
+    output  logic                                       hdu2exu_dbg_run_start_o,    // First cycle of run state
+
+    // PC interface
+    input  logic [`SCR1_XLEN-1:0]                       pipe2hdu_pc_curr_i,         // Current PC
+    output logic [`SCR1_XLEN-1:0]                       hdu2exu_dbg_new_pc_o,       // New PC for resume
+
+    // HDU <-> IFU i/f
+    // Program Buffer Instruction interface
+    input   logic                                       ifu2hdu_pbuf_instr_rdy_i,   // Program Buffer Instruction i/f ready
+    output  logic                                       hdu2ifu_pbuf_instr_vd_o,    // Program Buffer Instruction valid
+    output  logic                                       hdu2ifu_pbuf_instr_err_o,   // Program Buffer Instruction i/f error
+    output  logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]       hdu2ifu_pbuf_instr_o        // Program Buffer Instruction itself
+);
+
+//------------------------------------------------------------------------------
+// Local Parameters
+//------------------------------------------------------------------------------
+
+localparam int unsigned SCR1_HDU_TIMEOUT       = 64;       // must be power of 2
+localparam int unsigned SCR1_HDU_TIMEOUT_WIDTH = $clog2(SCR1_HDU_TIMEOUT);
+
+//------------------------------------------------------------------------------
+// Local Signals
+//------------------------------------------------------------------------------
+
+// Debug FSM
+//------------------------------------------------------------------------------
+
+// FSM control signals
+logic                                               dm_dhalt_req;
+logic                                               dm_run_req;
+
+logic                                               dm_cmd_run;
+logic                                               dm_cmd_dhalted;
+logic                                               dm_cmd_drun;
+
+// Debug state FSM signals
+type_scr1_hdu_dbgstates_e                           dbg_state;
+type_scr1_hdu_dbgstates_e                           dbg_state_next;
+logic                                               dbg_state_dhalted;
+logic                                               dbg_state_drun;
+logic                                               dbg_state_run;
+logic                                               dbg_state_reset;
+
+// FSM transition, update and event registers
+logic                                               dfsm_trans;
+logic                                               dfsm_trans_next;
+logic                                               dfsm_update;
+logic                                               dfsm_update_next;
+logic                                               dfsm_event;
+logic                                               dfsm_event_next;
+
+// HART Control signals
+//------------------------------------------------------------------------------
+
+logic                                               hart_resume_req;
+logic                                               hart_halt_req;
+logic                                               hart_cmd_req;
+
+// HART Run Control register
+logic                                               hart_runctrl_upd;
+logic                                               hart_runctrl_clr;
+type_scr1_hdu_runctrl_s                             hart_runctrl;
+
+// HART halt request timeout counter signals
+logic [SCR1_HDU_TIMEOUT_WIDTH-1:0]                  halt_req_timeout_cnt;
+logic [SCR1_HDU_TIMEOUT_WIDTH-1:0]                  halt_req_timeout_cnt_next;
+logic                                               halt_req_timeout_cnt_en;
+logic                                               halt_req_timeout_flag;
+
+// HART Status signals
+//------------------------------------------------------------------------------
+
+type_scr1_hdu_haltstatus_s                          hart_haltstatus;
+type_scr1_hdu_haltcause_e                           hart_haltcause;
+
+logic                                               hart_halt_pnd;
+logic                                               hart_halt_ack;
+
+// Debug mode cause decoder signals
+logic                                               dmode_cause_sstep;
+logic                                               dmode_cause_except;
+logic                                               dmode_cause_ebreak;
+logic                                               dmode_cause_any;
+`ifdef SCR1_TDU_EN
+logic                                               dmode_cause_tmreq;
+`endif // SCR1_TDU_EN
+
+// Program Buffer FSM
+//------------------------------------------------------------------------------
+
+// PBUF FSM control signals
+logic                                               ifu_handshake_done;
+logic                                               pbuf_exc_inj_req;
+logic                                               pbuf_exc_inj_end;
+logic                                               pbuf_start_fetch;
+
+// PBUF FSM signals
+type_scr1_hdu_pbufstates_e                          pbuf_fsm_curr;
+type_scr1_hdu_pbufstates_e                          pbuf_fsm_next;
+logic                                               pbuf_fsm_idle;
+logic                                               pbuf_fsm_fetch;
+logic                                               pbuf_fsm_excinj;
+
+// PBUF address signals
+logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]                pbuf_addr_ff;
+logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]                pbuf_addr_next;
+logic                                               pbuf_addr_end;
+logic                                               pbuf_addr_next_vd;
+
+logic                                               pbuf_instr_wait_latching;
+
+// Debugs CSRs
+//------------------------------------------------------------------------------
+
+// CSRs write/read interface signals
+logic                                               csr_upd_on_halt;
+logic                                               csr_wr;
+logic [`SCR1_XLEN-1:0]                              csr_wr_data;
+logic [`SCR1_XLEN-1:0]                              csr_rd_data;
+
+// Debug Control and Status register (DCSR)
+logic                                               csr_dcsr_sel;
+logic                                               csr_dcsr_wr;
+type_scr1_hdu_dcsr_s                                csr_dcsr_in;
+type_scr1_hdu_dcsr_s                                csr_dcsr_out;
+logic                                               csr_dcsr_ebreakm;
+logic                                               csr_dcsr_stepie;
+logic                                               csr_dcsr_step;
+logic [SCR1_HDU_DCSR_CAUSE_BIT_L-
+       SCR1_HDU_DCSR_CAUSE_BIT_R:0]                 csr_dcsr_cause;
+
+// Debug Program Counter register (DPC)
+logic                                               csr_dpc_sel;
+logic                                               csr_dpc_wr;
+logic [`SCR1_XLEN-1:0]                              csr_dpc_ff;
+logic [`SCR1_XLEN-1:0]                              csr_dpc_next;
+logic [`SCR1_XLEN-1:0]                              csr_dpc_out;
+
+// Debug Scratch register 0 (DSCRATCH0)
+logic                                               csr_addr_dscratch0;
+logic                                               csr_dscratch0_sel;
+logic                                               csr_dscratch0_wr;
+logic [`SCR1_XLEN-1:0]                              csr_dscratch0_out;
+type_scr1_csr_resp_e                                csr_dscratch0_resp;
+
+//------------------------------------------------------------------------------
+// Debug state FSM logic
+//------------------------------------------------------------------------------
+//
+ // Debug state FSM logic consists of the following functional units:
+ // - FSM control logic
+ // - Debug state FSM
+ // - FSM transition, update and event registers
+//
+
+// FSM control logic
+//------------------------------------------------------------------------------
+
+assign dm_cmd_dhalted = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_DHALTED);
+assign dm_cmd_run     = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_RUN);
+assign dm_cmd_drun    = (dm2hdu_cmd_i == SCR1_HDU_DBGSTATE_DRUN);
+
+assign dm_dhalt_req   = dm2hdu_cmd_req_i & dm_cmd_dhalted;
+assign dm_run_req     = dm2hdu_cmd_req_i & (dm_cmd_run | dm_cmd_drun);
+
+// Debug state FSM
+//------------------------------------------------------------------------------
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        dbg_state <= SCR1_HDU_DBGSTATE_RESET;
+    end else begin
+        dbg_state <= dbg_state_next;
+    end
+end
+
+always_comb begin
+    if (~pipe2hdu_rdc_qlfy_i) begin
+        dbg_state_next = SCR1_HDU_DBGSTATE_RESET;
+    end else begin
+        case (dbg_state)
+            SCR1_HDU_DBGSTATE_RESET: begin
+                dbg_state_next = ~pipe2hdu_init_pc_i ? SCR1_HDU_DBGSTATE_RESET
+                               : dm_dhalt_req        ? SCR1_HDU_DBGSTATE_DHALTED
+                                                     : SCR1_HDU_DBGSTATE_RUN;
+            end
+            SCR1_HDU_DBGSTATE_RUN: begin
+                dbg_state_next = dfsm_update         ? SCR1_HDU_DBGSTATE_DHALTED
+                                                     : SCR1_HDU_DBGSTATE_RUN;
+            end
+            SCR1_HDU_DBGSTATE_DHALTED: begin
+                dbg_state_next = ~dfsm_update        ? SCR1_HDU_DBGSTATE_DHALTED
+                               : dm_cmd_drun         ? SCR1_HDU_DBGSTATE_DRUN
+                                                     : SCR1_HDU_DBGSTATE_RUN;
+            end
+            SCR1_HDU_DBGSTATE_DRUN: begin
+                dbg_state_next = dfsm_update         ? SCR1_HDU_DBGSTATE_DHALTED
+                                                     : SCR1_HDU_DBGSTATE_DRUN;
+            end
+            default: begin
+`ifdef SCR1_XPROP_EN
+                dbg_state_next = SCR1_HDU_DBGSTATE_XXX;
+`else // SCR1_XPROP_EN
+                dbg_state_next = dbg_state;
+`endif // SCR1_XPROP_EN
+            end
+        endcase
+    end
+end
+
+assign dbg_state_dhalted = (dbg_state == SCR1_HDU_DBGSTATE_DHALTED);
+assign dbg_state_drun    = (dbg_state == SCR1_HDU_DBGSTATE_DRUN);
+assign dbg_state_run     = (dbg_state == SCR1_HDU_DBGSTATE_RUN);
+assign dbg_state_reset   = (dbg_state == SCR1_HDU_DBGSTATE_RESET);
+
+// FSM transition, update and event registers
+//------------------------------------------------------------------------------
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        dfsm_trans  <= 1'b0;
+        dfsm_update <= 1'b0;
+        dfsm_event  <= 1'b0;
+    end else begin
+        dfsm_trans  <= dfsm_trans_next;
+        dfsm_update <= dfsm_update_next;
+        dfsm_event  <= dfsm_event_next;
+    end
+end
+
+always_comb begin
+    dfsm_trans_next  = 1'b0;
+    dfsm_update_next = 1'b0;
+    dfsm_event_next  = 1'b0;
+
+    if (~pipe2hdu_rdc_qlfy_i) begin
+        dfsm_trans_next  = 1'b0;
+        dfsm_update_next = 1'b0;
+        dfsm_event_next  = 1'b1;
+    end else begin
+        case (dbg_state)
+            SCR1_HDU_DBGSTATE_RESET: begin
+                dfsm_trans_next  = 1'b0;
+                dfsm_update_next = 1'b0;
+                dfsm_event_next  = pipe2hdu_init_pc_i & ~dm2hdu_cmd_req_i;
+            end
+
+            SCR1_HDU_DBGSTATE_RUN,
+            SCR1_HDU_DBGSTATE_DRUN: begin
+                dfsm_trans_next  = ~dfsm_update ? hart_halt_pnd : dfsm_trans;
+                dfsm_update_next = ~dfsm_update & hart_halt_ack;
+                dfsm_event_next  = dfsm_update;
+            end
+
+            SCR1_HDU_DBGSTATE_DHALTED: begin
+                dfsm_trans_next  = ~dfsm_update ? ~dfsm_trans & dm_run_req
+                                                : dfsm_trans;
+                dfsm_update_next = ~dfsm_update & dfsm_trans;
+                dfsm_event_next  = dfsm_update;
+            end
+
+            default : begin
+                dfsm_trans_next  = 'X;
+                dfsm_update_next = 'X;
+                dfsm_event_next  = 'X;
+            end
+        endcase
+    end
+end
+
+//------------------------------------------------------------------------------
+// HART Control logic
+//------------------------------------------------------------------------------
+//
+ // HART Control logic consists of the following functional units:
+ // - Control signals
+ // - HART Run Control register
+ // - HART Halt Request Time-Out counter
+//
+
+// Control logic
+always_comb begin
+    hart_cmd_req = 1'b0;
+
+    if (~pipe2hdu_rdc_qlfy_i) begin
+        hart_cmd_req = 1'b0;
+    end else begin
+        case (dbg_state)
+            SCR1_HDU_DBGSTATE_RESET  : hart_cmd_req = dm2hdu_cmd_req_i;
+            SCR1_HDU_DBGSTATE_DHALTED: hart_cmd_req = (dfsm_update | dfsm_trans);
+            SCR1_HDU_DBGSTATE_RUN,
+            SCR1_HDU_DBGSTATE_DRUN   : hart_cmd_req = ~dfsm_update & dfsm_trans;
+            default                  : hart_cmd_req = 'X;
+        endcase
+    end
+end
+
+assign hart_halt_req   = dm_cmd_dhalted & hart_cmd_req;
+assign hart_resume_req = (dm_cmd_run | dm_cmd_drun) & hart_cmd_req;
+
+// HART Run Control register
+//------------------------------------------------------------------------------
+
+assign hart_runctrl_clr = (dbg_state_run | dbg_state_drun)
+                        & (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED);
+assign hart_runctrl_upd = dbg_state_dhalted & dfsm_trans_next;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        hart_runctrl.irq_dsbl      <= 1'b0;
+        hart_runctrl.fetch_src     <= SCR1_HDU_FETCH_SRC_NORMAL;
+        hart_runctrl.pc_advmt_dsbl <= 1'b0;
+        hart_runctrl.hwbrkpt_dsbl  <= 1'b0;
+        hart_runctrl.redirect      <= '0;
+    end else if(clk_en) begin
+        if (hart_runctrl_clr) begin
+            hart_runctrl           <= '0;
+        end else begin
+            if (hart_runctrl_upd) begin
+                if (~dm_cmd_drun) begin
+                    // Case : resume to RUN state
+                    hart_runctrl.irq_dsbl        <= csr_dcsr_step ? ~csr_dcsr_stepie : 1'b0;
+                    hart_runctrl.fetch_src       <= SCR1_HDU_FETCH_SRC_NORMAL;
+                    hart_runctrl.pc_advmt_dsbl   <= 1'b0;
+                    hart_runctrl.hwbrkpt_dsbl    <= 1'b0;
+                    hart_runctrl.redirect.sstep  <= csr_dcsr_step;
+                    hart_runctrl.redirect.ebreak <= csr_dcsr_ebreakm;
+                end else begin
+                    // Case : resume to DRUN state
+                    hart_runctrl.irq_dsbl        <= 1'b1;
+                    hart_runctrl.fetch_src       <= SCR1_HDU_FETCH_SRC_PBUF;
+                    hart_runctrl.pc_advmt_dsbl   <= 1'b1;
+                    hart_runctrl.hwbrkpt_dsbl    <= 1'b1;
+                    hart_runctrl.redirect.sstep  <= 1'b0;
+                    hart_runctrl.redirect.ebreak <= 1'b1;
+                end
+            end
+        end
+    end
+end
+
+// HART Halt Request Time-Out counter
+//------------------------------------------------------------------------------
+// HART goes into halt state only if the halt request is present for timeout period
+// of time
+
+assign halt_req_timeout_cnt_en = hdu2exu_dbg_halt2run_o
+                               | (hart_halt_req & ~hdu2exu_dbg_run2halt_o);
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        halt_req_timeout_cnt <= '1;
+    end else if (halt_req_timeout_cnt_en) begin
+        halt_req_timeout_cnt <= halt_req_timeout_cnt_next;
+    end
+end
+
+assign halt_req_timeout_cnt_next = hdu2exu_dbg_halt2run_o                    ? '1
+                                 : (hart_halt_req & ~hdu2exu_dbg_run2halt_o) ? halt_req_timeout_cnt - 1'b1
+                                                                             : halt_req_timeout_cnt;
+
+assign halt_req_timeout_flag = ~|halt_req_timeout_cnt;
+
+//------------------------------------------------------------------------------
+// HART Status logic
+//------------------------------------------------------------------------------
+//
+ // HART Status logic consists of the following functional units:
+ // - Debug mode cause decoder
+ // - Hart halt status cause encoder
+ // - Hart halt status register
+//
+
+// Debug mode cause decoder
+//------------------------------------------------------------------------------
+
+assign dmode_cause_sstep  = hart_runctrl.redirect.sstep & pipe2hdu_instret_i;
+assign dmode_cause_except = dbg_state_drun & pipe2hdu_exu_exc_req_i
+                          & ~pipe2hdu_brkpt_i
+`ifdef SCR1_TDU_EN
+                          & ~exu2hdu_ibrkpt_hw_i
+`endif // SCR1_TDU_EN
+                          ;
+assign dmode_cause_ebreak = hart_runctrl.redirect.ebreak & pipe2hdu_brkpt_i;
+`ifdef SCR1_TDU_EN
+assign dmode_cause_tmreq  = tdu2hdu_dmode_req_i & exu2hdu_ibrkpt_hw_i;
+`endif // SCR1_TDU_EN
+
+assign dmode_cause_any = dmode_cause_sstep | dmode_cause_ebreak | dmode_cause_except
+                       | hart_halt_req
+`ifdef SCR1_TDU_EN
+                       | dmode_cause_tmreq
+`endif // SCR1_TDU_EN
+                       ;
+
+// HART halt cause encoder
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (1'b1)
+`ifdef SCR1_TDU_EN
+        dmode_cause_tmreq   : hart_haltcause = SCR1_HDU_HALTCAUSE_TMREQ;
+`endif // SCR1_TDU_EN
+        dmode_cause_ebreak  : hart_haltcause = SCR1_HDU_HALTCAUSE_EBREAK;
+        hart_halt_req       : hart_haltcause = SCR1_HDU_HALTCAUSE_DMREQ;
+        dmode_cause_sstep   : hart_haltcause = SCR1_HDU_HALTCAUSE_SSTEP;
+        default             : hart_haltcause = SCR1_HDU_HALTCAUSE_NONE;
+    endcase
+end
+
+// HART halt status register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        hart_haltstatus        <= '0;
+    end else if (hart_halt_ack) begin
+        hart_haltstatus.except <= dmode_cause_except;
+        hart_haltstatus.cause  <= hart_haltcause;
+    end
+end
+
+assign hart_halt_pnd = (dfsm_trans | dm_dhalt_req) & ~hart_halt_ack;
+assign hart_halt_ack = ~hdu2exu_dbg_halted_o
+                     & (halt_req_timeout_flag | (~pipe2hdu_exu_busy_i & dmode_cause_any));
+
+//------------------------------------------------------------------------------
+// Program Buffer (PBUF) logic
+//------------------------------------------------------------------------------
+//
+ // Program Buffer allows to execute small programs in debug mode
+//
+
+// To terminate Program Buffer execution exception should be raised. There are 2
+// cases:
+// - One of PBUF instructions raise an exception
+// - No PBUF instruction raise an exception before the last PBUF instruction has
+// been issued. In this case FSM goes into EXCINJECT state and an "Instruction
+// fetch access fault" exception is injected
+
+// PBUF FSM
+//------------------------------------------------------------------------------
+
+assign ifu_handshake_done = hdu2ifu_pbuf_instr_vd_o & ifu2hdu_pbuf_instr_rdy_i;
+assign pbuf_addr_end      = (pbuf_addr_ff == (SCR1_HDU_PBUF_ADDR_SPAN-1));
+
+assign pbuf_start_fetch = dbg_state_dhalted      & (dbg_state_next == SCR1_HDU_DBGSTATE_DRUN);
+assign pbuf_exc_inj_req = ifu_handshake_done     & pbuf_addr_end;
+assign pbuf_exc_inj_end = pipe2hdu_exu_exc_req_i | ifu_handshake_done;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        pbuf_fsm_curr <= SCR1_HDU_PBUFSTATE_IDLE;
+    end else if(clk_en) begin
+        pbuf_fsm_curr <= pbuf_fsm_next;
+    end
+end
+
+always_comb begin
+    case (pbuf_fsm_curr)
+        SCR1_HDU_PBUFSTATE_IDLE: begin
+            pbuf_fsm_next = pbuf_start_fetch       ? SCR1_HDU_PBUFSTATE_FETCH
+                                                   : SCR1_HDU_PBUFSTATE_IDLE;
+        end
+        SCR1_HDU_PBUFSTATE_FETCH: begin
+            pbuf_fsm_next = pipe2hdu_exu_exc_req_i ? SCR1_HDU_PBUFSTATE_WAIT4END
+                          : pbuf_exc_inj_req       ? SCR1_HDU_PBUFSTATE_EXCINJECT
+                                                   : SCR1_HDU_PBUFSTATE_FETCH;
+        end
+        SCR1_HDU_PBUFSTATE_EXCINJECT: begin
+            pbuf_fsm_next = pbuf_exc_inj_end       ? SCR1_HDU_PBUFSTATE_WAIT4END
+                                                   : SCR1_HDU_PBUFSTATE_EXCINJECT;
+        end
+        SCR1_HDU_PBUFSTATE_WAIT4END: begin
+            pbuf_fsm_next = hdu2exu_dbg_halted_o   ? SCR1_HDU_PBUFSTATE_IDLE
+                                                   : SCR1_HDU_PBUFSTATE_WAIT4END;
+        end
+    endcase
+end
+
+assign pbuf_fsm_idle   = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_IDLE);
+assign pbuf_fsm_fetch  = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_FETCH);
+assign pbuf_fsm_excinj = (pbuf_fsm_curr == SCR1_HDU_PBUFSTATE_EXCINJECT);
+
+// Program Buffer address register
+//------------------------------------------------------------------------------
+
+assign pbuf_addr_next_vd = pbuf_fsm_fetch          & ifu_handshake_done
+                         & ~pipe2hdu_exu_exc_req_i & ~pbuf_addr_end;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        pbuf_addr_ff <= '0;
+    end else if(clk_en) begin
+        pbuf_addr_ff <= pbuf_addr_next;
+    end
+end
+
+assign pbuf_addr_next = pbuf_fsm_idle     ? '0
+                      : pbuf_addr_next_vd ? pbuf_addr_ff + 1'b1
+                                          : pbuf_addr_ff;
+
+// Pass instruction from debug program buffer to cpu pipeline with two options:
+// - through register, better for frequency
+// - through wires, better for area
+generate if (HART_PBUF_INSTR_REGOUT_EN) begin
+    always_ff @(posedge clk, negedge rst_n) begin
+        if (~rst_n) begin
+            pbuf_instr_wait_latching <= 1'b0;
+        end else begin
+            pbuf_instr_wait_latching <= ifu_handshake_done;
+        end
+    end
+end else begin
+    assign pbuf_instr_wait_latching = 1'b0;
+end endgenerate
+
+//------------------------------------------------------------------------------
+// Debug CSRs
+//------------------------------------------------------------------------------
+
+assign csr_upd_on_halt = (dbg_state_reset | dbg_state_run)
+                       & (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED);
+
+// CSRs select logic
+//------------------------------------------------------------------------------
+
+always_comb begin : csr_if_regsel
+    csr_dcsr_sel        = 1'b0;
+    csr_dpc_sel         = 1'b0;
+    csr_dscratch0_sel   = 1'b0;
+    //csr_dscratch1_sel   = 1'b0;
+
+    if (csr2hdu_req_i) begin
+        case (csr2hdu_addr_i)
+            SCR1_HDU_DBGCSR_OFFS_DCSR     : csr_dcsr_sel      = 1'b1;
+            SCR1_HDU_DBGCSR_OFFS_DPC      : csr_dpc_sel       = 1'b1;
+            SCR1_HDU_DBGCSR_OFFS_DSCRATCH0: csr_dscratch0_sel = 1'b1;
+            default : begin
+                                            csr_dcsr_sel      = 1'bX;
+                                            csr_dpc_sel       = 1'bX;
+                                            csr_dscratch0_sel = 1'bX;
+            end
+        endcase
+    end
+end : csr_if_regsel
+
+// CSRs read interface
+//------------------------------------------------------------------------------
+
+assign csr_rd_data = csr_dcsr_out | csr_dpc_out | csr_dscratch0_out;
+
+// CSRs write interface
+//------------------------------------------------------------------------------
+
+assign csr_wr = csr2hdu_req_i;
+
+always_comb begin : csr_if_write
+    csr_wr_data     = '0;
+
+    if (csr2hdu_req_i) begin
+        case (csr2hdu_cmd_i)
+            SCR1_CSR_CMD_WRITE : csr_wr_data = csr2hdu_wdata_i;
+            SCR1_CSR_CMD_SET   : csr_wr_data = csr_rd_data | csr2hdu_wdata_i;
+            SCR1_CSR_CMD_CLEAR : csr_wr_data = csr_rd_data & (~csr2hdu_wdata_i);
+            default            : csr_wr_data = 'X;
+        endcase
+    end
+end : csr_if_write
+
+// Debug Control and Status register
+//------------------------------------------------------------------------------
+// Setups the HART behaviour in Debug Mode and holds Debug status information
+
+always_comb begin
+    csr_dcsr_in                 = csr_wr_data;
+    csr_dcsr_wr                 = csr_wr & csr_dcsr_sel;
+
+    csr_dcsr_out                = '0;
+    if (csr_dcsr_sel) begin
+        csr_dcsr_out.xdebugver  = SCR1_HDU_DEBUGCSR_DCSR_XDEBUGVER;
+        csr_dcsr_out.ebreakm    = csr_dcsr_ebreakm;
+        csr_dcsr_out.stepie     = csr_dcsr_stepie;
+        csr_dcsr_out.step       = csr_dcsr_step;
+        csr_dcsr_out.prv        = 2'b11;
+        csr_dcsr_out.cause      = csr_dcsr_cause;
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_dcsr_ebreakm        <= 1'b0;
+        csr_dcsr_stepie         <= 1'b0;
+        csr_dcsr_step           <= 1'b0;
+    end else if(clk_en) begin
+        if (csr_dcsr_wr) begin
+            csr_dcsr_ebreakm    <= csr_dcsr_in.ebreakm;
+            csr_dcsr_stepie     <= csr_dcsr_in.stepie;
+            csr_dcsr_step       <= csr_dcsr_in.step;
+        end
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        csr_dcsr_cause <= 1'b0;
+    end else if(clk_en) begin
+        if(csr_upd_on_halt) begin
+            csr_dcsr_cause <= hart_haltstatus.cause;
+        end
+    end
+end
+
+// Debug PC register
+//------------------------------------------------------------------------------
+// Saves the virtual address of the next instruction to be executed when Debug
+// Mode is entered. Could be changed by debugger
+
+assign csr_dpc_wr   = csr_wr & csr_dpc_sel;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        csr_dpc_ff <= '0;
+    end else if(clk_en) begin
+        csr_dpc_ff <= csr_dpc_next;
+    end
+end
+
+assign csr_dpc_next = csr_upd_on_halt ? pipe2hdu_pc_curr_i
+                    : csr_dpc_wr      ? csr_wr_data
+                                      : csr_dpc_ff;
+assign csr_dpc_out  = csr_dpc_sel     ? csr_dpc_ff : '0;
+
+// Debug Scratch 0 register
+//------------------------------------------------------------------------------
+
+assign csr_dscratch0_resp = (~dm2hdu_dreg_resp_i | dm2hdu_dreg_fail_i)
+                          ? SCR1_CSR_RESP_ER
+                          : SCR1_CSR_RESP_OK;
+assign csr_dscratch0_out  = csr_dscratch0_sel ? dm2hdu_dreg_rdata_i : '0;
+
+//------------------------------------------------------------------------------
+// HDU <-> DM interface
+//------------------------------------------------------------------------------
+
+assign hdu2dm_hart_event_o = dfsm_event;
+
+// HART status
+always_comb begin
+    hdu2dm_hart_status_o           = '0;
+    hdu2dm_hart_status_o.dbg_state = dbg_state;
+    hdu2dm_hart_status_o.except    = dbg_state_dhalted & hart_haltstatus.except;
+    hdu2dm_hart_status_o.ebreak    = dbg_state_dhalted & (hart_haltstatus.cause == SCR1_HDU_HALTCAUSE_EBREAK);
+end
+
+assign hdu2dm_cmd_rcode_o = dbg_state_reset
+                          ? ~pipe2hdu_rdc_qlfy_i | ~pipe2hdu_init_pc_i | ~dm2hdu_cmd_req_i
+                          : ~pipe2hdu_rdc_qlfy_i | ~dfsm_update;
+
+always_comb begin
+    hdu2dm_cmd_resp_o   = 1'b0;
+
+    case (dbg_state)
+        SCR1_HDU_DBGSTATE_RESET: begin
+            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i & pipe2hdu_init_pc_i & dm2hdu_cmd_req_i;
+        end
+
+        SCR1_HDU_DBGSTATE_RUN: begin
+            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i & dfsm_update & dm2hdu_cmd_req_i;
+        end
+
+        SCR1_HDU_DBGSTATE_DHALTED: begin
+            hdu2dm_cmd_resp_o  = pipe2hdu_rdc_qlfy_i ? dfsm_update : dm2hdu_cmd_req_i;
+        end
+
+        SCR1_HDU_DBGSTATE_DRUN: begin
+            hdu2dm_cmd_resp_o  = (~pipe2hdu_rdc_qlfy_i | dfsm_update) & dm2hdu_cmd_req_i;
+        end
+
+        default: begin
+            hdu2dm_cmd_resp_o  = 'X;
+        end
+    endcase
+end
+
+assign hdu2dm_pbuf_addr_o  = pbuf_addr_ff;
+assign hdu2dm_dreg_req_o   = csr_dscratch0_sel;
+assign hdu2dm_dreg_wr_o    = csr_wr & csr_dscratch0_sel;
+assign hdu2dm_dreg_wdata_o = csr_wr_data;
+
+//------------------------------------------------------------------------------
+// HDU <-> EXU interface
+//------------------------------------------------------------------------------
+
+assign hdu2exu_dbg_halted_o    = (dbg_state_next == SCR1_HDU_DBGSTATE_DHALTED)
+                               | (~pipe2hdu_rdc_qlfy_i & ~dbg_state_run);
+assign hdu2exu_dbg_run_start_o = dbg_state_dhalted & pipe2hdu_rdc_qlfy_i & dfsm_update;
+assign hdu2exu_dbg_halt2run_o  = hdu2exu_dbg_halted_o & hart_resume_req
+`ifdef SCR1_CLKCTRL_EN
+                               & clk_pipe_en
+`endif // SCR1_CLKCTRL_EN
+                               ;
+assign hdu2exu_dbg_run2halt_o  = hart_halt_ack;
+
+assign hdu2exu_pbuf_fetch_o    = hart_runctrl.fetch_src;
+assign hdu2exu_irq_dsbl_o      = hart_runctrl.irq_dsbl;
+assign hdu2exu_pc_advmt_dsbl_o = hart_runctrl.pc_advmt_dsbl;
+// No change in arch. state if dmode caused by breakpoint
+assign hdu2exu_no_commit_o     = dmode_cause_ebreak
+`ifdef SCR1_TDU_EN
+                               | dmode_cause_tmreq
+`endif // SCR1_TDU_EN
+                               ;
+assign hdu2exu_dmode_sstep_en_o = hart_runctrl.redirect.sstep;
+assign hdu2exu_dbg_new_pc_o     = csr_dpc_ff;
+
+//------------------------------------------------------------------------------
+// HDU <-> IFU interface
+//------------------------------------------------------------------------------
+
+assign hdu2ifu_pbuf_instr_vd_o  = (pbuf_fsm_fetch | pbuf_fsm_excinj)
+                                & ~pbuf_instr_wait_latching;
+assign hdu2ifu_pbuf_instr_err_o = pbuf_fsm_excinj;
+
+generate if (HART_PBUF_INSTR_REGOUT_EN) begin
+    always_ff @(posedge clk) begin
+        hdu2ifu_pbuf_instr_o <= dm2hdu_pbuf_instr_i;
+    end
+end else begin
+    assign hdu2ifu_pbuf_instr_o = dm2hdu_pbuf_instr_i;
+end endgenerate
+
+//------------------------------------------------------------------------------
+// HDU <-> CSR interface
+//------------------------------------------------------------------------------
+
+assign csr_addr_dscratch0 = (csr2hdu_addr_i == SCR1_HDU_DBGCSR_OFFS_DSCRATCH0);
+
+assign hdu2csr_resp_o  = ~dbg_state_drun    ? SCR1_CSR_RESP_ER
+                       : csr_addr_dscratch0 ? csr_dscratch0_resp
+                       : csr2hdu_req_i      ? SCR1_CSR_RESP_OK
+                                            : SCR1_CSR_RESP_ER;
+assign hdu2csr_rdata_o = csr_rd_data;
+
+`ifdef SCR1_TDU_EN
+//------------------------------------------------------------------------------
+// HDU <-> TDU interface
+//------------------------------------------------------------------------------
+
+assign hdu2tdu_hwbrk_dsbl_o = hart_runctrl.hwbrkpt_dsbl;
+`endif // SCR1_TDU_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+SVA_HDU_XCHECK_COMMON :
+    assert property (
+        @(negedge clk) disable iff (~rst_n)
+        !$isunknown( {rst_n,clk,clk_en,csr2hdu_req_i,pipe2hdu_rdc_qlfy_i} )
+    )
+    else $error("HDU Error: common signals are in X state");
+
+SVA_HDU_XCHECK_CSR_INTF :
+    assert property (
+        @(negedge clk) disable iff (~rst_n)
+        csr2hdu_req_i |-> !$isunknown( {csr2hdu_cmd_i,csr2hdu_addr_i,csr2hdu_wdata_i} )
+    )
+    else $error("HDU Error: CSR i/f is in X state");
+
+SVA_HDU_XCHECK_DM_INTF :
+    assert property (
+        @(negedge clk) disable iff (~rst_n)
+        !$isunknown( {dm2hdu_cmd_req_i,dm2hdu_cmd_i,dm2hdu_dreg_resp_i,
+        dm2hdu_dreg_fail_i} )
+    )
+    else $error("HDU Error: DM i/f is in X state");
+
+SVA_HDU_XCHECK_TDU_INTF :
+    assert property (
+        @(negedge clk) disable iff (~rst_n)
+        !$isunknown( {tdu2hdu_dmode_req_i,exu2hdu_ibrkpt_hw_i} )
+    )
+    else $error("HDU Error: TDU i/f is in X state");
+
+SVA_HDU_XCHECK_HART_INTF :
+    assert property (
+        @(negedge clk) disable iff (~rst_n)
+        !$isunknown( {pipe2hdu_exu_busy_i,pipe2hdu_instret_i,pipe2hdu_init_pc_i,pipe2hdu_exu_exc_req_i,pipe2hdu_brkpt_i,
+        pipe2hdu_pc_curr_i,ifu2hdu_pbuf_instr_rdy_i} )
+    )
+    else $error("HDU Error: HART i/f is in X state");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_hdu
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ialu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ialu.sv
new file mode 100644
index 0000000..eec1c20
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ialu.sv
@@ -0,0 +1,720 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_ialu.sv>
+/// @brief      Integer Arithmetic Logic Unit (IALU)
+///
+
+//-------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Performs addition/subtraction and arithmetic and branch comparisons
+ // - Performs logical operations (AND(I), OR(I), XOR(I))
+ // - Performs address calculation for branch, jump, DMEM load and store and AUIPC
+ //   instructions
+ // - Performs shift operations
+ // - Performs MUL/DIV operations
+ //
+ // Structure:
+ // - Main adder
+ // - Address adder
+ // - Shift logic
+ // - MUL/DIV logic
+ // - Output result multiplexer
+ //
+//-------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_search_ms1.svh"
+
+
+module scr1_pipe_ialu (
+`ifdef SCR1_RVM_EXT
+    // Common
+    input   logic                           clk,                        // IALU clock
+    input   logic                           rst_n,                      // IALU reset
+    input   logic                           exu2ialu_rvm_cmd_vd_i,      // MUL/DIV command valid
+    output  logic                           ialu2exu_rvm_res_rdy_o,     // MUL/DIV result ready
+`endif // SCR1_RVM_EXT
+
+    // Main adder
+    input   logic [`SCR1_XLEN-1:0]          exu2ialu_main_op1_i,        // main ALU 1st operand
+    input   logic [`SCR1_XLEN-1:0]          exu2ialu_main_op2_i,        // main ALU 2nd operand
+    input   type_scr1_ialu_cmd_sel_e        exu2ialu_cmd_i,             // IALU command
+    output  logic [`SCR1_XLEN-1:0]          ialu2exu_main_res_o,        // main ALU result
+    output  logic                           ialu2exu_cmp_res_o,         // IALU comparison result
+
+    // Address adder
+    input   logic [`SCR1_XLEN-1:0]          exu2ialu_addr_op1_i,        // Address adder 1st operand
+    input   logic [`SCR1_XLEN-1:0]          exu2ialu_addr_op2_i,        // Address adder 2nd operand
+    output  logic [`SCR1_XLEN-1:0]          ialu2exu_addr_res_o         // Address adder result
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters declaration
+//-------------------------------------------------------------------------------
+
+`ifdef SCR1_RVM_EXT
+ `ifdef SCR1_FAST_MUL
+localparam SCR1_MUL_WIDTH     = `SCR1_XLEN;
+localparam SCR1_MUL_RES_WIDTH = 2 * `SCR1_XLEN;
+localparam SCR1_MDU_SUM_WIDTH = `SCR1_XLEN + 1;
+ `else
+localparam SCR1_MUL_STG_NUM   = 32;
+localparam SCR1_MUL_WIDTH     = 32 / SCR1_MUL_STG_NUM;
+localparam SCR1_MUL_CNT_INIT  = 32'b1 << (`SCR1_XLEN/SCR1_MUL_WIDTH - 2);
+localparam SCR1_MDU_SUM_WIDTH = `SCR1_XLEN + SCR1_MUL_WIDTH;
+ `endif // ~SCR1_FAST_MUL
+localparam SCR1_DIV_WIDTH     = 1;
+localparam SCR1_DIV_CNT_INIT  = 32'b1 << (`SCR1_XLEN/SCR1_DIV_WIDTH - 2);
+`endif // SCR1_RVM_EXT
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+
+typedef struct packed {
+    logic       z;      // Zero
+    logic       s;      // Sign
+    logic       o;      // Overflow
+    logic       c;      // Carry
+} type_scr1_ialu_flags_s;
+
+ `ifdef SCR1_RVM_EXT
+typedef enum logic [1:0] {
+    SCR1_IALU_MDU_FSM_IDLE,
+    SCR1_IALU_MDU_FSM_ITER,
+    SCR1_IALU_MDU_FSM_CORR
+} type_scr1_ialu_fsm_state;
+
+typedef enum logic [1:0] {
+   SCR1_IALU_MDU_NONE,
+   SCR1_IALU_MDU_MUL,
+   SCR1_IALU_MDU_DIV
+} type_scr1_ialu_mdu_cmd;
+ `endif // SCR1_RVM_EXT
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+
+// Main adder signals
+logic        [`SCR1_XLEN:0]                 main_sum_res;       // Main adder result
+type_scr1_ialu_flags_s                      main_sum_flags;     // Main adder flags
+logic                                       main_sum_pos_ovflw; // Main adder positive overflow
+logic                                       main_sum_neg_ovflw; // Main adder negative overflow
+logic                                       main_ops_diff_sgn;  // Main adder operands have different signs
+logic                                       main_ops_non_zero;  // Both main adder operands are NOT 0
+
+// Shifter signals
+logic                                       ialu_cmd_shft;      // IALU command is shift
+logic signed [`SCR1_XLEN-1:0]               shft_op1;           // SHIFT operand 1
+logic        [4:0]                          shft_op2;           // SHIFT operand 2
+logic        [1:0]                          shft_cmd;           // SHIFT command: 00 - logical left, 10 - logical right, 11 - arithmetical right
+logic        [`SCR1_XLEN-1:0]               shft_res;           // SHIFT result
+
+// MUL/DIV signals
+`ifdef SCR1_RVM_EXT
+// MUL/DIV FSM control signals
+logic                                       mdu_cmd_is_iter;    // MDU Command is iterative
+logic                                       mdu_iter_req;       // Request iterative stage
+logic                                       mdu_iter_rdy;       // Iteration is ready
+logic                                       mdu_corr_req;       // DIV/REM(U) correction request
+logic                                       div_corr_req;       // Correction request for DIV operation
+logic                                       rem_corr_req;       // Correction request for REM(U) operations
+
+// MUL/DIV FSM signals
+type_scr1_ialu_fsm_state                    mdu_fsm_ff;         // Current FSM state
+type_scr1_ialu_fsm_state                    mdu_fsm_next;       // Next FSM state
+logic                                       mdu_fsm_idle;       // MDU FSM is in IDLE state
+`ifdef SCR1_TRGT_SIMULATION
+logic                                       mdu_fsm_iter;       // MDU FSM is in ITER state
+`endif // SCR1_TRGT_SIMULATION
+logic                                       mdu_fsm_corr;       // MDU FSM is in CORR state
+
+// MDU command signals
+type_scr1_ialu_mdu_cmd                      mdu_cmd;            // MDU command: 00 - NONE, 01 - MUL,  10 - DIV
+logic                                       mdu_cmd_mul;        // MDU command is MUL(HSU)
+logic                                       mdu_cmd_div;        // MDU command is DIV(U)/REM(U)
+logic        [1:0]                          mul_cmd;            // MUL command: 00 - MUL,  01 - MULH, 10 - MULHSU, 11 - MULHU
+logic                                       mul_cmd_hi;         // High part of MUL result is requested
+logic        [1:0]                          div_cmd;            // DIV command: 00 - DIV,  01 - DIVU, 10 - REM,    11 - REMU
+logic                                       div_cmd_div;        // DIV command is DIV
+logic                                       div_cmd_rem;        // DIV command is REM(U)
+
+// Multiplier signals
+logic                                       mul_op1_is_sgn;     // First MUL operand is signed
+logic                                       mul_op2_is_sgn;     // Second MUL operand is signed
+logic                                       mul_op1_sgn;        // First MUL operand is negative
+logic                                       mul_op2_sgn;        // Second MUL operand is negative
+logic signed [`SCR1_XLEN:0]                 mul_op1;            // MUL operand 1
+logic signed [SCR1_MUL_WIDTH:0]             mul_op2;            // MUL operand 1
+ `ifdef SCR1_FAST_MUL
+logic signed [SCR1_MUL_RES_WIDTH-1:0]       mul_res;            // MUL result
+ `else // ~SCR1_FAST_MUL
+logic signed [SCR1_MDU_SUM_WIDTH:0]         mul_part_prod;
+logic        [`SCR1_XLEN-1:0]               mul_res_hi;
+logic        [`SCR1_XLEN-1:0]               mul_res_lo;
+ `endif // ~SCR1_FAST_MUL
+
+// Divisor signals
+logic                                       div_ops_are_sgn;
+logic                                       div_op1_is_neg;
+logic                                       div_op2_is_neg;
+logic                                       div_res_rem_c;
+logic        [`SCR1_XLEN-1:0]               div_res_rem;
+logic        [`SCR1_XLEN-1:0]               div_res_quo;
+logic                                       div_quo_bit;
+logic                                       div_dvdnd_lo_upd;
+logic        [`SCR1_XLEN-1:0]               div_dvdnd_lo_ff;
+logic        [`SCR1_XLEN-1:0]               div_dvdnd_lo_next;
+
+// MDU adder signals
+logic                                       mdu_sum_sub;        // MDU adder operation: 0 - add, 1 - sub
+logic signed [SCR1_MDU_SUM_WIDTH-1:0]       mdu_sum_op1;        // MDU adder operand 1
+logic signed [SCR1_MDU_SUM_WIDTH-1:0]       mdu_sum_op2;        // MDU adder operand 2
+logic signed [SCR1_MDU_SUM_WIDTH-1:0]       mdu_sum_res;        // MDU adder result
+
+// MDU iteration counter signals
+logic                                       mdu_iter_cnt_en;
+logic        [`SCR1_XLEN-1:0]               mdu_iter_cnt;
+logic        [`SCR1_XLEN-1:0]               mdu_iter_cnt_next;
+
+// Intermediate results registers
+logic                                       mdu_res_upd;
+logic                                       mdu_res_c_ff;
+logic                                       mdu_res_c_next;
+logic        [`SCR1_XLEN-1:0]               mdu_res_hi_ff;
+logic        [`SCR1_XLEN-1:0]               mdu_res_hi_next;
+logic        [`SCR1_XLEN-1:0]               mdu_res_lo_ff;
+logic        [`SCR1_XLEN-1:0]               mdu_res_lo_next;
+`endif // SCR1_RVM_EXT
+
+//-------------------------------------------------------------------------------
+// Main adder
+//-------------------------------------------------------------------------------
+//
+ // Main adder is used for the following types of operations:
+ // - Addition/subtraction          (ADD/ADDI/SUB)
+ // - Branch comparisons            (BEQ/BNE/BLT(U)/BGE(U))
+ // - Arithmetic comparisons        (SLT(U)/SLTI(U))
+//
+
+// Carry out (MSB of main_sum_res) is evaluated correctly because the result
+// width equals to the maximum width of both the right-hand and left-hand side variables
+always_comb begin
+    main_sum_res = (exu2ialu_cmd_i != SCR1_IALU_CMD_ADD)
+                 ? (exu2ialu_main_op1_i - exu2ialu_main_op2_i)   // Subtraction and comparison
+                 : (exu2ialu_main_op1_i + exu2ialu_main_op2_i);  // Addition
+
+    main_sum_pos_ovflw = ~exu2ialu_main_op1_i[`SCR1_XLEN-1]
+                       &  exu2ialu_main_op2_i[`SCR1_XLEN-1]
+                       &  main_sum_res[`SCR1_XLEN-1];
+    main_sum_neg_ovflw =  exu2ialu_main_op1_i[`SCR1_XLEN-1]
+                       & ~exu2ialu_main_op2_i[`SCR1_XLEN-1]
+                       & ~main_sum_res[`SCR1_XLEN-1];
+
+    // FLAGS1 - flags for comparison (result of subtraction)
+    main_sum_flags.c = main_sum_res[`SCR1_XLEN];
+    main_sum_flags.z = ~|main_sum_res[`SCR1_XLEN-1:0];
+    main_sum_flags.s = main_sum_res[`SCR1_XLEN-1];
+    main_sum_flags.o = main_sum_pos_ovflw | main_sum_neg_ovflw;
+end
+
+//-------------------------------------------------------------------------------
+// Address adder
+//-------------------------------------------------------------------------------
+//
+ // Additional adder is used for the following types of operations:
+ // - PC-based address calculation          (AUIPC)
+ // - IMEM branch address calculation       (BEQ/BNE/BLT(U)/BGE(U))
+ // - IMEM jump address calculation         (JAL/JALR)
+ // - DMEM load address calculation         (LB(U)/LH(U)/LW)
+ // - DMEM store address calculation        (SB/SH/SW)
+//
+
+assign ialu2exu_addr_res_o = exu2ialu_addr_op1_i + exu2ialu_addr_op2_i;
+
+//-------------------------------------------------------------------------------
+// Shift logic
+//-------------------------------------------------------------------------------
+ //
+ // Shift logic supports the following types of shift operations:
+ // - Logical left shift      (SLLI/SLL)
+ // - Logical right shift     (SRLI/SRL)
+ // - Arithmetic right shift  (SRAI/SRA)
+//
+
+assign ialu_cmd_shft = (exu2ialu_cmd_i == SCR1_IALU_CMD_SLL)
+                     | (exu2ialu_cmd_i == SCR1_IALU_CMD_SRL)
+                     | (exu2ialu_cmd_i == SCR1_IALU_CMD_SRA);
+assign shft_cmd      = ialu_cmd_shft
+                     ? {(exu2ialu_cmd_i != SCR1_IALU_CMD_SLL),
+                        (exu2ialu_cmd_i == SCR1_IALU_CMD_SRA)}
+                     : 2'b00;
+
+always_comb begin
+    shft_op1 = exu2ialu_main_op1_i;
+    shft_op2 = exu2ialu_main_op2_i[4:0];
+    case (shft_cmd)
+        2'b10   : shft_res = shft_op1  >> shft_op2;
+        2'b11   : shft_res = shft_op1 >>> shft_op2;
+        default : shft_res = shft_op1  << shft_op2;
+    endcase
+end
+
+`ifdef SCR1_RVM_EXT
+//-------------------------------------------------------------------------------
+// MUL/DIV logic
+//-------------------------------------------------------------------------------
+//
+ // MUL/DIV instructions use the following functional units:
+ // - MUL/DIV FSM control logic, including iteration number counter
+ // - MUL/DIV FSM
+ // - MUL logic
+ // - DIV logic
+ // - MDU adder to produce an intermediate result
+ // - 2 registers to save the intermediate result (shared between MUL and DIV
+ //   operations)
+//
+
+//-------------------------------------------------------------------------------
+// MUL/DIV FSM Control logic
+//-------------------------------------------------------------------------------
+
+assign mdu_cmd_div = (exu2ialu_cmd_i == SCR1_IALU_CMD_DIV)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_DIVU)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_REM)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_REMU);
+assign mdu_cmd_mul = (exu2ialu_cmd_i == SCR1_IALU_CMD_MUL)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_MULH)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_MULHU)
+                   | (exu2ialu_cmd_i == SCR1_IALU_CMD_MULHSU);
+
+assign mdu_cmd     = mdu_cmd_div ? SCR1_IALU_MDU_DIV
+                   : mdu_cmd_mul ? SCR1_IALU_MDU_MUL
+                                 : SCR1_IALU_MDU_NONE;
+
+assign main_ops_non_zero = |exu2ialu_main_op1_i & |exu2ialu_main_op2_i;
+assign main_ops_diff_sgn = exu2ialu_main_op1_i[`SCR1_XLEN-1]
+                         ^ exu2ialu_main_op2_i[`SCR1_XLEN-1];
+
+ `ifdef SCR1_FAST_MUL
+    assign mdu_cmd_is_iter = mdu_cmd_div;
+ `else // ~SCR1_FAST_MUL
+    assign mdu_cmd_is_iter = mdu_cmd_mul | mdu_cmd_div;
+ `endif // ~SCR1_FAST_MUL
+
+assign mdu_iter_req = mdu_cmd_is_iter ? (main_ops_non_zero & mdu_fsm_idle) : 1'b0;
+assign mdu_iter_rdy = mdu_iter_cnt[0];
+
+assign div_cmd_div = (div_cmd == 2'b00);
+assign div_cmd_rem = div_cmd[1];
+
+// Correction request signals
+assign div_corr_req = div_cmd_div & main_ops_diff_sgn;
+assign rem_corr_req = div_cmd_rem & |div_res_rem & (div_op1_is_neg ^ div_res_rem_c);
+assign mdu_corr_req = mdu_cmd_div & (div_corr_req | rem_corr_req);
+
+// MDU iteration counter
+//------------------------------------------------------------------------------
+
+assign mdu_iter_cnt_en = exu2ialu_rvm_cmd_vd_i & ~ialu2exu_rvm_res_rdy_o;
+
+always_ff @(posedge clk) begin
+    if (mdu_iter_cnt_en) begin
+        mdu_iter_cnt <= mdu_iter_cnt_next;
+    end
+end
+
+assign mdu_iter_cnt_next = ~mdu_fsm_idle ? mdu_iter_cnt >> 1
+                         : mdu_cmd_div   ? SCR1_DIV_CNT_INIT
+ `ifndef SCR1_FAST_MUL
+                         : mdu_cmd_mul   ? SCR1_MUL_CNT_INIT
+ `endif // ~SCR1_FAST_MUL
+                                         : mdu_iter_cnt;
+
+//-------------------------------------------------------------------------------
+// MUL/DIV FSM
+//-------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        mdu_fsm_ff <= SCR1_IALU_MDU_FSM_IDLE;
+    end else begin
+        mdu_fsm_ff <= mdu_fsm_next;
+    end
+end
+
+always_comb begin
+    mdu_fsm_next = SCR1_IALU_MDU_FSM_IDLE;
+
+    if (exu2ialu_rvm_cmd_vd_i) begin
+        case (mdu_fsm_ff)
+            SCR1_IALU_MDU_FSM_IDLE : begin
+                mdu_fsm_next = mdu_iter_req  ? SCR1_IALU_MDU_FSM_ITER
+                                             : SCR1_IALU_MDU_FSM_IDLE;
+            end
+            SCR1_IALU_MDU_FSM_ITER : begin
+                mdu_fsm_next = ~mdu_iter_rdy ? SCR1_IALU_MDU_FSM_ITER
+                             : mdu_corr_req  ? SCR1_IALU_MDU_FSM_CORR
+                                             : SCR1_IALU_MDU_FSM_IDLE;
+            end
+            SCR1_IALU_MDU_FSM_CORR : begin
+                mdu_fsm_next = SCR1_IALU_MDU_FSM_IDLE;
+            end
+        endcase
+    end
+end
+
+assign mdu_fsm_idle = (mdu_fsm_ff == SCR1_IALU_MDU_FSM_IDLE);
+`ifdef SCR1_TRGT_SIMULATION
+assign mdu_fsm_iter = (mdu_fsm_ff == SCR1_IALU_MDU_FSM_ITER);
+`endif // SCR1_TRGT_SIMULATION
+assign mdu_fsm_corr = (mdu_fsm_ff == SCR1_IALU_MDU_FSM_CORR);
+
+//-------------------------------------------------------------------------------
+// Multiplier logic
+//-------------------------------------------------------------------------------
+//
+ // Multiplication has 2 options: fast (1 cycle) and Radix-2 (32 cycles) multiplication.
+ //
+ // 1. Fast multiplication uses the straightforward approach when 2 operands are
+ // multiplied in one cycle
+ //
+ // 2. Radix-2 multiplication uses 2 registers (high and low part of multiplication)
+ //
+ // Radix-2 algorithm:
+ // 1. Initialize registers
+ // 2. Create a partial product by multiplying multiplicand by the LSB of multiplier
+ // 3. Add the partial product to the previous (intermediate) value of multiplication
+ //    result (stored into high and low parts of multiplication result register)
+ // 4. Shift the low part of multiplication result register right
+ // 4. Store the addition result into the high part of multiplication result register
+ // 6. If iteration is not ready, go to step 2. Otherwise multiplication is done
+ //
+//
+
+assign mul_cmd  = {((exu2ialu_cmd_i == SCR1_IALU_CMD_MULHU) | (exu2ialu_cmd_i == SCR1_IALU_CMD_MULHSU)),
+                   ((exu2ialu_cmd_i == SCR1_IALU_CMD_MULHU) | (exu2ialu_cmd_i == SCR1_IALU_CMD_MULH))};
+
+assign mul_cmd_hi     = |mul_cmd;
+assign mul_op1_is_sgn = ~&mul_cmd;
+assign mul_op2_is_sgn = ~mul_cmd[1];
+assign mul_op1_sgn    = mul_op1_is_sgn & exu2ialu_main_op1_i[`SCR1_XLEN-1];
+assign mul_op2_sgn    = mul_op2_is_sgn & exu2ialu_main_op2_i[`SCR1_XLEN-1];
+
+`ifdef SCR1_FAST_MUL
+assign mul_op1 = mdu_cmd_mul ? $signed({mul_op1_sgn, exu2ialu_main_op1_i}) : '0;
+assign mul_op2 = mdu_cmd_mul ? $signed({mul_op2_sgn, exu2ialu_main_op2_i}) : '0;
+assign mul_res = mdu_cmd_mul ? mul_op1 * mul_op2                           : 'sb0;
+`else // ~SCR1_FAST_MUL
+assign mul_op1 = mdu_cmd_mul  ? $signed({mul_op1_sgn, exu2ialu_main_op1_i}) : '0;
+assign mul_op2 = ~mdu_cmd_mul ? '0
+               : mdu_fsm_idle ? $signed({1'b0, exu2ialu_main_op2_i[SCR1_MUL_WIDTH-1:0]})
+                              : $signed({(mdu_iter_cnt[0] & mul_op2_is_sgn & mdu_res_lo_ff[SCR1_MUL_WIDTH-1]),
+                                          mdu_res_lo_ff[SCR1_MUL_WIDTH-1:0]});
+
+assign mul_part_prod            = mdu_cmd_mul  ? mul_op1 * mul_op2 : 'sb0;
+assign {mul_res_hi, mul_res_lo} = ~mdu_cmd_mul ? '0
+                                : mdu_fsm_idle ? ({mdu_sum_res, exu2ialu_main_op2_i[`SCR1_XLEN-1:SCR1_MUL_WIDTH]})
+                                               : ({mdu_sum_res, mdu_res_lo_ff[`SCR1_XLEN-1:SCR1_MUL_WIDTH]});
+`endif // ~SCR1_FAST_MUL
+
+//-------------------------------------------------------------------------------
+// Divider logic
+//-------------------------------------------------------------------------------
+//
+ // Division uses a non-restoring algorithm. 3 registers are used:
+ // - Remainder register
+ // - Quotient register
+ // - Dividend low part register (for corner case quotient bit calculation)
+ //
+ // Algorithm:
+ // 1. Initialize registers
+ // 2. Shift remainder and dividend low part registers left
+ // 3. Compare remainder register with the divisor (taking previous quotient bit
+ //    and operands signs into account) and calculate quotient bit based on the
+ //    comparison results
+ // 4. Shift quotient register left, append quotient bit to the quotient register
+ // 5. If iteration is not ready, go to step 2. Otherwise go to step 6
+ // 6. Do correction if necessary, otherwise division is done
+ //
+ // Quotient bit calculation has a corner case:
+ // When dividend is negative result carry bit check takes into account only
+ // the case of remainder register been greater than divisor. To handle
+ // equality case we should check if both the comparison result and the
+ // lower part of dividend are zero
+//
+
+assign div_cmd  = {((exu2ialu_cmd_i == SCR1_IALU_CMD_REM)   | (exu2ialu_cmd_i == SCR1_IALU_CMD_REMU)),
+                   ((exu2ialu_cmd_i == SCR1_IALU_CMD_REMU)  | (exu2ialu_cmd_i == SCR1_IALU_CMD_DIVU))};
+
+assign div_ops_are_sgn = ~div_cmd[0];
+assign div_op1_is_neg  = div_ops_are_sgn & exu2ialu_main_op1_i[`SCR1_XLEN-1];
+assign div_op2_is_neg  = div_ops_are_sgn & exu2ialu_main_op2_i[`SCR1_XLEN-1];
+
+always_comb begin
+    div_res_rem_c = '0;
+    div_res_rem   = '0;
+    div_res_quo   = '0;
+    div_quo_bit   = 1'b0;
+    if (mdu_cmd_div & ~mdu_fsm_corr) begin
+        div_res_rem_c = mdu_sum_res[SCR1_MDU_SUM_WIDTH-1];
+        div_res_rem   = mdu_sum_res[SCR1_MDU_SUM_WIDTH-2:0];
+        div_quo_bit   = ~(div_op1_is_neg ^ div_res_rem_c)
+                      | (div_op1_is_neg & ({mdu_sum_res, div_dvdnd_lo_next} == '0));
+        div_res_quo   = mdu_fsm_idle
+                      ? {'0, div_quo_bit}
+                      : {mdu_res_lo_ff[`SCR1_XLEN-2:0], div_quo_bit};
+    end
+end
+
+// Dividend low part register
+//------------------------------------------------------------------------------
+
+assign div_dvdnd_lo_upd = exu2ialu_rvm_cmd_vd_i & ~ialu2exu_rvm_res_rdy_o;
+
+always_ff @(posedge clk) begin
+    if (div_dvdnd_lo_upd) begin
+        div_dvdnd_lo_ff <= div_dvdnd_lo_next;
+    end
+end
+
+assign div_dvdnd_lo_next = (~mdu_cmd_div | mdu_fsm_corr) ? '0
+                         : mdu_fsm_idle                  ? exu2ialu_main_op1_i << 1
+                                                         : div_dvdnd_lo_ff     << 1;
+
+//-------------------------------------------------------------------------------
+// MDU adder
+//-------------------------------------------------------------------------------
+
+always_comb begin
+    mdu_sum_sub    = 1'b0;
+    mdu_sum_op1    = '0;
+    mdu_sum_op2    = '0;
+    case (mdu_cmd)
+        SCR1_IALU_MDU_DIV : begin
+            logic           sgn;
+            logic           inv;
+
+            sgn         = mdu_fsm_corr ? div_op1_is_neg ^ mdu_res_c_ff
+                        : mdu_fsm_idle ? 1'b0
+                                       : ~mdu_res_lo_ff[0];
+            inv         = div_ops_are_sgn & main_ops_diff_sgn;
+            mdu_sum_sub = ~inv ^ sgn;
+            mdu_sum_op1 = mdu_fsm_corr ? $signed({1'b0, mdu_res_hi_ff})
+                        : mdu_fsm_idle ? $signed({div_op1_is_neg, exu2ialu_main_op1_i[`SCR1_XLEN-1]})
+                                       : $signed({mdu_res_hi_ff, div_dvdnd_lo_ff[`SCR1_XLEN-1]});
+            mdu_sum_op2 = $signed({div_op2_is_neg, exu2ialu_main_op2_i});
+        end
+`ifndef SCR1_FAST_MUL
+        SCR1_IALU_MDU_MUL : begin
+            mdu_sum_op1 = mdu_fsm_idle
+                        ? '0
+                        : $signed({(mul_op1_is_sgn & mdu_res_hi_ff[`SCR1_XLEN-1]), mdu_res_hi_ff});
+            mdu_sum_op2 = mul_part_prod;
+        end
+`endif // SCR1_FAST_MUL
+        default : begin end
+    endcase
+    mdu_sum_res = mdu_sum_sub
+                ? (mdu_sum_op1 - mdu_sum_op2)
+                : (mdu_sum_op1 + mdu_sum_op2);
+end
+
+//-------------------------------------------------------------------------------
+// MUL/DIV intermediate results registers
+//-------------------------------------------------------------------------------
+
+assign mdu_res_upd = exu2ialu_rvm_cmd_vd_i & ~ialu2exu_rvm_res_rdy_o;
+
+always_ff @(posedge clk) begin
+    if (mdu_res_upd) begin
+        mdu_res_c_ff  <= mdu_res_c_next;
+        mdu_res_hi_ff <= mdu_res_hi_next;
+        mdu_res_lo_ff <= mdu_res_lo_next;
+    end
+end
+
+assign mdu_res_c_next  = mdu_cmd_div ? div_res_rem_c : mdu_res_c_ff;
+assign mdu_res_hi_next = mdu_cmd_div ? div_res_rem
+ `ifndef SCR1_FAST_MUL
+                       : mdu_cmd_mul ? mul_res_hi
+ `endif // SCR1_FAST_MUL
+                                     : mdu_res_hi_ff;
+assign mdu_res_lo_next = mdu_cmd_div ? div_res_quo
+ `ifndef SCR1_FAST_MUL
+                       : mdu_cmd_mul ? mul_res_lo
+ `endif // SCR1_FAST_MUL
+                                     : mdu_res_lo_ff;
+`endif // SCR1_RVM_EXT
+
+//-------------------------------------------------------------------------------
+// Operation result forming
+//-------------------------------------------------------------------------------
+
+always_comb begin
+    ialu2exu_main_res_o    = '0;
+    ialu2exu_cmp_res_o     = 1'b0;
+`ifdef SCR1_RVM_EXT
+    ialu2exu_rvm_res_rdy_o = 1'b1;
+`endif // SCR1_RVM_EXT
+
+    case (exu2ialu_cmd_i)
+        SCR1_IALU_CMD_AND : begin
+            ialu2exu_main_res_o = exu2ialu_main_op1_i & exu2ialu_main_op2_i;
+        end
+        SCR1_IALU_CMD_OR : begin
+            ialu2exu_main_res_o = exu2ialu_main_op1_i | exu2ialu_main_op2_i;
+        end
+        SCR1_IALU_CMD_XOR : begin
+            ialu2exu_main_res_o = exu2ialu_main_op1_i ^ exu2ialu_main_op2_i;
+        end
+        SCR1_IALU_CMD_ADD : begin
+            ialu2exu_main_res_o = main_sum_res[`SCR1_XLEN-1:0];
+        end
+        SCR1_IALU_CMD_SUB : begin
+            ialu2exu_main_res_o = main_sum_res[`SCR1_XLEN-1:0];
+        end
+        SCR1_IALU_CMD_SUB_LT : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(main_sum_flags.s ^ main_sum_flags.o);
+            ialu2exu_cmp_res_o  = main_sum_flags.s ^ main_sum_flags.o;
+        end
+        SCR1_IALU_CMD_SUB_LTU : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(main_sum_flags.c);
+            ialu2exu_cmp_res_o  = main_sum_flags.c;
+        end
+        SCR1_IALU_CMD_SUB_EQ : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(main_sum_flags.z);
+            ialu2exu_cmp_res_o  = main_sum_flags.z;
+        end
+        SCR1_IALU_CMD_SUB_NE : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(~main_sum_flags.z);
+            ialu2exu_cmp_res_o  = ~main_sum_flags.z;
+        end
+        SCR1_IALU_CMD_SUB_GE : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(~(main_sum_flags.s ^ main_sum_flags.o));
+            ialu2exu_cmp_res_o  = ~(main_sum_flags.s ^ main_sum_flags.o);
+        end
+        SCR1_IALU_CMD_SUB_GEU : begin
+            ialu2exu_main_res_o = `SCR1_XLEN'(~main_sum_flags.c);
+            ialu2exu_cmp_res_o  = ~main_sum_flags.c;
+        end
+        SCR1_IALU_CMD_SLL,
+        SCR1_IALU_CMD_SRL,
+        SCR1_IALU_CMD_SRA: begin
+            ialu2exu_main_res_o = shft_res;
+        end
+`ifdef SCR1_RVM_EXT
+        SCR1_IALU_CMD_MUL,
+        SCR1_IALU_CMD_MULHU,
+        SCR1_IALU_CMD_MULHSU,
+        SCR1_IALU_CMD_MULH : begin
+ `ifdef SCR1_FAST_MUL
+            ialu2exu_main_res_o = mul_cmd_hi
+                                ? mul_res[SCR1_MUL_RES_WIDTH-1:`SCR1_XLEN]
+                                : mul_res[`SCR1_XLEN-1:0];
+ `else // ~SCR1_FAST_MUL
+            case (mdu_fsm_ff)
+                SCR1_IALU_MDU_FSM_IDLE : begin
+                    ialu2exu_main_res_o    = '0;
+                    ialu2exu_rvm_res_rdy_o = ~mdu_iter_req;
+                end
+                SCR1_IALU_MDU_FSM_ITER : begin
+                    ialu2exu_main_res_o    = mul_cmd_hi ? mul_res_hi : mul_res_lo;
+                    ialu2exu_rvm_res_rdy_o = mdu_iter_rdy;
+                end
+            endcase
+ `endif // ~SCR1_FAST_MUL
+        end
+        SCR1_IALU_CMD_DIV,
+        SCR1_IALU_CMD_DIVU,
+        SCR1_IALU_CMD_REM,
+        SCR1_IALU_CMD_REMU : begin
+            case (mdu_fsm_ff)
+                SCR1_IALU_MDU_FSM_IDLE : begin
+                    ialu2exu_main_res_o    = (|exu2ialu_main_op2_i | div_cmd_rem)
+                                           ? exu2ialu_main_op1_i
+                                           : '1;
+                    ialu2exu_rvm_res_rdy_o = ~mdu_iter_req;
+                end
+                SCR1_IALU_MDU_FSM_ITER : begin
+                    ialu2exu_main_res_o    = div_cmd_rem ? div_res_rem : div_res_quo;
+                    ialu2exu_rvm_res_rdy_o = mdu_iter_rdy & ~mdu_corr_req;
+                end
+                SCR1_IALU_MDU_FSM_CORR : begin
+                    ialu2exu_main_res_o    = div_cmd_rem
+                                           ? mdu_sum_res[`SCR1_XLEN-1:0]
+                                           : -mdu_res_lo_ff[`SCR1_XLEN-1:0];
+                    ialu2exu_rvm_res_rdy_o = 1'b1;
+                end
+            endcase
+        end
+`endif // SCR1_RVM_EXT
+        default : begin end
+    endcase
+end
+
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+`ifdef SCR1_RVM_EXT
+
+// X checks
+
+SCR1_SVA_IALU_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({exu2ialu_rvm_cmd_vd_i, mdu_fsm_ff})
+    ) else $error("IALU Error: unknown values");
+
+SCR1_SVA_IALU_XCHECK_QUEUE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2ialu_rvm_cmd_vd_i |->
+    !$isunknown({exu2ialu_main_op1_i, exu2ialu_main_op2_i, exu2ialu_cmd_i})
+    ) else $error("IALU Error: unknown values in queue");
+
+// Behavior checks
+
+SCR1_SVA_IALU_ILL_STATE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    $onehot0({~exu2ialu_rvm_cmd_vd_i, mdu_fsm_iter, mdu_fsm_corr})
+    ) else $error("IALU Error: illegal state");
+
+SCR1_SVA_IALU_JUMP_FROM_IDLE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (mdu_fsm_idle & (~exu2ialu_rvm_cmd_vd_i | ~mdu_iter_req)) |=> mdu_fsm_idle
+    ) else $error("EXU Error: illegal jump from IDLE state");
+
+SCR1_SVA_IALU_IDLE_TO_ITER : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (mdu_fsm_idle & exu2ialu_rvm_cmd_vd_i & mdu_iter_req) |=> mdu_fsm_iter
+    ) else $error("EXU Error: illegal change state form IDLE to ITER");
+
+SCR1_SVA_IALU_JUMP_FROM_ITER : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (mdu_fsm_iter & ~mdu_iter_rdy) |=> mdu_fsm_iter
+    ) else $error("EXU Error: illegal jump from ITER state");
+
+SCR1_SVA_IALU_ITER_TO_IDLE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (mdu_fsm_iter & mdu_iter_rdy & ~mdu_corr_req) |=> mdu_fsm_idle
+    ) else $error("EXU Error: illegal state change ITER to IDLE");
+
+SCR1_SVA_IALU_ITER_TO_CORR : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (mdu_fsm_iter & mdu_iter_rdy & mdu_corr_req) |=> mdu_fsm_corr
+    ) else $error("EXU Error: illegal state change ITER to CORR");
+
+SCR1_SVA_IALU_CORR_TO_IDLE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    mdu_fsm_corr |=> mdu_fsm_idle
+    ) else $error("EXU Error: illegal state stay in CORR");
+
+`endif // SCR1_RVM_EXT
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_ialu
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_idu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_idu.sv
new file mode 100644
index 0000000..f51dacf
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_idu.sv
@@ -0,0 +1,876 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_idu.sv>
+/// @brief      Instruction Decoder Unit (IDU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Decodes the instruction and creates the appropriate control signals for EXU
+ //
+ // Structure:
+ // - Instruction decoder
+ // - IDU <-> IFU i/f
+ // - IDU <-> EXU i/f
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_memif.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_arch_description.svh"
+
+module scr1_pipe_idu
+(
+`ifdef SCR1_TRGT_SIMULATION
+    input   logic                           rst_n,                  // IDU reset
+    input   logic                           clk,                    // IDU clock
+`endif // SCR1_TRGT_SIMULATION
+
+    // IFU <-> IDU interface
+    output  logic                           idu2ifu_rdy_o,          // IDU ready for new data
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]   ifu2idu_instr_i,        // IFU instruction
+    input   logic                           ifu2idu_imem_err_i,     // Instruction access fault exception
+    input   logic                           ifu2idu_err_rvi_hi_i,   // 1 - imem fault when trying to fetch second half of an unaligned RVI instruction
+    input   logic                           ifu2idu_vd_i,           // IFU request
+
+    // IDU <-> EXU interface
+    output  logic                           idu2exu_req_o,          // IDU request
+    output  type_scr1_exu_cmd_s             idu2exu_cmd_o,          // IDU command
+    output  logic                           idu2exu_use_rs1_o,      // Instruction uses rs1
+    output  logic                           idu2exu_use_rs2_o,      // Instruction uses rs2
+    output  logic                           idu2exu_use_rd_o,       // Instruction uses rd
+    output  logic                           idu2exu_use_imm_o,      // Instruction uses immediate
+    input   logic                           exu2idu_rdy_i           // EXU ready for new data
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters declaration
+//-------------------------------------------------------------------------------
+
+localparam [SCR1_GPR_FIELD_WIDTH-1:0] SCR1_MPRF_ZERO_ADDR   = 5'd0;
+localparam [SCR1_GPR_FIELD_WIDTH-1:0] SCR1_MPRF_RA_ADDR     = 5'd1;
+localparam [SCR1_GPR_FIELD_WIDTH-1:0] SCR1_MPRF_SP_ADDR     = 5'd2;
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+
+logic [`SCR1_IMEM_DWIDTH-1:0]       instr;
+type_scr1_instr_type_e              instr_type;
+type_scr1_rvi_opcode_e              rvi_opcode;
+logic                               rvi_illegal;
+logic [2:0]                         funct3;
+logic [6:0]                         funct7;
+logic [11:0]                        funct12;
+logic [4:0]                         shamt;
+`ifdef SCR1_RVC_EXT
+logic                               rvc_illegal;
+`endif  // SCR1_RVC_EXT
+`ifdef SCR1_RVE_EXT
+logic                               rve_illegal;
+`endif  // SCR1_RVE_EXT
+
+//-------------------------------------------------------------------------------
+// Instruction decoding
+//-------------------------------------------------------------------------------
+
+assign idu2ifu_rdy_o  = exu2idu_rdy_i;
+assign idu2exu_req_o  = ifu2idu_vd_i;
+assign instr          = ifu2idu_instr_i;
+
+// RVI / RVC
+assign instr_type   = type_scr1_instr_type_e'(instr[1:0]);
+
+// RVI / RVC fields
+assign rvi_opcode   = type_scr1_rvi_opcode_e'(instr[6:2]);                          // RVI
+assign funct3       = (instr_type == SCR1_INSTR_RVI) ? instr[14:12] : instr[15:13]; // RVI / RVC
+assign funct7       = instr[31:25];                                                 // RVI
+assign funct12      = instr[31:20];                                                 // RVI (SYSTEM)
+assign shamt        = instr[24:20];                                                 // RVI
+
+// RV32I(MC) decode
+always_comb begin
+    // Defaults
+    idu2exu_cmd_o.instr_rvc   = 1'b0;
+    idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+    idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_NONE;
+    idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+    idu2exu_cmd_o.lsu_cmd     = SCR1_LSU_CMD_NONE;
+    idu2exu_cmd_o.csr_op      = SCR1_CSR_OP_REG;
+    idu2exu_cmd_o.csr_cmd     = SCR1_CSR_CMD_NONE;
+    idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_NONE;
+    idu2exu_cmd_o.jump_req    = 1'b0;
+    idu2exu_cmd_o.branch_req  = 1'b0;
+    idu2exu_cmd_o.mret_req    = 1'b0;
+    idu2exu_cmd_o.fencei_req  = 1'b0;
+    idu2exu_cmd_o.wfi_req     = 1'b0;
+    idu2exu_cmd_o.rs1_addr    = '0;
+    idu2exu_cmd_o.rs2_addr    = '0;
+    idu2exu_cmd_o.rd_addr     = '0;
+    idu2exu_cmd_o.imm         = '0;
+    idu2exu_cmd_o.exc_req     = 1'b0;
+    idu2exu_cmd_o.exc_code    = SCR1_EXC_CODE_INSTR_MISALIGN;
+
+    // Clock gating
+    idu2exu_use_rs1_o         = 1'b0;
+    idu2exu_use_rs2_o         = 1'b0;
+    idu2exu_use_rd_o          = 1'b0;
+    idu2exu_use_imm_o         = 1'b0;
+
+    rvi_illegal             = 1'b0;
+`ifdef SCR1_RVE_EXT
+    rve_illegal             = 1'b0;
+`endif  // SCR1_RVE_EXT
+`ifdef SCR1_RVC_EXT
+    rvc_illegal             = 1'b0;
+`endif  // SCR1_RVC_EXT
+
+    // Check for IMEM access fault
+    if (ifu2idu_imem_err_i) begin
+        idu2exu_cmd_o.exc_req     = 1'b1;
+        idu2exu_cmd_o.exc_code    = SCR1_EXC_CODE_INSTR_ACCESS_FAULT;
+        idu2exu_cmd_o.instr_rvc   = ifu2idu_err_rvi_hi_i;
+    end else begin  // no imem fault
+        case (instr_type)
+            SCR1_INSTR_RVI  : begin
+                idu2exu_cmd_o.rs1_addr    = instr[19:15];
+                idu2exu_cmd_o.rs2_addr    = instr[24:20];
+                idu2exu_cmd_o.rd_addr     = instr[11:7];
+                case (rvi_opcode)
+                    SCR1_OPCODE_AUIPC           : begin
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_SUM2;
+                        idu2exu_cmd_o.imm         = {instr[31:12], 12'b0};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_AUIPC
+
+                    SCR1_OPCODE_LUI             : begin
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IMM;
+                        idu2exu_cmd_o.imm         = {instr[31:12], 12'b0};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_LUI
+
+                    SCR1_OPCODE_JAL             : begin
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_INC_PC;
+                        idu2exu_cmd_o.jump_req    = 1'b1;
+                        idu2exu_cmd_o.imm         = {{12{instr[31]}}, instr[19:12], instr[20], instr[30:21], 1'b0};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_JAL
+
+                    SCR1_OPCODE_LOAD            : begin
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_LSU;
+                        idu2exu_cmd_o.imm         = {{21{instr[31]}}, instr[30:20]};
+                        case (funct3)
+                            3'b000  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_LB;
+                            3'b001  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_LH;
+                            3'b010  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_LW;
+                            3'b100  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_LBU;
+                            3'b101  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_LHU;
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct3
+`ifdef SCR1_RVE_EXT
+                        if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_LOAD
+
+                    SCR1_OPCODE_STORE           : begin
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.imm         = {{21{instr[31]}}, instr[30:25], instr[11:7]};
+                        case (funct3)
+                            3'b000  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_SB;
+                            3'b001  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_SH;
+                            3'b010  : idu2exu_cmd_o.lsu_cmd = SCR1_LSU_CMD_SW;
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct3
+`ifdef SCR1_RVE_EXT
+                        if (instr[19] | instr[24])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_STORE
+
+                    SCR1_OPCODE_OP              : begin
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                        case (funct7)
+                            7'b0000000 : begin
+                                case (funct3)
+                                    3'b000  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_ADD;
+                                    3'b001  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SLL;
+                                    3'b010  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SUB_LT;
+                                    3'b011  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SUB_LTU;
+                                    3'b100  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_XOR;
+                                    3'b101  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SRL;
+                                    3'b110  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_OR;
+                                    3'b111  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_AND;
+                                endcase // funct3
+                            end // 7'b0000000
+
+                            7'b0100000 : begin
+                                case (funct3)
+                                    3'b000  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SUB;
+                                    3'b101  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SRA;
+                                    default : rvi_illegal = 1'b1;
+                                endcase // funct3
+                            end // 7'b0100000
+`ifdef SCR1_RVM_EXT
+                            7'b0000001 : begin
+                                case (funct3)
+                                    3'b000  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_MUL;
+                                    3'b001  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_MULH;
+                                    3'b010  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_MULHSU;
+                                    3'b011  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_MULHU;
+                                    3'b100  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_DIV;
+                                    3'b101  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_DIVU;
+                                    3'b110  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_REM;
+                                    3'b111  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_REMU;
+                                endcase // funct3
+                            end // 7'b0000001
+`endif  // SCR1_RVM_EXT
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct7
+`ifdef SCR1_RVE_EXT
+                        if (instr[11] | instr[19] | instr[24])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_OP
+
+                    SCR1_OPCODE_OP_IMM          : begin
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.imm         = {{21{instr[31]}}, instr[30:20]};
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                        case (funct3)
+                            3'b000  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_ADD;        // ADDI
+                            3'b010  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SUB_LT;     // SLTI
+                            3'b011  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_SUB_LTU;    // SLTIU
+                            3'b100  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_XOR;        // XORI
+                            3'b110  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_OR;         // ORI
+                            3'b111  : idu2exu_cmd_o.ialu_cmd  = SCR1_IALU_CMD_AND;        // ANDI
+                            3'b001  : begin
+                                case (funct7)
+                                    7'b0000000  : begin
+                                        // SLLI
+                                        idu2exu_cmd_o.imm         = `SCR1_XLEN'(shamt);   // zero-extend
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SLL;
+                                    end
+                                    default     : rvi_illegal   = 1'b1;
+                                endcase // funct7
+                            end
+                            3'b101  : begin
+                                case (funct7)
+                                    7'b0000000  : begin
+                                        // SRLI
+                                        idu2exu_cmd_o.imm         = `SCR1_XLEN'(shamt);   // zero-extend
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SRL;
+                                    end
+                                    7'b0100000  : begin
+                                        // SRAI
+                                        idu2exu_cmd_o.imm         = `SCR1_XLEN'(shamt);   // zero-extend
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SRA;
+                                    end
+                                    default     : rvi_illegal   = 1'b1;
+                                endcase // funct7
+                            end
+                        endcase // funct3
+`ifdef SCR1_RVE_EXT
+                        if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_OP_IMM
+
+                    SCR1_OPCODE_MISC_MEM    : begin
+                        case (funct3)
+                            3'b000  : begin
+                                if (~|{instr[31:28], instr[19:15], instr[11:7]}) begin
+                                    // FENCE = NOP
+                                end
+                                else rvi_illegal = 1'b1;
+                            end
+                            3'b001  : begin
+                                if (~|{instr[31:15], instr[11:7]}) begin
+                                    // FENCE.I
+                                    idu2exu_cmd_o.fencei_req    = 1'b1;
+                                end
+                                else rvi_illegal = 1'b1;
+                            end
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct3
+                    end // SCR1_OPCODE_MISC_MEM
+
+                    SCR1_OPCODE_BRANCH          : begin
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.imm         = {{20{instr[31]}}, instr[7], instr[30:25], instr[11:8], 1'b0};
+                        idu2exu_cmd_o.branch_req  = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                        case (funct3)
+                            3'b000  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_EQ;
+                            3'b001  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_NE;
+                            3'b100  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_LT;
+                            3'b101  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_GE;
+                            3'b110  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_LTU;
+                            3'b111  : idu2exu_cmd_o.ialu_cmd = SCR1_IALU_CMD_SUB_GEU;
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct3
+`ifdef SCR1_RVE_EXT
+                        if (instr[19] | instr[24])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_BRANCH
+
+                    SCR1_OPCODE_JALR        : begin
+                        idu2exu_use_rs1_o     = 1'b1;
+                        idu2exu_use_rd_o      = 1'b1;
+                        idu2exu_use_imm_o     = 1'b1;
+                        case (funct3)
+                            3'b000  : begin
+                                // JALR
+                                idu2exu_cmd_o.sum2_op   = SCR1_SUM2_OP_REG_IMM;
+                                idu2exu_cmd_o.rd_wb_sel = SCR1_RD_WB_INC_PC;
+                                idu2exu_cmd_o.jump_req  = 1'b1;
+                                idu2exu_cmd_o.imm       = {{21{instr[31]}}, instr[30:20]};
+                            end
+                            default : rvi_illegal = 1'b1;
+                        endcase
+`ifdef SCR1_RVE_EXT
+                        if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end // SCR1_OPCODE_JALR
+
+                    SCR1_OPCODE_SYSTEM      : begin
+                        idu2exu_use_rd_o      = 1'b1;
+                        idu2exu_use_imm_o     = 1'b1;
+                        idu2exu_cmd_o.imm     = `SCR1_XLEN'({funct3, instr[31:20]});      // {funct3, CSR address}
+                        case (funct3)
+                            3'b000  : begin
+                                idu2exu_use_rd_o    = 1'b0;
+                                idu2exu_use_imm_o   = 1'b0;
+                                case ({instr[19:15], instr[11:7]})
+                                    10'd0 : begin
+                                        case (funct12)
+                                            12'h000 : begin
+                                                // ECALL
+                                                idu2exu_cmd_o.exc_req     = 1'b1;
+                                                idu2exu_cmd_o.exc_code    = SCR1_EXC_CODE_ECALL_M;
+                                            end
+                                            12'h001 : begin
+                                                // EBREAK
+                                                idu2exu_cmd_o.exc_req     = 1'b1;
+                                                idu2exu_cmd_o.exc_code    = SCR1_EXC_CODE_BREAKPOINT;
+                                            end
+                                            12'h302 : begin
+                                                // MRET
+                                                idu2exu_cmd_o.mret_req    = 1'b1;
+                                            end
+                                            12'h105 : begin
+                                                // WFI
+                                                idu2exu_cmd_o.wfi_req     = 1'b1;
+                                            end
+                                            default : rvi_illegal = 1'b1;
+                                        endcase // funct12
+                                    end
+                                    default : rvi_illegal = 1'b1;
+                                endcase // {instr[19:15], instr[11:7]}
+                            end
+                            3'b001  : begin
+                                // CSRRW
+                                idu2exu_use_rs1_o             = 1'b1;
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_WRITE;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_REG;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            3'b010  : begin
+                                // CSRRS
+                                idu2exu_use_rs1_o             = 1'b1;
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_SET;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_REG;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            3'b011  : begin
+                                // CSRRC
+                                idu2exu_use_rs1_o             = 1'b1;
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_CLEAR;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_REG;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11] | instr[19])  rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            3'b101  : begin
+                                // CSRRWI
+                                idu2exu_use_rs1_o             = 1'b1;             // zimm
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_WRITE;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_IMM;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11])              rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            3'b110  : begin
+                                // CSRRSI
+                                idu2exu_use_rs1_o             = 1'b1;             // zimm
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_SET;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_IMM;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11])              rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            3'b111  : begin
+                                // CSRRCI
+                                idu2exu_use_rs1_o             = 1'b1;             // zimm
+                                idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_CSR;
+                                idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_CLEAR;
+                                idu2exu_cmd_o.csr_op          = SCR1_CSR_OP_IMM;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11])              rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                            default : rvi_illegal = 1'b1;
+                        endcase // funct3
+                    end // SCR1_OPCODE_SYSTEM
+
+                    default : begin
+                        rvi_illegal = 1'b1;
+                    end
+                endcase // rvi_opcode
+            end // SCR1_INSTR_RVI
+
+`ifdef SCR1_RVC_EXT
+
+            // Quadrant 0
+            SCR1_INSTR_RVC0 : begin
+                idu2exu_cmd_o.instr_rvc   = 1'b1;
+                idu2exu_use_rs1_o         = 1'b1;
+                idu2exu_use_imm_o         = 1'b1;
+                case (funct3)
+                    3'b000  : begin
+                        if (~|instr[12:5])      rvc_illegal = 1'b1;
+                        // C.ADDI4SPN
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_ADD;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                        idu2exu_cmd_o.rs1_addr    = SCR1_MPRF_SP_ADDR;
+                        idu2exu_cmd_o.rd_addr     = {2'b01, instr[4:2]};
+                        idu2exu_cmd_o.imm         = {22'd0, instr[10:7], instr[12:11], instr[5], instr[6], 2'b00};
+                    end
+                    3'b010  : begin
+                        // C.LW
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.lsu_cmd     = SCR1_LSU_CMD_LW;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_LSU;
+                        idu2exu_cmd_o.rs1_addr    = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rd_addr     = {2'b01, instr[4:2]};
+                        idu2exu_cmd_o.imm         = {25'd0, instr[5], instr[12:10], instr[6], 2'b00};
+                    end
+                    3'b110  : begin
+                        // C.SW
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.lsu_cmd     = SCR1_LSU_CMD_SW;
+                        idu2exu_cmd_o.rs1_addr    = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rs2_addr    = {2'b01, instr[4:2]};
+                        idu2exu_cmd_o.imm         = {25'd0, instr[5], instr[12:10], instr[6], 2'b00};
+                    end
+                    default : begin
+                        rvc_illegal = 1'b1;
+                    end
+                endcase // funct3
+            end // Quadrant 0
+
+            // Quadrant 1
+            SCR1_INSTR_RVC1 : begin
+                idu2exu_cmd_o.instr_rvc   = 1'b1;
+                idu2exu_use_rd_o          = 1'b1;
+                idu2exu_use_imm_o         = 1'b1;
+                case (funct3)
+                    3'b000  : begin
+                        // C.ADDI / C.NOP
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_ADD;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                        idu2exu_cmd_o.rs1_addr    = instr[11:7];
+                        idu2exu_cmd_o.rd_addr     = instr[11:7];
+                        idu2exu_cmd_o.imm         = {{27{instr[12]}}, instr[6:2]};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end
+                    3'b001  : begin
+                        // C.JAL
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_INC_PC;
+                        idu2exu_cmd_o.jump_req    = 1'b1;
+                        idu2exu_cmd_o.rd_addr     = SCR1_MPRF_RA_ADDR;
+                        idu2exu_cmd_o.imm         = {{21{instr[12]}}, instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], 1'b0};
+                    end
+                    3'b010  : begin
+                        // C.LI
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IMM;
+                        idu2exu_cmd_o.rd_addr     = instr[11:7];
+                        idu2exu_cmd_o.imm         = {{27{instr[12]}}, instr[6:2]};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end
+                    3'b011  : begin
+                        if (~|{instr[12], instr[6:2]}) rvc_illegal = 1'b1;
+                        if (instr[11:7] == SCR1_MPRF_SP_ADDR) begin
+                            // C.ADDI16SP
+                            idu2exu_use_rs1_o         = 1'b1;
+                            idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_ADD;
+                            idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                            idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                            idu2exu_cmd_o.rs1_addr    = SCR1_MPRF_SP_ADDR;
+                            idu2exu_cmd_o.rd_addr     = SCR1_MPRF_SP_ADDR;
+                            idu2exu_cmd_o.imm         = {{23{instr[12]}}, instr[4:3], instr[5], instr[2], instr[6], 4'd0};
+                        end else begin
+                            // C.LUI
+                            idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IMM;
+                            idu2exu_cmd_o.rd_addr     = instr[11:7];
+                            idu2exu_cmd_o.imm         = {{15{instr[12]}}, instr[6:2], 12'd0};
+`ifdef SCR1_RVE_EXT
+                            if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                        end
+                    end
+                    3'b100  : begin
+                        idu2exu_cmd_o.rs1_addr    = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rd_addr     = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rs2_addr    = {2'b01, instr[4:2]};
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rd_o          = 1'b1;
+                        case (instr[11:10])
+                            2'b00   : begin
+                                if (instr[12])          rvc_illegal = 1'b1;
+                                // C.SRLI
+                                idu2exu_use_imm_o         = 1'b1;
+                                idu2exu_cmd_o.imm         = {27'd0, instr[6:2]};
+                                idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SRL;
+                                idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                            end
+                            2'b01   : begin
+                                if (instr[12])          rvc_illegal = 1'b1;
+                                // C.SRAI
+                                idu2exu_use_imm_o         = 1'b1;
+                                idu2exu_cmd_o.imm         = {27'd0, instr[6:2]};
+                                idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SRA;
+                                idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                            end
+                            2'b10   : begin
+                                // C.ANDI
+                                idu2exu_use_imm_o         = 1'b1;
+                                idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_AND;
+                                idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                idu2exu_cmd_o.imm         = {{27{instr[12]}}, instr[6:2]};
+                            end
+                            2'b11   : begin
+                                idu2exu_use_rs2_o         = 1'b1;
+                                case ({instr[12], instr[6:5]})
+                                    3'b000  : begin
+                                        // C.SUB
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SUB;
+                                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                    end
+                                    3'b001  : begin
+                                        // C.XOR
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_XOR;
+                                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                    end
+                                    3'b010  : begin
+                                        // C.OR
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_OR;
+                                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                    end
+                                    3'b011  : begin
+                                        // C.AND
+                                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_AND;
+                                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                    end
+                                    default : begin
+                                        rvc_illegal = 1'b1;
+                                    end
+                                endcase // {instr[12], instr[6:5]}
+                            end
+                        endcase // instr[11:10]
+                    end // funct3 == 3'b100
+                    3'b101  : begin
+                        // C.J
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.jump_req    = 1'b1;
+                        idu2exu_cmd_o.imm         = {{21{instr[12]}}, instr[8], instr[10:9], instr[6], instr[7], instr[2], instr[11], instr[5:3], 1'b0};
+                    end
+                    3'b110  : begin
+                        // C.BEQZ
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SUB_EQ;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.branch_req  = 1'b1;
+                        idu2exu_cmd_o.rs1_addr    = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rs2_addr    = SCR1_MPRF_ZERO_ADDR;
+                        idu2exu_cmd_o.imm         = {{24{instr[12]}}, instr[6:5], instr[2], instr[11:10], instr[4:3], 1'b0};
+                    end
+                    3'b111  : begin
+                        // C.BNEZ
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SUB_NE;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_PC_IMM;
+                        idu2exu_cmd_o.branch_req  = 1'b1;
+                        idu2exu_cmd_o.rs1_addr    = {2'b01, instr[9:7]};
+                        idu2exu_cmd_o.rs2_addr    = SCR1_MPRF_ZERO_ADDR;
+                        idu2exu_cmd_o.imm         = {{24{instr[12]}}, instr[6:5], instr[2], instr[11:10], instr[4:3], 1'b0};
+                    end
+                endcase // funct3
+            end // Quadrant 1
+
+            // Quadrant 2
+            SCR1_INSTR_RVC2 : begin
+                idu2exu_cmd_o.instr_rvc   = 1'b1;
+                idu2exu_use_rs1_o         = 1'b1;
+                case (funct3)
+                    3'b000  : begin
+                        if (instr[12])          rvc_illegal = 1'b1;
+                        // C.SLLI
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.rs1_addr    = instr[11:7];
+                        idu2exu_cmd_o.rd_addr     = instr[11:7];
+                        idu2exu_cmd_o.imm         = {27'd0, instr[6:2]};
+                        idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_SLL;
+                        idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_IMM;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end
+                    3'b010  : begin
+                        if (~|instr[11:7])      rvc_illegal = 1'b1;
+                        // C.LWSP
+                        idu2exu_use_rd_o          = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.lsu_cmd     = SCR1_LSU_CMD_LW;
+                        idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_LSU;
+                        idu2exu_cmd_o.rs1_addr    = SCR1_MPRF_SP_ADDR;
+                        idu2exu_cmd_o.rd_addr     = instr[11:7];
+                        idu2exu_cmd_o.imm         = {24'd0, instr[3:2], instr[12], instr[6:4], 2'b00};
+`ifdef SCR1_RVE_EXT
+                        if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end
+                    3'b100  : begin
+                        if (~instr[12]) begin
+                            if (|instr[6:2]) begin
+                                // C.MV
+                                idu2exu_use_rs2_o         = 1'b1;
+                                idu2exu_use_rd_o          = 1'b1;
+                                idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_ADD;
+                                idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                idu2exu_cmd_o.rs1_addr    = SCR1_MPRF_ZERO_ADDR;
+                                idu2exu_cmd_o.rs2_addr    = instr[6:2];
+                                idu2exu_cmd_o.rd_addr     = instr[11:7];
+`ifdef SCR1_RVE_EXT
+                                if (instr[11]|instr[6]) rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end else begin
+                                if (~|instr[11:7])      rvc_illegal = 1'b1;
+                                // C.JR
+                                idu2exu_use_imm_o         = 1'b1;
+                                idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                                idu2exu_cmd_o.jump_req    = 1'b1;
+                                idu2exu_cmd_o.rs1_addr    = instr[11:7];
+                                idu2exu_cmd_o.imm         = 0;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                        end else begin  // instr[12] == 1
+                            if (~|instr[11:2]) begin
+                                // C.EBREAK
+                                idu2exu_cmd_o.exc_req     = 1'b1;
+                                idu2exu_cmd_o.exc_code    = SCR1_EXC_CODE_BREAKPOINT;
+                            end else if (~|instr[6:2]) begin
+                                // C.JALR
+                                idu2exu_use_rs1_o         = 1'b1;
+                                idu2exu_use_rd_o          = 1'b1;
+                                idu2exu_use_imm_o         = 1'b1;
+                                idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_INC_PC;
+                                idu2exu_cmd_o.jump_req    = 1'b1;
+                                idu2exu_cmd_o.rs1_addr    = instr[11:7];
+                                idu2exu_cmd_o.rd_addr     = SCR1_MPRF_RA_ADDR;
+                                idu2exu_cmd_o.imm         = 0;
+`ifdef SCR1_RVE_EXT
+                                if (instr[11])          rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end else begin
+                                // C.ADD
+                                idu2exu_use_rs1_o         = 1'b1;
+                                idu2exu_use_rs2_o         = 1'b1;
+                                idu2exu_use_rd_o          = 1'b1;
+                                idu2exu_cmd_o.ialu_cmd    = SCR1_IALU_CMD_ADD;
+                                idu2exu_cmd_o.ialu_op     = SCR1_IALU_OP_REG_REG;
+                                idu2exu_cmd_o.rd_wb_sel   = SCR1_RD_WB_IALU;
+                                idu2exu_cmd_o.rs1_addr    = instr[11:7];
+                                idu2exu_cmd_o.rs2_addr    = instr[6:2];
+                                idu2exu_cmd_o.rd_addr     = instr[11:7];
+`ifdef SCR1_RVE_EXT
+                                if (instr[11]|instr[6]) rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                            end
+                        end // instr[12] == 1
+                    end
+                    3'b110  : begin
+                        // C.SWSP
+                        idu2exu_use_rs1_o         = 1'b1;
+                        idu2exu_use_rs2_o         = 1'b1;
+                        idu2exu_use_imm_o         = 1'b1;
+                        idu2exu_cmd_o.sum2_op     = SCR1_SUM2_OP_REG_IMM;
+                        idu2exu_cmd_o.lsu_cmd     = SCR1_LSU_CMD_SW;
+                        idu2exu_cmd_o.rs1_addr    = SCR1_MPRF_SP_ADDR;
+                        idu2exu_cmd_o.rs2_addr    = instr[6:2];
+                        idu2exu_cmd_o.imm         = {24'd0, instr[8:7], instr[12:9], 2'b00};
+`ifdef SCR1_RVE_EXT
+                        if (instr[6])           rve_illegal = 1'b1;
+`endif  // SCR1_RVE_EXT
+                    end
+                    default : begin
+                        rvc_illegal = 1'b1;
+                    end
+                endcase // funct3
+            end // Quadrant 2
+
+            default         : begin
+            end
+`else   // SCR1_RVC_EXT
+            default         : begin
+                idu2exu_cmd_o.instr_rvc   = 1'b1;
+                rvi_illegal             = 1'b1;
+            end
+`endif  // SCR1_RVC_EXT
+        endcase // instr_type
+    end // no imem fault
+
+    // At this point the instruction is fully decoded
+    // given that no imem fault has happened
+
+    // Check illegal instruction
+    if (
+    rvi_illegal
+`ifdef SCR1_RVC_EXT
+    | rvc_illegal
+`endif
+`ifdef SCR1_RVE_EXT
+    | rve_illegal
+`endif
+    ) begin
+        idu2exu_cmd_o.ialu_cmd        = SCR1_IALU_CMD_NONE;
+        idu2exu_cmd_o.lsu_cmd         = SCR1_LSU_CMD_NONE;
+        idu2exu_cmd_o.csr_cmd         = SCR1_CSR_CMD_NONE;
+        idu2exu_cmd_o.rd_wb_sel       = SCR1_RD_WB_NONE;
+        idu2exu_cmd_o.jump_req        = 1'b0;
+        idu2exu_cmd_o.branch_req      = 1'b0;
+        idu2exu_cmd_o.mret_req        = 1'b0;
+        idu2exu_cmd_o.fencei_req      = 1'b0;
+        idu2exu_cmd_o.wfi_req         = 1'b0;
+
+        idu2exu_use_rs1_o             = 1'b0;
+        idu2exu_use_rs2_o             = 1'b0;
+        idu2exu_use_rd_o              = 1'b0;
+
+`ifndef SCR1_MTVAL_ILLEGAL_INSTR_EN
+        idu2exu_use_imm_o             = 1'b0;
+`else // SCR1_MTVAL_ILLEGAL_INSTR_EN
+        idu2exu_use_imm_o             = 1'b1;
+        idu2exu_cmd_o.imm             = instr;
+`endif // SCR1_MTVAL_ILLEGAL_INSTR_EN
+
+        idu2exu_cmd_o.exc_req         = 1'b1;
+        idu2exu_cmd_o.exc_code        = SCR1_EXC_CODE_ILLEGAL_INSTR;
+    end
+
+end // RV32I(MC) decode
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+// X checks
+
+SCR1_SVA_IDU_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({ifu2idu_vd_i, exu2idu_rdy_i})
+    ) else $error("IDU Error: unknown values");
+
+SCR1_SVA_IDU_XCHECK2 : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ifu2idu_vd_i |-> !$isunknown({ifu2idu_imem_err_i, (ifu2idu_imem_err_i ? 0 : ifu2idu_instr_i)})
+    ) else $error("IDU Error: unknown values");
+
+// Behavior checks
+
+SCR1_SVA_IDU_IALU_CMD_RANGE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (ifu2idu_vd_i & ~ifu2idu_imem_err_i) |->
+    ((idu2exu_cmd_o.ialu_cmd >= SCR1_IALU_CMD_NONE) &
+    (idu2exu_cmd_o.ialu_cmd <=
+`ifdef SCR1_RVM_EXT
+                            SCR1_IALU_CMD_REMU
+`else
+                            SCR1_IALU_CMD_SRA
+`endif // SCR1_RVM_EXT
+        ))
+    ) else $error("IDU Error: IALU_CMD out of range");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_idu
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ifu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ifu.sv
new file mode 100644
index 0000000..740c4f6
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_ifu.sv
@@ -0,0 +1,826 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_ifu.sv>
+/// @brief      Instruction Fetch Unit (IFU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Controls instruction fetching process:
+ //   - Fetches instructions either from IMEM or from Program Buffer, supporting
+ //     pending IMEM instructions handling
+ //   - Handles new PC misalignment and constructs the correct instruction (supports
+ //     RVI and RVC instructions)
+ //   - Either stores instructions in the instruction queue or bypasses to the
+ //     IDU if the corresponding option is used
+ //   - Flushes instruction queue if requested
+ //
+ // Structure:
+ // - Instruction queue
+ // - IFU FSM
+ // - IFU <-> IMEM i/f
+ // - IFU <-> IDU i/f
+ // - IFU <-> HDU i/f
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_memif.svh"
+`include "scr1_arch_description.svh"
+`ifdef SCR1_DBG_EN
+`include "scr1_hdu.svh"
+`endif // SCR1_DBG_EN
+
+module scr1_pipe_ifu
+(
+    // Control signals
+    input   logic                                   rst_n,                      // IFU reset
+    input   logic                                   clk,                        // IFU clock
+    input   logic                                   pipe2ifu_stop_fetch_i,      // Stop instruction fetch
+
+    // IFU <-> IMEM interface
+    input   logic                                   imem2ifu_req_ack_i,         // Instruction memory request acknowledgement
+    output  logic                                   ifu2imem_req_o,             // Instruction memory request
+    output  type_scr1_mem_cmd_e                     ifu2imem_cmd_o,             // Instruction memory command (READ/WRITE)
+    output  logic [`SCR1_IMEM_AWIDTH-1:0]           ifu2imem_addr_o,            // Instruction memory address
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]           imem2ifu_rdata_i,           // Instruction memory read data
+    input   type_scr1_mem_resp_e                    imem2ifu_resp_i,            // Instruction memory response
+
+    // IFU <-> EXU New PC interface
+    input   logic                                   exu2ifu_pc_new_req_i,       // New PC request (jumps, branches, traps etc)
+    input   logic [`SCR1_XLEN-1:0]                  exu2ifu_pc_new_i,           // New PC
+
+`ifdef SCR1_DBG_EN
+    // IFU <-> HDU Program Buffer interface
+    input   logic                                   hdu2ifu_pbuf_fetch_i,       // Fetch instructions provided by Program Buffer
+    output  logic                                   ifu2hdu_pbuf_rdy_o,         // Program Buffer Instruction i/f ready
+    input   logic                                   hdu2ifu_pbuf_vd_i,          // Program Buffer Instruction valid
+    input   logic                                   hdu2ifu_pbuf_err_i,         // Program Buffer Instruction i/f error
+    input   logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]   hdu2ifu_pbuf_instr_i,       // Program Buffer Instruction itself
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_CLKCTRL_EN
+    output  logic                                   ifu2pipe_imem_txns_pnd_o,   // There are pending imem transactions
+`endif // SCR1_CLKCTRL_EN
+
+    // IFU <-> IDU interface
+    input   logic                                   idu2ifu_rdy_i,              // IDU ready for new data
+    output  logic [`SCR1_IMEM_DWIDTH-1:0]           ifu2idu_instr_o,            // IFU instruction
+    output  logic                                   ifu2idu_imem_err_o,         // Instruction access fault exception
+    output  logic                                   ifu2idu_err_rvi_hi_o,       // 1 - imem fault when trying to fetch second half of an unaligned RVI instruction
+    output  logic                                   ifu2idu_vd_o                // IFU request
+);
+
+//------------------------------------------------------------------------------
+// Local parameters declaration
+//------------------------------------------------------------------------------
+
+localparam SCR1_IFU_Q_SIZE_WORD     = 2;
+localparam SCR1_IFU_Q_SIZE_HALF     = SCR1_IFU_Q_SIZE_WORD * 2;
+localparam SCR1_TXN_CNT_W           = 3;
+
+localparam SCR1_IFU_QUEUE_ADR_W     = $clog2(SCR1_IFU_Q_SIZE_HALF);
+localparam SCR1_IFU_QUEUE_PTR_W     = SCR1_IFU_QUEUE_ADR_W + 1;
+
+localparam SCR1_IFU_Q_FREE_H_W      = $clog2(SCR1_IFU_Q_SIZE_HALF + 1);
+localparam SCR1_IFU_Q_FREE_W_W      = $clog2(SCR1_IFU_Q_SIZE_WORD + 1);
+
+//------------------------------------------------------------------------------
+// Local types declaration
+//------------------------------------------------------------------------------
+
+typedef enum logic {
+    SCR1_IFU_FSM_IDLE,
+    SCR1_IFU_FSM_FETCH
+} type_scr1_ifu_fsm_e;
+
+typedef enum logic[1:0] {
+    SCR1_IFU_QUEUE_WR_NONE,      // No write to queue
+    SCR1_IFU_QUEUE_WR_FULL,      // Write 32 rdata bits to queue
+    SCR1_IFU_QUEUE_WR_HI         // Write 16 upper rdata bits to queue
+} type_scr1_ifu_queue_wr_e;
+
+typedef enum logic[1:0] {
+    SCR1_IFU_QUEUE_RD_NONE,      // No queue read
+    SCR1_IFU_QUEUE_RD_HWORD,     // Read halfword
+    SCR1_IFU_QUEUE_RD_WORD       // Read word
+} type_scr1_ifu_queue_rd_e;
+
+`ifdef SCR1_NO_DEC_STAGE
+typedef enum logic[1:0] {
+    SCR1_BYPASS_NONE,               // No bypass
+    SCR1_BYPASS_RVC,                // Bypass RVC
+    SCR1_BYPASS_RVI_RDATA_QUEUE,    // Bypass RVI, rdata+queue
+    SCR1_BYPASS_RVI_RDATA           // Bypass RVI, rdata only
+} type_scr1_bypass_e;
+`endif // SCR1_NO_DEC_STAGE
+
+typedef enum logic [2:0] {
+    // SCR1_IFU_INSTR_<UPPER_16_BITS>_<LOWER_16_BITS>
+    SCR1_IFU_INSTR_NONE,                // No valid instruction
+    SCR1_IFU_INSTR_RVI_HI_RVI_LO,       // Full RV32I instruction
+    SCR1_IFU_INSTR_RVC_RVC,
+    SCR1_IFU_INSTR_RVI_LO_RVC,
+    SCR1_IFU_INSTR_RVC_RVI_HI,
+    SCR1_IFU_INSTR_RVI_LO_RVI_HI,
+    SCR1_IFU_INSTR_RVC_NV,              // Instruction after unaligned new_pc
+    SCR1_IFU_INSTR_RVI_LO_NV            // Instruction after unaligned new_pc
+} type_scr1_ifu_instr_e;
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// Instruction queue signals
+//------------------------------------------------------------------------------
+
+// New PC unaligned flag register
+logic                               new_pc_unaligned_ff;
+logic                               new_pc_unaligned_next;
+logic                               new_pc_unaligned_upd;
+
+// IMEM instruction type decoder
+logic                               instr_hi_is_rvi;
+logic                               instr_lo_is_rvi;
+type_scr1_ifu_instr_e               instr_type;
+
+// Register to store if the previous IMEM instruction had low part of RVI instruction
+// in its high part
+logic                               instr_hi_rvi_lo_ff;
+logic                               instr_hi_rvi_lo_next;
+
+// Queue read/write size decoders
+type_scr1_ifu_queue_rd_e            q_rd_size;
+logic                               q_rd_vd;
+logic                               q_rd_none;
+logic                               q_rd_hword;
+type_scr1_ifu_queue_wr_e            q_wr_size;
+logic                               q_wr_none;
+logic                               q_wr_full;
+
+// Write/read pointer registers
+logic [SCR1_IFU_QUEUE_PTR_W-1:0]    q_rptr;
+logic [SCR1_IFU_QUEUE_PTR_W-1:0]    q_rptr_next;
+logic                               q_rptr_upd;
+logic [SCR1_IFU_QUEUE_PTR_W-1:0]    q_wptr;
+logic [SCR1_IFU_QUEUE_PTR_W-1:0]    q_wptr_next;
+logic                               q_wptr_upd;
+
+// Instruction queue control signals
+logic                               q_wr_en;
+logic                               q_flush_req;
+
+// Queue data registers
+logic [`SCR1_IMEM_DWIDTH/2-1:0]     q_data  [SCR1_IFU_Q_SIZE_HALF];
+logic [`SCR1_IMEM_DWIDTH/2-1:0]     q_data_head;
+logic [`SCR1_IMEM_DWIDTH/2-1:0]     q_data_next;
+
+// Queue error flags registers
+logic                               q_err   [SCR1_IFU_Q_SIZE_HALF];
+logic                               q_err_head;
+logic                               q_err_next;
+
+// Instruction queue status signals
+logic                               q_is_empty;
+logic                               q_has_free_slots;
+logic                               q_has_1_ocpd_hw;
+logic                               q_head_is_rvc;
+logic                               q_head_is_rvi;
+logic [SCR1_IFU_Q_FREE_H_W-1:0]     q_ocpd_h;
+logic [SCR1_IFU_Q_FREE_H_W-1:0]     q_free_h_next;
+logic [SCR1_IFU_Q_FREE_W_W-1:0]     q_free_w_next;
+
+// IFU FSM signals
+//------------------------------------------------------------------------------
+
+// IFU FSM control signals
+logic                               ifu_fetch_req;
+logic                               ifu_stop_req;
+
+type_scr1_ifu_fsm_e                 ifu_fsm_curr;
+type_scr1_ifu_fsm_e                 ifu_fsm_next;
+logic                               ifu_fsm_fetch;
+
+// IMEM signals
+//------------------------------------------------------------------------------
+
+// IMEM response signals
+logic                               imem_resp_ok;
+logic                               imem_resp_er;
+logic                               imem_resp_er_discard_pnd;
+logic                               imem_resp_discard_req;
+logic                               imem_resp_received;
+logic                               imem_resp_vd;
+logic                               imem_handshake_done;
+
+logic [15:0]                        imem_rdata_lo;
+logic [31:16]                       imem_rdata_hi;
+
+// IMEM address signals
+logic                               imem_addr_upd;
+logic [`SCR1_XLEN-1:2]              imem_addr_ff;
+logic [`SCR1_XLEN-1:2]              imem_addr_next;
+
+// IMEM pending transactions counter
+logic                               imem_pnd_txns_cnt_upd;
+logic [SCR1_TXN_CNT_W-1:0]          imem_pnd_txns_cnt;
+logic [SCR1_TXN_CNT_W-1:0]          imem_pnd_txns_cnt_next;
+logic [SCR1_TXN_CNT_W-1:0]          imem_vd_pnd_txns_cnt;
+logic                               imem_pnd_txns_q_full;
+
+// IMEM responses discard counter
+logic                               imem_resp_discard_cnt_upd;
+logic [SCR1_TXN_CNT_W-1:0]          imem_resp_discard_cnt;
+logic [SCR1_TXN_CNT_W-1:0]          imem_resp_discard_cnt_next;
+
+`ifdef SCR1_NEW_PC_REG
+logic                               new_pc_req_ff;
+`endif // SCR1_NEW_PC_REG
+
+// Instruction bypass signals
+`ifdef SCR1_NO_DEC_STAGE
+type_scr1_bypass_e                  instr_bypass_type;
+logic                               instr_bypass_vd;
+`endif // SCR1_NO_DEC_STAGE
+
+//------------------------------------------------------------------------------
+// Instruction queue
+//------------------------------------------------------------------------------
+//
+ // Instruction queue consists of the following functional units:
+ // - New PC unaligned flag register
+ // - Instruction type decoder, including register to store if the previous
+ //   IMEM instruction had low part of RVI instruction in its high part
+ // - Read/write size decoders
+ // - Read/write pointer registers
+ // - Data and error flag registers
+ // - Status logic
+//
+
+// New PC unaligned flag register
+//------------------------------------------------------------------------------
+
+assign new_pc_unaligned_upd = exu2ifu_pc_new_req_i | imem_resp_vd;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        new_pc_unaligned_ff <= 1'b0;
+    end else if (new_pc_unaligned_upd) begin
+        new_pc_unaligned_ff <= new_pc_unaligned_next;
+    end
+end
+
+assign new_pc_unaligned_next = exu2ifu_pc_new_req_i ? exu2ifu_pc_new_i[1]
+                             : ~imem_resp_vd        ? new_pc_unaligned_ff
+                                                    : 1'b0;
+
+// Instruction type decoder
+//------------------------------------------------------------------------------
+
+assign instr_hi_is_rvi = &imem2ifu_rdata_i[17:16];
+assign instr_lo_is_rvi = &imem2ifu_rdata_i[1:0];
+
+always_comb begin
+    instr_type = SCR1_IFU_INSTR_NONE;
+
+    if (imem_resp_ok & ~imem_resp_discard_req) begin
+        if (new_pc_unaligned_ff) begin
+            instr_type = instr_hi_is_rvi ? SCR1_IFU_INSTR_RVI_LO_NV
+                                         : SCR1_IFU_INSTR_RVC_NV;
+        end else begin // ~new_pc_unaligned_ff
+            if (instr_hi_rvi_lo_ff) begin
+                instr_type = instr_hi_is_rvi ? SCR1_IFU_INSTR_RVI_LO_RVI_HI
+                                             : SCR1_IFU_INSTR_RVC_RVI_HI;
+            end else begin // SCR1_OTHER
+                casez ({instr_hi_is_rvi, instr_lo_is_rvi})
+                    2'b?1   : instr_type   = SCR1_IFU_INSTR_RVI_HI_RVI_LO;
+                    2'b00   : instr_type   = SCR1_IFU_INSTR_RVC_RVC;
+                    2'b10   : instr_type   = SCR1_IFU_INSTR_RVI_LO_RVC;
+                endcase
+            end
+        end
+    end
+end
+
+// Register to store if the previous IMEM instruction had low part of RVI
+// instruction in its high part
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        instr_hi_rvi_lo_ff <= 1'b0;
+    end else begin
+        if (exu2ifu_pc_new_req_i) begin
+            instr_hi_rvi_lo_ff <= 1'b0;
+        end else if (imem_resp_vd) begin
+            instr_hi_rvi_lo_ff <= instr_hi_rvi_lo_next;
+        end
+    end
+end
+
+assign instr_hi_rvi_lo_next = (instr_type == SCR1_IFU_INSTR_RVI_LO_NV)
+                            | (instr_type == SCR1_IFU_INSTR_RVI_LO_RVI_HI)
+                            | (instr_type == SCR1_IFU_INSTR_RVI_LO_RVC);
+
+// Queue write/read size decoders
+//------------------------------------------------------------------------------
+
+// Queue read size decoder
+assign q_rd_vd    = ~q_is_empty & ifu2idu_vd_o & idu2ifu_rdy_i;
+assign q_rd_hword = q_head_is_rvc | q_err_head
+`ifdef SCR1_NO_DEC_STAGE
+                  | (q_head_is_rvi & instr_bypass_vd)
+`endif // SCR1_NO_DEC_STAGE
+                  ;
+assign q_rd_size  = ~q_rd_vd   ? SCR1_IFU_QUEUE_RD_NONE
+                  : q_rd_hword ? SCR1_IFU_QUEUE_RD_HWORD
+                               : SCR1_IFU_QUEUE_RD_WORD;
+assign q_rd_none  = (q_rd_size == SCR1_IFU_QUEUE_RD_NONE);
+
+// Queue write size decoder
+always_comb begin
+    q_wr_size = SCR1_IFU_QUEUE_WR_NONE;
+    if (~imem_resp_discard_req) begin
+        if (imem_resp_ok) begin
+`ifdef SCR1_NO_DEC_STAGE
+            case (instr_type)
+                SCR1_IFU_INSTR_NONE         : q_wr_size = SCR1_IFU_QUEUE_WR_NONE;
+                SCR1_IFU_INSTR_RVI_LO_NV    : q_wr_size = SCR1_IFU_QUEUE_WR_HI;
+                SCR1_IFU_INSTR_RVC_NV       : q_wr_size = (instr_bypass_vd & idu2ifu_rdy_i)
+                                                        ? SCR1_IFU_QUEUE_WR_NONE
+                                                        : SCR1_IFU_QUEUE_WR_HI;
+                SCR1_IFU_INSTR_RVI_HI_RVI_LO: q_wr_size = (instr_bypass_vd & idu2ifu_rdy_i)
+                                                        ? SCR1_IFU_QUEUE_WR_NONE
+                                                        : SCR1_IFU_QUEUE_WR_FULL;
+                SCR1_IFU_INSTR_RVC_RVC,
+                SCR1_IFU_INSTR_RVI_LO_RVC,
+                SCR1_IFU_INSTR_RVC_RVI_HI,
+                SCR1_IFU_INSTR_RVI_LO_RVI_HI: q_wr_size = (instr_bypass_vd & idu2ifu_rdy_i)
+                                                        ? SCR1_IFU_QUEUE_WR_HI
+                                                        : SCR1_IFU_QUEUE_WR_FULL;
+            endcase // instr_type
+`else // SCR1_NO_DEC_STAGE
+            case (instr_type)
+                SCR1_IFU_INSTR_NONE         : q_wr_size = SCR1_IFU_QUEUE_WR_NONE;
+                SCR1_IFU_INSTR_RVC_NV,
+                SCR1_IFU_INSTR_RVI_LO_NV    : q_wr_size = SCR1_IFU_QUEUE_WR_HI;
+                default                     : q_wr_size = SCR1_IFU_QUEUE_WR_FULL;
+            endcase // instr_type
+`endif // SCR1_NO_DEC_STAGE
+        end else if (imem_resp_er) begin
+            q_wr_size = SCR1_IFU_QUEUE_WR_FULL;
+        end // imem_resp_er
+    end // ~imem_resp_discard_req
+end
+
+assign q_wr_none   = (q_wr_size == SCR1_IFU_QUEUE_WR_NONE);
+assign q_wr_full   = (q_wr_size == SCR1_IFU_QUEUE_WR_FULL);
+
+// Write/read pointer registers
+//------------------------------------------------------------------------------
+
+assign q_flush_req = exu2ifu_pc_new_req_i | pipe2ifu_stop_fetch_i;
+
+// Queue write pointer register
+assign q_wptr_upd  = q_flush_req | ~q_wr_none;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        q_wptr <= '0;
+    end else if (q_wptr_upd) begin
+        q_wptr <= q_wptr_next;
+    end
+end
+
+assign q_wptr_next = q_flush_req ? '0
+                   : ~q_wr_none  ? q_wptr + (q_wr_full ? 2'd2 : 1'b1)
+                                 : q_wptr;
+
+// Queue read pointer register
+assign q_rptr_upd  = q_flush_req | ~q_rd_none;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        q_rptr <= '0;
+    end else if (q_rptr_upd) begin
+        q_rptr <= q_rptr_next;
+    end
+end
+
+assign q_rptr_next = q_flush_req ? '0
+                   : ~q_rd_none  ? q_rptr + (q_rd_hword ? 1'b1 : 2'd2)
+                                 : q_rptr;
+
+// Queue data and error flag registers
+//------------------------------------------------------------------------------
+
+assign imem_rdata_hi = imem2ifu_rdata_i[31:16];
+assign imem_rdata_lo = imem2ifu_rdata_i[15:0];
+
+assign q_wr_en = imem_resp_vd & ~q_flush_req;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        q_data  <= '{SCR1_IFU_Q_SIZE_HALF{'0}};
+        q_err   <= '{SCR1_IFU_Q_SIZE_HALF{1'b0}};
+    end else if (q_wr_en) begin
+        case (q_wr_size)
+            SCR1_IFU_QUEUE_WR_HI    : begin
+                q_data[SCR1_IFU_QUEUE_ADR_W'(q_wptr)]         <= imem_rdata_hi;
+                q_err [SCR1_IFU_QUEUE_ADR_W'(q_wptr)]         <= imem_resp_er;
+            end
+            SCR1_IFU_QUEUE_WR_FULL  : begin
+                q_data[SCR1_IFU_QUEUE_ADR_W'(q_wptr)]         <= imem_rdata_lo;
+                q_err [SCR1_IFU_QUEUE_ADR_W'(q_wptr)]         <= imem_resp_er;
+                q_data[SCR1_IFU_QUEUE_ADR_W'(q_wptr + 1'b1)]  <= imem_rdata_hi;
+                q_err [SCR1_IFU_QUEUE_ADR_W'(q_wptr + 1'b1)]  <= imem_resp_er;
+            end
+        endcase
+    end
+end
+
+assign q_data_head = q_data [SCR1_IFU_QUEUE_ADR_W'(q_rptr)];
+assign q_data_next = q_data [SCR1_IFU_QUEUE_ADR_W'(q_rptr + 1'b1)];
+assign q_err_head  = q_err  [SCR1_IFU_QUEUE_ADR_W'(q_rptr)];
+assign q_err_next  = q_err  [SCR1_IFU_QUEUE_ADR_W'(q_rptr + 1'b1)];
+
+// Queue status logic
+//------------------------------------------------------------------------------
+
+assign q_ocpd_h         = SCR1_IFU_Q_FREE_H_W'(q_wptr - q_rptr);
+assign q_free_h_next    = SCR1_IFU_Q_FREE_H_W'(SCR1_IFU_Q_SIZE_HALF - (q_wptr - q_rptr_next));
+assign q_free_w_next    = SCR1_IFU_Q_FREE_W_W'(q_free_h_next >> 1'b1);
+
+assign q_is_empty       = (q_rptr == q_wptr);
+assign q_has_free_slots = (SCR1_TXN_CNT_W'(q_free_w_next) > imem_vd_pnd_txns_cnt);
+assign q_has_1_ocpd_hw  = (q_ocpd_h == SCR1_IFU_Q_FREE_H_W'(1));
+
+assign q_head_is_rvi    = &(q_data_head[1:0]);
+assign q_head_is_rvc    = ~q_head_is_rvi;
+
+//------------------------------------------------------------------------------
+// IFU FSM
+//------------------------------------------------------------------------------
+
+// IFU FSM control signals
+assign ifu_fetch_req = exu2ifu_pc_new_req_i & ~pipe2ifu_stop_fetch_i;
+assign ifu_stop_req  = pipe2ifu_stop_fetch_i
+                     | (imem_resp_er_discard_pnd & ~exu2ifu_pc_new_req_i);
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        ifu_fsm_curr <= SCR1_IFU_FSM_IDLE;
+    end else begin
+        ifu_fsm_curr <= ifu_fsm_next;
+    end
+end
+
+always_comb begin
+    case (ifu_fsm_curr)
+        SCR1_IFU_FSM_IDLE   : begin
+            ifu_fsm_next = ifu_fetch_req ? SCR1_IFU_FSM_FETCH
+                                         : SCR1_IFU_FSM_IDLE;
+        end
+        SCR1_IFU_FSM_FETCH  : begin
+            ifu_fsm_next = ifu_stop_req  ? SCR1_IFU_FSM_IDLE
+                                         : SCR1_IFU_FSM_FETCH;
+        end
+    endcase
+end
+
+assign ifu_fsm_fetch = (ifu_fsm_curr == SCR1_IFU_FSM_FETCH);
+
+//------------------------------------------------------------------------------
+// IFU <-> IMEM interface
+//------------------------------------------------------------------------------
+//
+ // IFU <-> IMEM interface consists of the following functional units:
+ // - IMEM response logic
+ // - IMEM address register
+ // - Pending IMEM transactions counter
+ // - IMEM discard responses counter
+ // - IFU <-> IMEM interface output signals
+//
+
+// IMEM response logic
+//------------------------------------------------------------------------------
+
+assign imem_resp_er             = (imem2ifu_resp_i == SCR1_MEM_RESP_RDY_ER);
+assign imem_resp_ok             = (imem2ifu_resp_i == SCR1_MEM_RESP_RDY_OK);
+assign imem_resp_received       = imem_resp_ok | imem_resp_er;
+assign imem_resp_vd             = imem_resp_received & ~imem_resp_discard_req;
+assign imem_resp_er_discard_pnd = imem_resp_er & ~imem_resp_discard_req;
+
+assign imem_handshake_done = ifu2imem_req_o & imem2ifu_req_ack_i;
+
+// IMEM address register
+//------------------------------------------------------------------------------
+
+assign imem_addr_upd = imem_handshake_done | exu2ifu_pc_new_req_i;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        imem_addr_ff <= '0;
+    end else if (imem_addr_upd) begin
+        imem_addr_ff <= imem_addr_next;
+    end
+end
+
+`ifndef SCR1_NEW_PC_REG
+assign imem_addr_next = exu2ifu_pc_new_req_i ? exu2ifu_pc_new_i[`SCR1_XLEN-1:2]                 + imem_handshake_done
+                      : &imem_addr_ff[5:2]   ? imem_addr_ff                                     + imem_handshake_done
+                                             : {imem_addr_ff[`SCR1_XLEN-1:6], imem_addr_ff[5:2] + imem_handshake_done};
+`else // SCR1_NEW_PC_REG
+assign imem_addr_next = exu2ifu_pc_new_req_i ? exu2ifu_pc_new_i[`SCR1_XLEN-1:2]
+                      : &imem_addr_ff[5:2]   ? imem_addr_ff                                     + imem_handshake_done
+                                             : {imem_addr_ff[`SCR1_XLEN-1:6], imem_addr_ff[5:2] + imem_handshake_done};
+`endif // SCR1_NEW_PC_REG
+
+// Pending IMEM transactions counter
+//------------------------------------------------------------------------------
+// Pending IMEM transactions occur if IFU request has been acknowledged, but
+// response comes in the next cycle or later
+
+assign imem_pnd_txns_cnt_upd  = imem_handshake_done ^ imem_resp_received;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        imem_pnd_txns_cnt <= '0;
+    end else if (imem_pnd_txns_cnt_upd) begin
+        imem_pnd_txns_cnt <= imem_pnd_txns_cnt_next;
+    end
+end
+
+assign imem_pnd_txns_cnt_next = imem_pnd_txns_cnt + (imem_handshake_done - imem_resp_received);
+assign imem_pnd_txns_q_full   = &imem_pnd_txns_cnt;
+
+// IMEM discard responses counter
+//------------------------------------------------------------------------------
+// IMEM instructions should be discarded in the following 2 cases:
+// 1. New PC is requested by jump, branch, mret or other instruction
+// 2. IMEM response was erroneous and not discarded
+//
+// In both cases the number of instructions to be discarded equals to the number
+// of pending instructions.
+// In the 1st case we don't need all the instructions that haven't been fetched
+// yet, since the PC has changed.
+// In the 2nd case, since the IMEM responce was erroneous there is no guarantee
+// that subsequent IMEM instructions would be valid.
+
+assign imem_resp_discard_cnt_upd = exu2ifu_pc_new_req_i | imem_resp_er
+                                 | (imem_resp_ok & imem_resp_discard_req);
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        imem_resp_discard_cnt <= '0;
+    end else if (imem_resp_discard_cnt_upd) begin
+        imem_resp_discard_cnt <= imem_resp_discard_cnt_next;
+    end
+end
+
+`ifndef SCR1_NEW_PC_REG
+assign imem_resp_discard_cnt_next = exu2ifu_pc_new_req_i     ? imem_pnd_txns_cnt_next - imem_handshake_done
+                                  : imem_resp_er_discard_pnd ? imem_pnd_txns_cnt_next
+                                                             : imem_resp_discard_cnt - 1'b1;
+`else // SCR1_NEW_PC_REG
+assign imem_resp_discard_cnt_next = exu2ifu_pc_new_req_i | imem_resp_er_discard_pnd
+                                  ? imem_pnd_txns_cnt_next
+                                  : imem_resp_discard_cnt - 1'b1;
+`endif // SCR1_NEW_PC_REG
+
+assign imem_vd_pnd_txns_cnt  = imem_pnd_txns_cnt - imem_resp_discard_cnt;
+assign imem_resp_discard_req = |imem_resp_discard_cnt;
+
+// IFU <-> IMEM interface output signals
+//------------------------------------------------------------------------------
+
+`ifndef SCR1_NEW_PC_REG
+assign ifu2imem_req_o  = (exu2ifu_pc_new_req_i & ~imem_pnd_txns_q_full & ~pipe2ifu_stop_fetch_i)
+                       | (ifu_fsm_fetch        & ~imem_pnd_txns_q_full & q_has_free_slots);
+assign ifu2imem_addr_o = exu2ifu_pc_new_req_i
+                       ? {exu2ifu_pc_new_i[`SCR1_XLEN-1:2], 2'b00}
+                       : {imem_addr_ff, 2'b00};
+`else // SCR1_NEW_PC_REG
+assign ifu2imem_req_o  = ifu_fsm_fetch & ~imem_pnd_txns_q_full & q_has_free_slots;
+assign ifu2imem_addr_o = {imem_addr_ff, 2'b00};
+`endif // SCR1_NEW_PC_REG
+
+assign ifu2imem_cmd_o  = SCR1_MEM_CMD_RD;
+
+`ifdef SCR1_CLKCTRL_EN
+assign ifu2pipe_imem_txns_pnd_o = |imem_pnd_txns_cnt;
+`endif // SCR1_CLKCTRL_EN
+
+//------------------------------------------------------------------------------
+// IFU <-> IDU interface
+//------------------------------------------------------------------------------
+//
+ // IFU <-> IDU interface consists of the following functional units:
+ // - Instruction bypass type decoder
+ // - IFU <-> IDU status signals
+ // - Output instruction multiplexer
+//
+
+`ifdef SCR1_NO_DEC_STAGE
+
+// Instruction bypass type decoder
+//------------------------------------------------------------------------------
+
+assign instr_bypass_vd  = (instr_bypass_type != SCR1_BYPASS_NONE);
+
+always_comb begin
+    instr_bypass_type    = SCR1_BYPASS_NONE;
+
+    if (imem_resp_vd) begin
+        if (q_is_empty) begin
+            case (instr_type)
+                SCR1_IFU_INSTR_RVC_NV,
+                SCR1_IFU_INSTR_RVC_RVC,
+                SCR1_IFU_INSTR_RVI_LO_RVC       : begin
+                    instr_bypass_type = SCR1_BYPASS_RVC;
+                end
+                SCR1_IFU_INSTR_RVI_HI_RVI_LO    : begin
+                    instr_bypass_type = SCR1_BYPASS_RVI_RDATA;
+                end
+                default : begin end
+            endcase // instr_type
+        end else if (q_has_1_ocpd_hw & q_head_is_rvi) begin
+            if (instr_hi_rvi_lo_ff) begin
+                instr_bypass_type = SCR1_BYPASS_RVI_RDATA_QUEUE;
+            end
+        end
+    end // imem_resp_vd
+end
+
+// IFU <-> IDU interface status signals
+//------------------------------------------------------------------------------
+
+always_comb begin
+    ifu2idu_vd_o         = 1'b0;
+    ifu2idu_imem_err_o   = 1'b0;
+    ifu2idu_err_rvi_hi_o = 1'b0;
+
+    if (ifu_fsm_fetch | ~q_is_empty) begin
+        if (instr_bypass_vd) begin
+            ifu2idu_vd_o          = 1'b1;
+            ifu2idu_imem_err_o    = (instr_bypass_type == SCR1_BYPASS_RVI_RDATA_QUEUE)
+                                  ? (imem_resp_er | q_err_head)
+                                  : imem_resp_er;
+            ifu2idu_err_rvi_hi_o  = (instr_bypass_type == SCR1_BYPASS_RVI_RDATA_QUEUE) & imem_resp_er;
+        end else if (~q_is_empty) begin
+            if (q_has_1_ocpd_hw) begin
+                ifu2idu_vd_o         = q_head_is_rvc | q_err_head;
+                ifu2idu_imem_err_o   = q_err_head;
+                ifu2idu_err_rvi_hi_o = ~q_err_head & q_head_is_rvi & q_err_next;
+            end else begin
+                ifu2idu_vd_o         = 1'b1;
+                ifu2idu_imem_err_o   = q_err_head ? 1'b1 : (q_head_is_rvi & q_err_next);
+            end
+        end // ~q_is_empty
+    end
+`ifdef SCR1_DBG_EN
+    if (hdu2ifu_pbuf_fetch_i) begin
+        ifu2idu_vd_o          = hdu2ifu_pbuf_vd_i;
+        ifu2idu_imem_err_o    = hdu2ifu_pbuf_err_i;
+    end
+`endif // SCR1_DBG_EN
+end
+
+// Output instruction multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (instr_bypass_type)
+        SCR1_BYPASS_RVC            : begin
+            ifu2idu_instr_o = `SCR1_IMEM_DWIDTH'(new_pc_unaligned_ff ? imem_rdata_hi
+                                                                     : imem_rdata_lo);
+        end
+        SCR1_BYPASS_RVI_RDATA      : begin
+            ifu2idu_instr_o = imem2ifu_rdata_i;
+        end
+        SCR1_BYPASS_RVI_RDATA_QUEUE: begin
+            ifu2idu_instr_o = {imem_rdata_lo, q_data_head};
+        end
+        default                    : begin
+            ifu2idu_instr_o = `SCR1_IMEM_DWIDTH'(q_head_is_rvc ? q_data_head
+                                                               : {q_data_next, q_data_head});
+        end
+    endcase // instr_bypass_type
+`ifdef SCR1_DBG_EN
+    if (hdu2ifu_pbuf_fetch_i) begin
+        ifu2idu_instr_o = `SCR1_IMEM_DWIDTH'({'0, hdu2ifu_pbuf_instr_i});
+    end
+`endif // SCR1_DBG_EN
+end
+
+`else   // SCR1_NO_DEC_STAGE
+
+// IFU <-> IDU interface status signals
+//------------------------------------------------------------------------------
+
+always_comb begin
+    ifu2idu_vd_o          = 1'b0;
+    ifu2idu_imem_err_o    = 1'b0;
+    ifu2idu_err_rvi_hi_o  = 1'b0;
+    if (~q_is_empty) begin
+        if (q_has_1_ocpd_hw) begin
+            ifu2idu_vd_o          = q_head_is_rvc | q_err_head;
+            ifu2idu_imem_err_o    = q_err_head;
+        end else begin
+            ifu2idu_vd_o          = 1'b1;
+            ifu2idu_imem_err_o    = q_err_head ? 1'b1 : (q_head_is_rvi & q_err_next);
+            ifu2idu_err_rvi_hi_o  = ~q_err_head & q_head_is_rvi & q_err_next;
+        end
+    end // ~q_is_empty
+`ifdef SCR1_DBG_EN
+    if (hdu2ifu_pbuf_fetch_i) begin
+        ifu2idu_vd_o          = hdu2ifu_pbuf_vd_i;
+        ifu2idu_imem_err_o    = hdu2ifu_pbuf_err_i;
+    end
+`endif // SCR1_DBG_EN
+end
+
+// Output instruction multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    ifu2idu_instr_o = q_head_is_rvc ? `SCR1_IMEM_DWIDTH'(q_data_head)
+                                    : {q_data_next, q_data_head};
+`ifdef SCR1_DBG_EN
+    if (hdu2ifu_pbuf_fetch_i) begin
+        ifu2idu_instr_o = `SCR1_IMEM_DWIDTH'({'0, hdu2ifu_pbuf_instr_i});
+    end
+`endif // SCR1_DBG_EN
+end
+
+`endif  // SCR1_NO_DEC_STAGE
+
+`ifdef SCR1_DBG_EN
+assign ifu2hdu_pbuf_rdy_o = idu2ifu_rdy_i;
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+
+//------------------------------------------------------------------------------
+// Assertions
+//------------------------------------------------------------------------------
+
+// X checks
+
+SCR1_SVA_IFU_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({imem2ifu_req_ack_i, idu2ifu_rdy_i, exu2ifu_pc_new_req_i})
+    ) else $error("IFU Error: unknown values");
+
+SCR1_SVA_IFU_XCHECK_REQ : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ifu2imem_req_o |-> !$isunknown({ifu2imem_addr_o, ifu2imem_cmd_o})
+    ) else $error("IFU Error: unknown {ifu2imem_addr_o, ifu2imem_cmd_o}");
+
+// Behavior checks
+
+SCR1_SVA_IFU_DRC_UNDERFLOW : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ~imem_resp_discard_req |=> ~(imem_resp_discard_cnt == SCR1_TXN_CNT_W'('1))
+    ) else $error("IFU Error: imem_resp_discard_cnt underflow");
+
+SCR1_SVA_IFU_DRC_RANGE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (imem_resp_discard_cnt >= 0) & (imem_resp_discard_cnt <= imem_pnd_txns_cnt)
+    ) else $error("IFU Error: imem_resp_discard_cnt out of range");
+
+SCR1_SVA_IFU_QUEUE_OVF : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (q_ocpd_h >= SCR1_IFU_Q_FREE_H_W'(SCR1_IFU_Q_SIZE_HALF-1)) |->
+    ((q_ocpd_h == SCR1_IFU_Q_FREE_H_W'(SCR1_IFU_Q_SIZE_HALF-1)) ? (q_wr_size != SCR1_IFU_QUEUE_WR_FULL)
+                                                                : (q_wr_size == SCR1_IFU_QUEUE_WR_NONE))
+    ) else $error("IFU Error: queue overflow");
+
+SCR1_SVA_IFU_IMEM_ERR_BEH : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (imem_resp_er & ~imem_resp_discard_req & ~exu2ifu_pc_new_req_i) |=>
+    (ifu_fsm_curr == SCR1_IFU_FSM_IDLE) & (imem_resp_discard_cnt == imem_pnd_txns_cnt)
+    ) else $error("IFU Error: incorrect behavior after memory error");
+
+SCR1_SVA_IFU_NEW_PC_REQ_BEH : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2ifu_pc_new_req_i |=> q_is_empty
+    ) else $error("IFU Error: incorrect behavior after exu2ifu_pc_new_req_i");
+
+SCR1_SVA_IFU_IMEM_ADDR_ALIGNED : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ifu2imem_req_o |-> ~|ifu2imem_addr_o[1:0]
+    ) else $error("IFU Error: unaligned IMEM access");
+
+SCR1_SVA_IFU_STOP_FETCH : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    pipe2ifu_stop_fetch_i |=> (ifu_fsm_curr == SCR1_IFU_FSM_IDLE)
+    ) else $error("IFU Error: fetch not stopped");
+
+SCR1_SVA_IFU_IMEM_FAULT_RVI_HI : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    ifu2idu_err_rvi_hi_o |-> ifu2idu_imem_err_o
+    ) else $error("IFU Error: ifu2idu_imem_err_o == 0");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_ifu
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_lsu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_lsu.sv
new file mode 100644
index 0000000..cb87993
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_lsu.sv
@@ -0,0 +1,351 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_lsu.sv>
+/// @brief      Load/Store Unit (LSU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Performs load and store operations in Data Memory
+ // - Generates DMEM address misalign and access fault exceptions
+ // - Passes DMEM operations information to TDU and generates LSU breakpoint exception
+ //
+ // Structure:
+ // - FSM
+ // - Exceptions logic
+ // - LSU <-> EXU interface
+ // - LSU <-> DMEM interface
+ // - LSU <-> TDU interface
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_memif.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`ifdef SCR1_TDU_EN
+`include "scr1_tdu.svh"
+`endif // SCR1_TDU_EN
+
+module scr1_pipe_lsu (
+    // Common
+    input   logic                               rst_n,                      // LSU reset
+    input   logic                               clk,                        // LSU clock
+
+    // LSU <-> EXU interface
+    input   logic                               exu2lsu_req_i,              // Request to LSU
+    input   type_scr1_lsu_cmd_sel_e             exu2lsu_cmd_i,              // LSU command
+    input   logic [`SCR1_XLEN-1:0]              exu2lsu_addr_i,             // Address of DMEM
+    input   logic [`SCR1_XLEN-1:0]              exu2lsu_sdata_i,            // Data for store
+    output  logic                               lsu2exu_rdy_o,              // LSU received DMEM response
+    output  logic [`SCR1_XLEN-1:0]              lsu2exu_ldata_o,            // Load data
+    output  logic                               lsu2exu_exc_o,              // Exception from LSU
+    output  type_scr1_exc_code_e                lsu2exu_exc_code_o,         // Exception code
+
+`ifdef SCR1_TDU_EN
+    // LSU <-> TDU interface
+    output  type_scr1_brkm_lsu_mon_s            lsu2tdu_dmon_o,             // Data address stream monitoring
+    input   logic                               tdu2lsu_ibrkpt_exc_req_i,   // Instruction BP exception request
+    input   logic                               tdu2lsu_dbrkpt_exc_req_i,   // Data BP exception request
+`endif // SCR1_TDU_EN
+
+    // LSU <-> DMEM interface
+    output  logic                               lsu2dmem_req_o,             // Data memory request
+    output  type_scr1_mem_cmd_e                 lsu2dmem_cmd_o,             // Data memory command (READ/WRITE)
+    output  type_scr1_mem_width_e               lsu2dmem_width_o,           // Data memory data width
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]       lsu2dmem_addr_o,            // Data memory address
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]       lsu2dmem_wdata_o,           // Data memory write data
+    input   logic                               dmem2lsu_req_ack_i,         // Data memory request acknowledge
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]       dmem2lsu_rdata_i,           // Data memory read data
+    input   type_scr1_mem_resp_e                dmem2lsu_resp_i             // Data memory response
+);
+
+//------------------------------------------------------------------------------
+// Local types declaration
+//------------------------------------------------------------------------------
+
+typedef enum logic {
+    SCR1_LSU_FSM_IDLE,
+    SCR1_LSU_FSM_BUSY
+} type_scr1_lsu_fsm_e;
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// LSU FSM signals
+type_scr1_lsu_fsm_e         lsu_fsm_curr;       // LSU FSM current state
+type_scr1_lsu_fsm_e         lsu_fsm_next;       // LSU FSM next state
+logic                       lsu_fsm_idle;       // LSU FSM is in IDLE state
+
+// LSU Command register signals
+logic                       lsu_cmd_upd;        // LSU Command register update
+type_scr1_lsu_cmd_sel_e     lsu_cmd_ff;         // LSU Command register value
+logic                       lsu_cmd_ff_load;    // Registered LSU Command is load
+logic                       lsu_cmd_ff_store;   // Registered LSU Command is store
+
+// DMEM command and width flags
+logic                       dmem_cmd_load;      // DMEM command is load
+logic                       dmem_cmd_store;     // DMEM Command is store
+logic                       dmem_wdth_word;     // DMEM data width is WORD
+logic                       dmem_wdth_hword;    // DMEM data width is HALFWORD
+logic                       dmem_wdth_byte;     // DMEM data width is BYTE
+
+// DMEM response and request control signals
+logic                       dmem_resp_ok;       // DMEM response is OK
+logic                       dmem_resp_er;       // DMEM response is erroneous
+logic                       dmem_resp_received; // DMEM response is received
+logic                       dmem_req_vd;        // DMEM request is valid (req_ack received)
+
+// Exceptions signals
+logic                       lsu_exc_req;        // LSU exception request
+logic                       dmem_addr_mslgn;    // DMEM address is misaligned
+logic                       dmem_addr_mslgn_l;  // DMEM load address is misaligned
+logic                       dmem_addr_mslgn_s;  // DMEM store address is misaligned
+`ifdef SCR1_TDU_EN
+logic                       lsu_exc_hwbrk;      // LSU hardware breakpoint exception
+`endif // SCR1_TDU_EN
+
+//------------------------------------------------------------------------------
+// Control logic
+//------------------------------------------------------------------------------
+
+// DMEM response and request control signals
+assign dmem_resp_ok       = (dmem2lsu_resp_i == SCR1_MEM_RESP_RDY_OK);
+assign dmem_resp_er       = (dmem2lsu_resp_i == SCR1_MEM_RESP_RDY_ER);
+assign dmem_resp_received = dmem_resp_ok | dmem_resp_er;
+assign dmem_req_vd        = exu2lsu_req_i & dmem2lsu_req_ack_i & ~lsu_exc_req;
+
+// LSU load and store command flags
+assign dmem_cmd_load  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LB )
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LBU)
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LH )
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LHU)
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_LW );
+assign dmem_cmd_store = (exu2lsu_cmd_i == SCR1_LSU_CMD_SB )
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_SH )
+                      | (exu2lsu_cmd_i == SCR1_LSU_CMD_SW );
+
+// LSU data width flags
+assign dmem_wdth_word  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LW )
+                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SW );
+assign dmem_wdth_hword = (exu2lsu_cmd_i == SCR1_LSU_CMD_LH )
+                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_LHU)
+                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SH );
+assign dmem_wdth_byte  = (exu2lsu_cmd_i == SCR1_LSU_CMD_LB )
+                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_LBU)
+                       | (exu2lsu_cmd_i == SCR1_LSU_CMD_SB );
+
+// LSU command register
+assign lsu_cmd_upd = lsu_fsm_idle & dmem_req_vd;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        lsu_cmd_ff <= SCR1_LSU_CMD_NONE;
+    end else if (lsu_cmd_upd) begin
+        lsu_cmd_ff <= exu2lsu_cmd_i;
+    end
+end
+
+// LSU registered load and store command flags
+assign lsu_cmd_ff_load  = (lsu_cmd_ff == SCR1_LSU_CMD_LB )
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_LBU)
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_LH )
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_LHU)
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_LW );
+assign lsu_cmd_ff_store = (lsu_cmd_ff == SCR1_LSU_CMD_SB )
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_SH )
+                        | (lsu_cmd_ff == SCR1_LSU_CMD_SW );
+
+//------------------------------------------------------------------------------
+// LSU FSM
+//------------------------------------------------------------------------------
+ //
+ // LSU FSM is used to control the LSU <-> DMEM interface
+ //
+//
+
+// Updating LSU FSM state
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        lsu_fsm_curr <= SCR1_LSU_FSM_IDLE;
+    end else begin
+        lsu_fsm_curr <= lsu_fsm_next;
+    end
+end
+
+// LSU FSM next state logic
+always_comb begin
+    case (lsu_fsm_curr)
+        SCR1_LSU_FSM_IDLE: begin
+            lsu_fsm_next = dmem_req_vd        ? SCR1_LSU_FSM_BUSY
+                                              : SCR1_LSU_FSM_IDLE;
+        end
+        SCR1_LSU_FSM_BUSY: begin
+            lsu_fsm_next = dmem_resp_received ? SCR1_LSU_FSM_IDLE
+                                              : SCR1_LSU_FSM_BUSY;
+        end
+    endcase
+end
+
+assign lsu_fsm_idle = (lsu_fsm_curr == SCR1_LSU_FSM_IDLE);
+
+//------------------------------------------------------------------------------
+// Exceptions logic
+//------------------------------------------------------------------------------
+ //
+ // The following types of exceptions are supported:
+ // - Load address misalign
+ // - Load access fault
+ // - Store address misalign
+ // - Store access fault
+ // - LSU breakpoint exception
+//
+
+// DMEM addr misalign logic
+assign dmem_addr_mslgn   = exu2lsu_req_i & ( (dmem_wdth_hword & exu2lsu_addr_i[0])
+                                           | (dmem_wdth_word  & |exu2lsu_addr_i[1:0]));
+assign dmem_addr_mslgn_l = dmem_addr_mslgn & dmem_cmd_load;
+assign dmem_addr_mslgn_s = dmem_addr_mslgn & dmem_cmd_store;
+
+// Exception code logic
+always_comb begin
+    case (1'b1)
+        dmem_resp_er     : lsu2exu_exc_code_o = lsu_cmd_ff_load  ? SCR1_EXC_CODE_LD_ACCESS_FAULT
+                                              : lsu_cmd_ff_store ? SCR1_EXC_CODE_ST_ACCESS_FAULT
+                                                                 : SCR1_EXC_CODE_INSTR_MISALIGN;
+`ifdef SCR1_TDU_EN
+        lsu_exc_hwbrk    : lsu2exu_exc_code_o = SCR1_EXC_CODE_BREAKPOINT;
+`endif // SCR1_TDU_EN
+        dmem_addr_mslgn_l: lsu2exu_exc_code_o = SCR1_EXC_CODE_LD_ADDR_MISALIGN;
+        dmem_addr_mslgn_s: lsu2exu_exc_code_o = SCR1_EXC_CODE_ST_ADDR_MISALIGN;
+        default          : lsu2exu_exc_code_o = SCR1_EXC_CODE_INSTR_MISALIGN;
+    endcase // 1'b1
+end
+
+assign lsu_exc_req = dmem_addr_mslgn_l | dmem_addr_mslgn_s
+`ifdef SCR1_TDU_EN
+                   | lsu_exc_hwbrk
+`endif // SCR1_TDU_EN
+;
+
+//------------------------------------------------------------------------------
+// LSU <-> EXU interface
+//------------------------------------------------------------------------------
+
+assign lsu2exu_rdy_o = dmem_resp_received;
+assign lsu2exu_exc_o = dmem_resp_er | lsu_exc_req;
+
+// Sign- or zero-extending data received from DMEM
+always_comb begin
+    case (lsu_cmd_ff)
+        SCR1_LSU_CMD_LH : lsu2exu_ldata_o = {{16{dmem2lsu_rdata_i[15]}}, dmem2lsu_rdata_i[15:0]};
+        SCR1_LSU_CMD_LHU: lsu2exu_ldata_o = { 16'b0,                     dmem2lsu_rdata_i[15:0]};
+        SCR1_LSU_CMD_LB : lsu2exu_ldata_o = {{24{dmem2lsu_rdata_i[7]}},  dmem2lsu_rdata_i[7:0]};
+        SCR1_LSU_CMD_LBU: lsu2exu_ldata_o = { 24'b0,                     dmem2lsu_rdata_i[7:0]};
+        default         : lsu2exu_ldata_o = dmem2lsu_rdata_i;
+    endcase // lsu_cmd_ff
+end
+
+//------------------------------------------------------------------------------
+// LSU <-> DMEM interface
+//------------------------------------------------------------------------------
+
+assign lsu2dmem_req_o   = exu2lsu_req_i & ~lsu_exc_req & lsu_fsm_idle;
+assign lsu2dmem_addr_o  = exu2lsu_addr_i;
+assign lsu2dmem_wdata_o = exu2lsu_sdata_i;
+assign lsu2dmem_cmd_o   = dmem_cmd_store  ? SCR1_MEM_CMD_WR : SCR1_MEM_CMD_RD;
+assign lsu2dmem_width_o = dmem_wdth_byte  ? SCR1_MEM_WIDTH_BYTE
+                        : dmem_wdth_hword ? SCR1_MEM_WIDTH_HWORD
+                                          : SCR1_MEM_WIDTH_WORD;
+
+`ifdef SCR1_TDU_EN
+//------------------------------------------------------------------------------
+// LSU <-> TDU interface
+//------------------------------------------------------------------------------
+
+assign lsu2tdu_dmon_o.vd    = exu2lsu_req_i & lsu_fsm_idle & ~tdu2lsu_ibrkpt_exc_req_i;
+assign lsu2tdu_dmon_o.addr  = exu2lsu_addr_i;
+assign lsu2tdu_dmon_o.load  = dmem_cmd_load;
+assign lsu2tdu_dmon_o.store = dmem_cmd_store;
+
+assign lsu_exc_hwbrk = (exu2lsu_req_i & tdu2lsu_ibrkpt_exc_req_i)
+                     | tdu2lsu_dbrkpt_exc_req_i;
+
+`endif // SCR1_TDU_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//------------------------------------------------------------------------------
+// Assertions
+//------------------------------------------------------------------------------
+
+// X checks
+
+SCR1_SVA_LSU_XCHECK_CTRL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({exu2lsu_req_i, lsu_fsm_curr
+`ifdef SCR1_TDU_EN
+        , tdu2lsu_ibrkpt_exc_req_i, tdu2lsu_dbrkpt_exc_req_i
+`endif // SCR1_TDU_EN
+    })
+    ) else $error("LSU Error: unknown control value");
+
+SCR1_SVA_LSU_XCHECK_CMD : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2lsu_req_i |-> !$isunknown({exu2lsu_cmd_i, exu2lsu_addr_i})
+    ) else $error("LSU Error: undefined CMD or address");
+
+SCR1_SVA_LSU_XCHECK_SDATA : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (exu2lsu_req_i & (lsu2dmem_cmd_o == SCR1_MEM_CMD_WR)) |-> !$isunknown({exu2lsu_sdata_i})
+    ) else $error("LSU Error: undefined store data");
+
+SCR1_SVA_LSU_XCHECK_EXC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2exu_exc_o |-> !$isunknown(lsu2exu_exc_code_o)
+    ) else $error("LSU Error: exception code undefined");
+
+SCR1_SVA_LSU_IMEM_CTRL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2dmem_req_o |-> !$isunknown({lsu2dmem_cmd_o, lsu2dmem_width_o, lsu2dmem_addr_o})
+    ) else $error("LSU Error: undefined dmem control");
+
+SCR1_SVA_LSU_IMEM_ACK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2dmem_req_o |-> !$isunknown(dmem2lsu_req_ack_i)
+    ) else $error("LSU Error: undefined dmem ack");
+
+SCR1_SVA_LSU_IMEM_WDATA : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2dmem_req_o & (lsu2dmem_cmd_o == SCR1_MEM_CMD_WR)
+    |-> !$isunknown(lsu2dmem_wdata_o[8:0])
+    ) else $error("LSU Error: undefined dmem wdata");
+
+// Behavior checks
+
+SCR1_SVA_LSU_EXC_ONEHOT : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    $onehot0({dmem_resp_er, dmem_addr_mslgn_l, dmem_addr_mslgn_s})
+    ) else $error("LSU Error: more than one exception at a time");
+
+SCR1_SVA_LSU_UNEXPECTED_DMEM_RESP : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu_fsm_idle |-> ~dmem_resp_received
+    ) else $error("LSU Error: not expecting memory response");
+
+SCR1_SVA_LSU_REQ_EXC : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2exu_exc_o |-> exu2lsu_req_i
+    ) else $error("LSU Error: impossible exception");
+
+`ifdef SCR1_TDU_EN
+
+SCR1_COV_LSU_MISALIGN_BRKPT : cover property (
+    @(negedge clk) disable iff (~rst_n)
+    (dmem_addr_mslgn_l | dmem_addr_mslgn_s) & lsu_exc_hwbrk
+);
+`endif // SCR1_TDU_EN
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_lsu
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_mprf.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_mprf.sv
new file mode 100644
index 0000000..6cb2a34
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_mprf.sv
@@ -0,0 +1,167 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_mprf.sv>
+/// @brief      Multi Port Register File (MPRF)
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+
+module scr1_pipe_mprf (
+    // Common
+`ifdef SCR1_MPRF_RST_EN
+    input   logic                               rst_n,                      // MPRF reset
+`endif // SCR1_MPRF_RST_EN
+    input   logic                               clk,                        // MPRF clock
+
+    // EXU <-> MPRF interface
+    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs1_addr_i,        // MPRF rs1 read address
+    output  logic [`SCR1_XLEN-1:0]              mprf2exu_rs1_data_o,        // MPRF rs1 read data
+    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rs2_addr_i,        // MPRF rs2 read address
+    output  logic [`SCR1_XLEN-1:0]              mprf2exu_rs2_data_o,        // MPRF rs2 read data
+    input   logic                               exu2mprf_w_req_i,           // MPRF write request
+    input   logic [`SCR1_MPRF_AWIDTH-1:0]       exu2mprf_rd_addr_i,         // MPRF rd write address
+    input   logic [`SCR1_XLEN-1:0]              exu2mprf_rd_data_i          // MPRF rd write data
+);
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+
+logic                        wr_req_vd;
+
+logic                        rs1_addr_vd;
+logic                        rs2_addr_vd;
+
+`ifdef  SCR1_MPRF_RAM
+logic                        rs1_addr_vd_ff;
+logic                        rs2_addr_vd_ff;
+
+logic                        rs1_new_data_req;
+logic                        rs2_new_data_req;
+logic                        rs1_new_data_req_ff;
+logic                        rs2_new_data_req_ff;
+logic                        read_new_data_req;
+
+logic    [`SCR1_XLEN-1:0]    rd_data_ff;
+
+logic    [`SCR1_XLEN-1:0]    rs1_data_ff;
+logic    [`SCR1_XLEN-1:0]    rs2_data_ff;
+
+// when using RAM, 2 memories are needed because 3 simultaneous independent
+// write/read operations can occur
+ `ifdef SCR1_TRGT_FPGA_INTEL_MAX10
+(* ramstyle = "M9K" *)      logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
+(* ramstyle = "M9K" *)      logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
+ `elsif SCR1_TRGT_FPGA_INTEL_ARRIAV
+(* ramstyle = "M10K" *)     logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
+(* ramstyle = "M10K" *)     logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
+ `else
+logic   [`SCR1_XLEN-1:0]    mprf_int   [1:`SCR1_MPRF_SIZE-1];
+logic   [`SCR1_XLEN-1:0]    mprf_int2  [1:`SCR1_MPRF_SIZE-1];
+ `endif
+`else  // distributed logic implementation
+type_scr1_mprf_v [1:`SCR1_MPRF_SIZE-1]                  mprf_int;
+`endif
+
+//------------------------------------------------------------------------------
+// MPRF control logic
+//------------------------------------------------------------------------------
+
+// control signals common for distributed logic and RAM implementations
+assign  rs1_addr_vd  =   |exu2mprf_rs1_addr_i;
+assign  rs2_addr_vd  =   |exu2mprf_rs2_addr_i;
+
+assign  wr_req_vd  =   exu2mprf_w_req_i & |exu2mprf_rd_addr_i;
+
+// RAM implementation specific control signals
+`ifdef SCR1_MPRF_RAM
+assign  rs1_new_data_req    =   wr_req_vd & ( exu2mprf_rs1_addr_i == exu2mprf_rd_addr_i );
+assign  rs2_new_data_req    =   wr_req_vd & ( exu2mprf_rs2_addr_i == exu2mprf_rd_addr_i );
+assign  read_new_data_req   =   rs1_new_data_req | rs2_new_data_req;
+
+always_ff @( posedge clk ) begin
+    rs1_addr_vd_ff          <=  rs1_addr_vd;
+    rs2_addr_vd_ff          <=  rs2_addr_vd;
+    rs1_new_data_req_ff     <=  rs1_new_data_req;
+    rs2_new_data_req_ff     <=  rs2_new_data_req;
+end
+`endif // SCR1_MPRF_RAM
+
+`ifdef  SCR1_MPRF_RAM
+//-------------------------------------------------------------------------------
+// RAM implementation
+//-------------------------------------------------------------------------------
+
+// RAM is implemented with 2 simple dual-port memories with sync read operation;
+// logic for "write-first" RDW behavior is implemented externally to the embedded
+// memory blocks
+
+// bypass new wr_data to the read output if write/read collision occurs
+assign  mprf2exu_rs1_data_o   =   ( rs1_new_data_req_ff ) ? rd_data_ff
+                                : (( rs1_addr_vd_ff )   ? rs1_data_ff
+                                                        : '0 );
+
+assign  mprf2exu_rs2_data_o   =   ( rs2_new_data_req_ff ) ? rd_data_ff
+                                : (( rs2_addr_vd_ff )   ? rs2_data_ff
+                                                        : '0 );
+
+always_ff @( posedge clk ) begin
+    if ( read_new_data_req ) begin
+        rd_data_ff     <=  exu2mprf_rd_data_i;
+    end
+end
+
+// synchronous read operation
+always_ff @( posedge clk ) begin
+    rs1_data_ff   <=   mprf_int[exu2mprf_rs1_addr_i];
+    rs2_data_ff   <=   mprf_int2[exu2mprf_rs2_addr_i];
+end
+
+// write operation
+always_ff @( posedge clk ) begin
+    if ( wr_req_vd ) begin
+        mprf_int[exu2mprf_rd_addr_i]  <= exu2mprf_rd_data_i;
+        mprf_int2[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
+    end
+end
+`else   // distributed logic implementation
+//------------------------------------------------------------------------------
+// distributed logic implementation
+//------------------------------------------------------------------------------
+
+// asynchronous read operation
+assign  mprf2exu_rs1_data_o = ( rs1_addr_vd ) ? mprf_int[exu2mprf_rs1_addr_i] : '0;
+assign  mprf2exu_rs2_data_o = ( rs2_addr_vd ) ? mprf_int[exu2mprf_rs2_addr_i] : '0;
+
+// write operation
+ `ifdef SCR1_MPRF_RST_EN
+always_ff @( posedge clk, negedge rst_n ) begin
+    if ( ~rst_n ) begin
+        mprf_int <= '{default: '0};
+    end else if ( wr_req_vd ) begin
+        mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
+    end
+end
+ `else // ~SCR1_MPRF_RST_EN
+always_ff @( posedge clk ) begin
+    if ( wr_req_vd ) begin
+        mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i;
+    end
+end
+ `endif // ~SCR1_MPRF_RST_EN
+`endif
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+`ifdef SCR1_MPRF_RST_EN
+SCR1_SVA_MPRF_WRITEX : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2mprf_w_req_i |-> !$isunknown({exu2mprf_rd_addr_i, (|exu2mprf_rd_addr_i ? exu2mprf_rd_data_i : `SCR1_XLEN'd0)})
+    ) else $error("MPRF error: unknown values");
+`endif // SCR1_MPRF_RST_EN
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_mprf
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_tdu.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_tdu.sv
new file mode 100644
index 0000000..441f6a4
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_tdu.sv
@@ -0,0 +1,610 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_tdu.sv>
+/// @brief      Trigger Debug Unit (TDU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Provides read/write interface for TDU CSRs
+ // - Provides triggers functionality:
+ //   - Supports triggers either in both Debug and M modes or in Debug mode only
+ //   - Supports virtual address matching (load, store, exec) triggers
+ //   - Supports instruction count triggers
+ //   - Supports the following actions on trigger firing:
+ //     - Breakpoint exception raising
+ //     - Debug Mode entering
+ //   - Supports triggers chaining
+ //
+ // Structure:
+ // - CSR read/write i/f
+ // - TDU CSRs:
+ //   - TSELECT
+ //   - TDATA1/MCONTROL/ICOUNT
+ //   - TDATA2
+ //   - TINFO
+ // - TDU <-> EXU i/f
+ // - TDU <-> LSU i/f
+ // - TDU <-> HDU i/f
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_TDU_EN
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_tdu.svh"
+
+module scr1_pipe_tdu (
+    // Common signals
+    input  logic                                            rst_n,                      // TDU reset
+    input  logic                                            clk,                        // TDU clock
+    input  logic                                            clk_en,                     // TDU clock enable
+    input  logic                                            tdu_dsbl_i,                 // TDU Disable
+
+    // TDU <-> CSR interface
+    input  logic                                            csr2tdu_req_i,              // CSR-TDU i/f request
+    input  type_scr1_csr_cmd_sel_e                          csr2tdu_cmd_i,              // CSR-TDU i/f command
+    input  logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]             csr2tdu_addr_i,             // CSR-TDU i/f address
+    input  logic [SCR1_TDU_DATA_W-1:0]                      csr2tdu_wdata_i,            // CSR-TDU i/f write data
+    output logic [SCR1_TDU_DATA_W-1:0]                      tdu2csr_rdata_o,            // CSR-TDU i/f read data
+    output type_scr1_csr_resp_e                             tdu2csr_resp_o,             // CSR-TDU i/f response
+
+    // TDU <-> EXU interface
+    input  type_scr1_brkm_instr_mon_s                       exu2tdu_imon_i,             // Instruction stream monitoring
+    output logic [SCR1_TDU_ALLTRIG_NUM-1 : 0]               tdu2exu_ibrkpt_match_o,     // Instruction BP match
+    output logic                                            tdu2exu_ibrkpt_exc_req_o,   // Instruction BP exception request
+    input  logic [SCR1_TDU_ALLTRIG_NUM-1 : 0]               exu2tdu_bp_retire_i,        // Map of BPs being retired
+
+    // TDU <-> LSU interface
+`ifndef SCR1_TDU_EN
+    output logic                                            tdu2lsu_brk_en_o,           // TDU-LSU Breakpoint enable
+`endif // SCR1_TDU_EN
+    output logic                                            tdu2lsu_ibrkpt_exc_req_o,   // TDU-LSU Instruction BP exception request
+    input  type_scr1_brkm_lsu_mon_s                         lsu2tdu_dmon_i,             // TDU-LSU Data address stream monitoring
+    output logic [SCR1_TDU_MTRIG_NUM-1 : 0]                 tdu2lsu_dbrkpt_match_o,     // TDU-LSU Data BP match
+    output logic                                            tdu2lsu_dbrkpt_exc_req_o,   // TDU-LSU Data BP exception request
+
+    // TDU <-> HDU interface
+    output logic                                            tdu2hdu_dmode_req_o         // Debug Mode redirection request
+);
+
+//------------------------------------------------------------------------------
+// Local parameters declaration
+//------------------------------------------------------------------------------
+
+localparam int unsigned MTRIG_NUM   = SCR1_TDU_MTRIG_NUM;
+localparam int unsigned ALLTRIG_NUM = SCR1_TDU_ALLTRIG_NUM;
+localparam int unsigned ALLTRIG_W   = $clog2(ALLTRIG_NUM+1);
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// TDU CSRs read/write i/f signals
+//------------------------------------------------------------------------------
+
+// Write signals
+logic                                           csr_wr_req;
+logic [SCR1_TDU_DATA_W-1:0]                     csr_wr_data;
+
+// Register select
+logic                                           csr_addr_tselect;
+logic [MTRIG_NUM-1:0]                           csr_addr_mcontrol;
+logic [MTRIG_NUM-1:0]                           csr_addr_tdata2;
+`ifdef SCR1_TDU_ICOUNT_EN
+logic                                           csr_addr_icount;
+`endif // SCR1_TDU_ICOUNT_EN
+
+// TDU CSRs
+//------------------------------------------------------------------------------
+
+// TSELECT register
+logic                                           csr_tselect_upd;
+logic [ALLTRIG_W-1:0]                           csr_tselect_ff;
+
+// MCONTROL register
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_wr_req;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_clk_en;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_upd;
+
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_dmode_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_dmode_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_m_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_m_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_load_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_load_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_store_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_store_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_action_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_action_next;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_hit_ff;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_hit_next;
+
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_exec_hit;
+logic [MTRIG_NUM-1:0]                           csr_mcontrol_ldst_hit;
+
+// ICOUNT register
+`ifdef SCR1_TDU_ICOUNT_EN
+logic                                           csr_icount_wr_req;
+logic                                           csr_icount_clk_en;
+logic                                           csr_icount_upd;
+
+logic                                           csr_icount_dmode_ff;
+logic                                           csr_icount_dmode_next;
+logic                                           csr_icount_m_ff;
+logic                                           csr_icount_m_next;
+logic                                           csr_icount_action_ff;
+logic                                           csr_icount_action_next;
+logic                                           csr_icount_hit_ff;
+logic                                           csr_icount_hit_next;
+logic [SCR1_TDU_ICOUNT_COUNT_HI-SCR1_TDU_ICOUNT_COUNT_LO:0]
+                                                csr_icount_count_ff;
+logic [SCR1_TDU_ICOUNT_COUNT_HI-SCR1_TDU_ICOUNT_COUNT_LO:0]
+                                                csr_icount_count_next;
+logic                                           csr_icount_skip_ff;
+logic                                           csr_icount_skip_next;
+
+logic                                           csr_icount_decr_en;
+logic                                           csr_icount_count_decr;
+logic                                           csr_icount_skip_dsbl;
+logic                                           csr_icount_hit;
+`endif // SCR1_TDU_ICOUNT_EN
+
+// TDATA2 register
+logic [MTRIG_NUM-1:0]                           csr_tdata2_upd;
+logic [MTRIG_NUM-1:0] [SCR1_TDU_DATA_W-1:0]     csr_tdata2_ff;
+
+//------------------------------------------------------------------------------
+// CSR read/write interface
+//------------------------------------------------------------------------------
+
+// Read logic
+//------------------------------------------------------------------------------
+
+assign tdu2csr_resp_o = csr2tdu_req_i ? SCR1_CSR_RESP_OK : SCR1_CSR_RESP_ER;
+
+always_comb begin
+    tdu2csr_rdata_o = '0;
+    if (csr2tdu_req_i) begin
+        case (csr2tdu_addr_i)
+            SCR1_CSR_ADDR_TDU_OFFS_TSELECT: begin
+                tdu2csr_rdata_o = {'0, csr_tselect_ff};
+            end
+            SCR1_CSR_ADDR_TDU_OFFS_TDATA2 : begin
+                for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
+                        tdu2csr_rdata_o = csr_tdata2_ff[i];
+                    end
+                end
+            end
+            SCR1_CSR_ADDR_TDU_OFFS_TDATA1 : begin
+                for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
+                        tdu2csr_rdata_o[SCR1_TDU_TDATA1_TYPE_HI:
+                                       SCR1_TDU_TDATA1_TYPE_LO]      = SCR1_TDU_MCONTROL_TYPE_VAL;
+                        tdu2csr_rdata_o[SCR1_TDU_TDATA1_DMODE]       = csr_mcontrol_dmode_ff[i];
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_MASKMAX_HI:
+                                       SCR1_TDU_MCONTROL_MASKMAX_LO] = SCR1_TDU_MCONTROL_MASKMAX_VAL;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_HIT]       = csr_mcontrol_hit_ff[i];
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_SELECT]    = SCR1_TDU_MCONTROL_SELECT_VAL;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_TIMING]    = SCR1_TDU_MCONTROL_TIMING_VAL;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_ACTION_HI:
+                                       SCR1_TDU_MCONTROL_ACTION_LO]  = {5'b0, csr_mcontrol_action_ff[i]};
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_CHAIN]     = 1'b0;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_MATCH_HI:
+                                       SCR1_TDU_MCONTROL_MATCH_LO]   = 4'b0;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_M]         = csr_mcontrol_m_ff[i];
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_RESERVEDA] = SCR1_TDU_MCONTROL_RESERVEDA_VAL;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_S]         = 1'b0;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_U]         = 1'b0;
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_EXECUTE]   = csr_mcontrol_exec_ff [i];
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_STORE]     = csr_mcontrol_store_ff[i];
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_LOAD]      = csr_mcontrol_load_ff [i];
+                    end
+                end
+`ifdef SCR1_TDU_ICOUNT_EN
+                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
+                    tdu2csr_rdata_o[SCR1_TDU_TDATA1_TYPE_HI:
+                                   SCR1_TDU_TDATA1_TYPE_LO]    = SCR1_TDU_ICOUNT_TYPE_VAL;
+                    tdu2csr_rdata_o[SCR1_TDU_TDATA1_DMODE]     = csr_icount_dmode_ff;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_HIT]       = csr_icount_hit_ff;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_COUNT_HI:
+                                   SCR1_TDU_ICOUNT_COUNT_LO]   = csr_icount_count_ff;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_U]         = 1'b0;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_S]         = 1'b0;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_M]         = csr_icount_m_ff;
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_ACTION_HI:
+                                   SCR1_TDU_ICOUNT_ACTION_LO]  = {5'b0, csr_icount_action_ff};
+                end
+`endif // SCR1_TDU_ICOUNT_EN
+            end
+            SCR1_CSR_ADDR_TDU_OFFS_TINFO : begin
+                for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
+                        tdu2csr_rdata_o[SCR1_TDU_MCONTROL_TYPE_VAL] = 1'b1;
+                    end
+                end
+`ifdef SCR1_TDU_ICOUNT_EN
+                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
+                    tdu2csr_rdata_o[SCR1_TDU_ICOUNT_TYPE_VAL] = 1'b1;
+                end
+`endif // SCR1_TDU_ICOUNT_EN
+            end
+            default : begin
+            end
+        endcase
+    end
+end
+
+// Write logic
+//------------------------------------------------------------------------------
+
+always_comb begin
+    csr_wr_req  = 1'b0;
+    csr_wr_data = '0;
+
+    case (csr2tdu_cmd_i)
+        SCR1_CSR_CMD_WRITE: begin
+            csr_wr_req  = 1'b1;
+            csr_wr_data = csr2tdu_wdata_i;
+        end
+        SCR1_CSR_CMD_SET  : begin
+            csr_wr_req  = |csr2tdu_wdata_i;
+            csr_wr_data = tdu2csr_rdata_o | csr2tdu_wdata_i;
+        end
+        SCR1_CSR_CMD_CLEAR: begin
+            csr_wr_req  = |csr2tdu_wdata_i;
+            csr_wr_data = tdu2csr_rdata_o & ~csr2tdu_wdata_i;
+        end
+        default : begin
+        end
+    endcase
+end
+
+// Register selection
+//------------------------------------------------------------------------------
+
+always_comb begin
+    csr_addr_tselect  = 1'b0;
+    csr_addr_tdata2   = '0;
+    csr_addr_mcontrol = '0;
+`ifdef SCR1_TDU_ICOUNT_EN
+    csr_addr_icount   = '0;
+`endif // SCR1_TDU_ICOUNT_EN
+
+    if (csr2tdu_req_i) begin
+        case (csr2tdu_addr_i)
+            SCR1_CSR_ADDR_TDU_OFFS_TSELECT: begin
+                csr_addr_tselect = 1'b1;
+            end
+            SCR1_CSR_ADDR_TDU_OFFS_TDATA1 : begin
+                for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+                    if(csr_tselect_ff == ALLTRIG_W'(i)) begin
+                        csr_addr_mcontrol[i] = 1'b1;
+                    end
+                end
+`ifdef SCR1_TDU_ICOUNT_EN
+                if(csr_tselect_ff == ALLTRIG_W'(SCR1_TDU_ALLTRIG_NUM - 1'b1)) begin
+                    csr_addr_icount = 1'b1;
+                end
+`endif // SCR1_TDU_ICOUNT_EN
+            end
+            SCR1_CSR_ADDR_TDU_OFFS_TDATA2 : begin
+                for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+                    if(csr_tselect_ff == ALLTRIG_W'(i) ) begin
+                        csr_addr_tdata2[i] = 1'b1;
+                    end
+                end
+            end
+            default : begin
+            end
+        endcase
+    end
+end
+
+//------------------------------------------------------------------------------
+// TDU CSRs
+//------------------------------------------------------------------------------
+//
+ // TDU CSRs consist of the following registers:
+ // - TSELECT
+ // - TDATA1/MCONTROL/ICOUNT (depending on the type field value)
+ // - TDATA2
+//
+
+// TSELECT register
+//------------------------------------------------------------------------------
+// Determines which trigger is accessible through the other trigger registers
+
+assign csr_tselect_upd = clk_en & csr_addr_tselect & csr_wr_req
+                       & (csr_wr_data[ALLTRIG_W-1:0] < ALLTRIG_W'(ALLTRIG_NUM));
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if(~rst_n) begin
+        csr_tselect_ff <= '0;
+    end else if(csr_tselect_upd) begin
+        csr_tselect_ff <= csr_wr_data[ALLTRIG_W-1:0];
+    end
+end
+
+`ifdef SCR1_TDU_ICOUNT_EN
+// ICOUNT register
+//------------------------------------------------------------------------------
+// Provides a trigger that fires when the certain number of instructions has retired
+// Is intended to be used as a single step trigger (in this case count must be 1)
+
+assign csr_icount_wr_req = csr_addr_icount & csr_wr_req;
+assign csr_icount_clk_en = clk_en & (csr_icount_wr_req | csr_icount_m_ff);
+assign csr_icount_upd    = ~csr_icount_dmode_ff
+                         ? csr_icount_wr_req
+                         : tdu_dsbl_i & csr_icount_wr_req;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if(~rst_n) begin
+        csr_icount_dmode_ff  <= 1'b0;
+        csr_icount_m_ff      <= 1'b0;
+        csr_icount_action_ff <= 1'b0;
+        csr_icount_hit_ff    <= 1'b0;
+        csr_icount_count_ff  <= '0;
+        csr_icount_skip_ff   <= 1'b0;
+    end else if (csr_icount_clk_en) begin
+        csr_icount_dmode_ff  <= csr_icount_dmode_next;
+        csr_icount_m_ff      <= csr_icount_m_next;
+        csr_icount_action_ff <= csr_icount_action_next;
+        csr_icount_hit_ff    <= csr_icount_hit_next;
+        csr_icount_count_ff  <= csr_icount_count_next;
+        csr_icount_skip_ff   <= csr_icount_skip_next;
+    end
+end
+
+assign csr_icount_decr_en    = (~tdu_dsbl_i & csr_icount_m_ff)
+                             ? exu2tdu_imon_i.vd & (csr_icount_count_ff != 14'b0)
+                             : 1'b0;
+assign csr_icount_count_decr = exu2tdu_imon_i.req & csr_icount_decr_en & ~csr_icount_skip_ff;
+assign csr_icount_skip_dsbl  = exu2tdu_imon_i.req & csr_icount_decr_en & csr_icount_skip_ff;
+
+always_comb begin
+    if (csr_icount_upd) begin
+        csr_icount_dmode_next  = csr_wr_data[SCR1_TDU_TDATA1_DMODE];
+        csr_icount_m_next      = csr_wr_data[SCR1_TDU_ICOUNT_M];
+        csr_icount_action_next = (csr_wr_data[SCR1_TDU_ICOUNT_ACTION_HI
+                                             :SCR1_TDU_ICOUNT_ACTION_LO] == 'b1);
+        csr_icount_hit_next    = csr_wr_data[SCR1_TDU_ICOUNT_HIT];
+        csr_icount_count_next  = csr_wr_data[SCR1_TDU_ICOUNT_COUNT_HI:SCR1_TDU_ICOUNT_COUNT_LO];
+    end else begin
+        csr_icount_dmode_next  = csr_icount_dmode_ff;
+        csr_icount_m_next      = csr_icount_m_ff;
+        csr_icount_action_next = csr_icount_action_ff;
+        csr_icount_hit_next    = exu2tdu_bp_retire_i[ALLTRIG_NUM - 1'b1]
+                               ? 1'b1
+                               : csr_icount_hit_ff;
+        csr_icount_count_next  = csr_icount_count_decr
+                               ? csr_icount_count_ff - 1'b1
+                               : csr_icount_count_ff;
+    end
+end
+
+assign csr_icount_skip_next = csr_icount_wr_req    ? csr_wr_data[SCR1_TDU_ICOUNT_M]
+                            : csr_icount_skip_dsbl ? 1'b0
+                                                   : csr_icount_skip_ff;
+`endif // SCR1_TDU_ICOUNT_EN
+
+// MCONTROL registers
+//------------------------------------------------------------------------------
+// Provides a trigger that fires on the virtual address (stored in TDATA2) match
+// (load, store, exec options supported). Triggers chaining supported
+
+genvar trig;
+generate
+for (trig = 0; $unsigned(trig) < MTRIG_NUM; ++trig) begin : gblock_mtrig
+
+assign csr_mcontrol_wr_req[trig] = csr_addr_mcontrol[trig] & csr_wr_req;
+assign csr_mcontrol_clk_en[trig] = clk_en
+                                 & (csr_mcontrol_wr_req[trig] | csr_mcontrol_m_ff[trig]);
+assign csr_mcontrol_upd   [trig] = ~csr_mcontrol_dmode_ff[trig]
+                                 ? csr_mcontrol_wr_req[trig]
+                                 : tdu_dsbl_i & csr_mcontrol_wr_req[trig];
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if(~rst_n) begin
+        csr_mcontrol_dmode_ff [trig] <= 1'b0;
+        csr_mcontrol_m_ff     [trig] <= 1'b0;
+        csr_mcontrol_exec_ff  [trig] <= 1'b0;
+        csr_mcontrol_load_ff  [trig] <= 1'b0;
+        csr_mcontrol_store_ff [trig] <= 1'b0;
+        csr_mcontrol_action_ff[trig] <= 1'b0;
+        csr_mcontrol_hit_ff   [trig] <= 1'b0;
+    end else if(csr_mcontrol_clk_en[trig]) begin
+        csr_mcontrol_dmode_ff [trig] <= csr_mcontrol_dmode_next[trig];
+        csr_mcontrol_m_ff     [trig] <= csr_mcontrol_m_next[trig];
+        csr_mcontrol_exec_ff  [trig] <= csr_mcontrol_exec_next[trig];
+        csr_mcontrol_load_ff  [trig] <= csr_mcontrol_load_next[trig];
+        csr_mcontrol_store_ff [trig] <= csr_mcontrol_store_next[trig];
+        csr_mcontrol_action_ff[trig] <= csr_mcontrol_action_next[trig];
+        csr_mcontrol_hit_ff   [trig] <= csr_mcontrol_hit_next[trig];
+    end
+end
+
+always_comb begin
+    if (csr_mcontrol_upd[trig]) begin
+        csr_mcontrol_dmode_next [trig] = csr_wr_data[SCR1_TDU_TDATA1_DMODE];
+        csr_mcontrol_m_next     [trig] = csr_wr_data[SCR1_TDU_MCONTROL_M];
+        csr_mcontrol_exec_next  [trig] = csr_wr_data[SCR1_TDU_MCONTROL_EXECUTE];
+        csr_mcontrol_load_next  [trig] = csr_wr_data[SCR1_TDU_MCONTROL_LOAD];
+        csr_mcontrol_store_next [trig] = csr_wr_data[SCR1_TDU_MCONTROL_STORE];
+        csr_mcontrol_action_next[trig] = (csr_wr_data[SCR1_TDU_MCONTROL_ACTION_HI
+                                                     :SCR1_TDU_MCONTROL_ACTION_LO] == 'b1);
+        csr_mcontrol_hit_next   [trig] = csr_wr_data[SCR1_TDU_MCONTROL_HIT];
+    end else begin
+        csr_mcontrol_dmode_next [trig] = csr_mcontrol_dmode_ff [trig];
+        csr_mcontrol_m_next     [trig] = csr_mcontrol_m_ff     [trig];
+        csr_mcontrol_exec_next  [trig] = csr_mcontrol_exec_ff  [trig];
+        csr_mcontrol_load_next  [trig] = csr_mcontrol_load_ff  [trig];
+        csr_mcontrol_store_next [trig] = csr_mcontrol_store_ff [trig];
+        csr_mcontrol_action_next[trig] = csr_mcontrol_action_ff[trig];
+        csr_mcontrol_hit_next   [trig] = exu2tdu_bp_retire_i[trig]
+                                       ? 1'b1
+                                       : csr_mcontrol_hit_ff[trig];
+    end
+end
+
+// TDATA2 register
+//------------------------------------------------------------------------------
+
+assign csr_tdata2_upd[trig] = ~csr_mcontrol_dmode_ff[trig]
+                            ? clk_en & csr_addr_tdata2[trig] & csr_wr_req
+                            : clk_en & csr_addr_tdata2[trig] & csr_wr_req & tdu_dsbl_i;
+
+always_ff @(posedge clk) begin
+    if (csr_tdata2_upd[trig]) begin
+        csr_tdata2_ff[trig] <= csr_wr_data;
+    end
+end
+
+end
+endgenerate // gblock_mtrig
+
+//------------------------------------------------------------------------------
+// TDU <-> EXU interface
+//------------------------------------------------------------------------------
+
+assign csr_icount_hit = ~tdu_dsbl_i & csr_icount_m_ff
+                      ? exu2tdu_imon_i.vd & (csr_icount_count_ff == 14'b1) & ~csr_icount_skip_ff
+                      : 1'b0;
+
+`ifndef SCR1_TDU_ICOUNT_EN
+assign tdu2exu_ibrkpt_match_o   = csr_mcontrol_exec_hit;
+assign tdu2exu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit;
+`else
+assign tdu2exu_ibrkpt_match_o   = {csr_icount_hit, csr_mcontrol_exec_hit};
+assign tdu2exu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit | csr_icount_hit;
+`endif // SCR1_TDU_ICOUNT_EN
+
+//------------------------------------------------------------------------------
+// TDU <-> LSU interface
+//------------------------------------------------------------------------------
+
+// Breakpoint logic
+//------------------------------------------------------------------------------
+
+generate
+for (trig = 0; $unsigned(trig) < MTRIG_NUM; ++trig) begin : gblock_break_trig
+assign csr_mcontrol_exec_hit[trig] = ~tdu_dsbl_i
+                                   & csr_mcontrol_m_ff[trig]
+                                   & csr_mcontrol_exec_ff[trig]
+                                   & exu2tdu_imon_i.vd
+                                   & exu2tdu_imon_i.addr == csr_tdata2_ff[trig];
+end
+endgenerate
+
+`ifndef SCR1_TDU_ICOUNT_EN
+assign tdu2lsu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit;
+`else
+assign tdu2lsu_ibrkpt_exc_req_o = |csr_mcontrol_exec_hit | csr_icount_hit;
+`endif // SCR1_TDU_ICOUNT_EN
+
+// Watchpoint logic
+//------------------------------------------------------------------------------
+
+generate
+for( trig = 0; $unsigned(trig) < MTRIG_NUM; ++trig ) begin : gblock_watch_trig
+assign csr_mcontrol_ldst_hit[trig] = ~tdu_dsbl_i
+                                   & csr_mcontrol_m_ff[trig]
+                                   & lsu2tdu_dmon_i.vd
+                                   & ( (csr_mcontrol_load_ff [trig] & lsu2tdu_dmon_i.load)
+                                     | (csr_mcontrol_store_ff[trig] & lsu2tdu_dmon_i.store))
+                                   & lsu2tdu_dmon_i.addr == csr_tdata2_ff[trig];
+end
+endgenerate
+
+assign tdu2lsu_dbrkpt_match_o   = csr_mcontrol_ldst_hit;
+assign tdu2lsu_dbrkpt_exc_req_o = |csr_mcontrol_ldst_hit;
+
+`ifndef SCR1_TDU_EN
+assign tdu2lsu_brk_en_o = |csr_mcontrol_m_ff | csr_icount_m_ff;
+`endif // SCR1_TDU_EN
+
+//------------------------------------------------------------------------------
+// TDU <-> HDU interface
+//------------------------------------------------------------------------------
+
+always_comb begin
+    tdu2hdu_dmode_req_o = 1'b0;
+
+    for(int unsigned i = 0; i < MTRIG_NUM; ++i) begin
+        tdu2hdu_dmode_req_o |= (csr_mcontrol_action_ff[i] & exu2tdu_bp_retire_i[i]);
+    end
+`ifdef SCR1_TDU_ICOUNT_EN
+    tdu2hdu_dmode_req_o |= (csr_icount_action_ff & exu2tdu_bp_retire_i[ALLTRIG_NUM-1]);
+`endif // SCR1_TDU_ICOUNT_EN
+end
+
+`ifdef SCR1_TRGT_SIMULATION
+//------------------------------------------------------------------------------
+// Assertion
+//------------------------------------------------------------------------------
+
+SVA_TDU_X_CONTROL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({clk_en, tdu_dsbl_i, csr2tdu_req_i,
+                 exu2tdu_imon_i.vd, lsu2tdu_dmon_i.vd, exu2tdu_bp_retire_i})
+    ) else $error("TDU Error: control signals is X - %0b", {clk_en,
+    tdu_dsbl_i, csr2tdu_req_i, exu2tdu_imon_i.vd, lsu2tdu_dmon_i.vd, exu2tdu_bp_retire_i});
+
+SVA_DM_X_CLK_EN : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(clk_en)
+    ) else $error("TDU Error: clk_en control signals is X");
+
+SVA_DM_X_DSBL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(tdu_dsbl_i)
+    ) else $error("TDU Error: tdu_dsbl_i control signals is X");
+
+SVA_DM_X_CSR2TDU_REQ : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(csr2tdu_req_i)
+    ) else $error("TDU Error: csr2tdu_req_i control signals is X");
+
+SVA_DM_X_I_MON_VD : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(exu2tdu_imon_i.vd)
+    ) else $error("TDU Error: exu2tdu_imon_i.vd control signals is X");
+
+SVA_DM_X_D_MON_VD : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(lsu2tdu_dmon_i.vd)
+    ) else $error("TDU Error: lsu2tdu_dmon_i.vd control signals is X");
+
+SVA_DM_X_BP_RETIRE : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(exu2tdu_bp_retire_i)
+    ) else $error("TDU Error: exu2tdu_bp_retire_i control signals is X");
+
+SVA_TDU_X_CSR : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    csr2tdu_req_i |-> !$isunknown({csr2tdu_cmd_i,csr2tdu_addr_i})
+    ) else $error("TDU Error: csr is X");
+
+SVA_TDU_XW_CSR : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    (csr2tdu_req_i & csr_wr_req) |-> !$isunknown(csr2tdu_wdata_i)
+    ) else $error("TDU Error: csr wdata is X ");
+
+SVA_TDU_X_IMON : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    exu2tdu_imon_i.vd |-> !$isunknown({exu2tdu_imon_i.req,exu2tdu_imon_i.addr})
+    ) else $error("TDU Error: imonitor is X");
+
+SVA_TDU_X_DMON : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    lsu2tdu_dmon_i.vd |-> !$isunknown({lsu2tdu_dmon_i})
+    ) else $error("TDU Error: dmonitor is X");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_tdu
+
+`endif // SCR1_TDU_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_top.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_top.sv
new file mode 100644
index 0000000..69ea0d1
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_pipe_top.sv
@@ -0,0 +1,809 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_pipe_top.sv>
+/// @brief      SCR1 pipeline top
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_memif.svh"
+`include "scr1_riscv_isa_decoding.svh"
+`include "scr1_csr.svh"
+
+`ifdef SCR1_IPIC_EN
+`include "scr1_ipic.svh"
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_DBG_EN
+`include "scr1_hdu.svh"
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+`include "scr1_tdu.svh"
+`endif // SCR1_TDU_EN
+
+module scr1_pipe_top (
+    // Common
+    input   logic                                       pipe_rst_n,                 // Pipe reset
+`ifdef SCR1_DBG_EN
+    input   logic                                       pipe2hdu_rdc_qlfy_i,        // Pipe RDC qualifier
+    input   logic                                       dbg_rst_n,                  // Debug reset
+`endif // SCR1_DBG_EN
+    input   logic                                       clk,                        // Pipe clock
+
+    // Instruction Memory Interface
+    output  logic                                       pipe2imem_req_o,            // IMEM request
+    output  type_scr1_mem_cmd_e                         pipe2imem_cmd_o,            // IMEM command
+    output  logic [`SCR1_IMEM_AWIDTH-1:0]               pipe2imem_addr_o,           // IMEM address
+    input   logic                                       imem2pipe_req_ack_i,        // IMEM request acknowledge
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]               imem2pipe_rdata_i,          // IMEM read data
+    input   type_scr1_mem_resp_e                        imem2pipe_resp_i,           // IMEM response
+
+    // Data Memory Interface
+    output  logic                                       pipe2dmem_req_o,            // DMEM request
+    output  type_scr1_mem_cmd_e                         pipe2dmem_cmd_o,            // DMEM command
+    output  type_scr1_mem_width_e                       pipe2dmem_width_o,          // DMEM data width
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]               pipe2dmem_addr_o,           // DMEM address
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]               pipe2dmem_wdata_o,          // DMEM write data
+    input   logic                                       dmem2pipe_req_ack_i,        // DMEM request acknowledge
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]               dmem2pipe_rdata_i,          // DMEM read data
+    input   type_scr1_mem_resp_e                        dmem2pipe_resp_i,           // DMEM response
+
+`ifdef SCR1_DBG_EN
+    // Debug interface:
+    input  logic                                        dbg_en,                     // 1 - debug operations enabled
+    // DM <-> Pipeline: HART Run Control i/f
+    input  logic                                        dm2pipe_active_i,           // Debug Module active flag
+    input  logic                                        dm2pipe_cmd_req_i,          // Request from Debug Module
+    input  type_scr1_hdu_dbgstates_e                    dm2pipe_cmd_i,              // Command from Debug Module
+    output logic                                        pipe2dm_cmd_resp_o,         // Response to Debug Module
+    output logic                                        pipe2dm_cmd_rcode_o,        // Debug Module return code: 0 - Ok; 1 - Error
+    output logic                                        pipe2dm_hart_event_o,       // HART event flag
+    output type_scr1_hdu_hartstatus_s                   pipe2dm_hart_status_o,      // HART status
+
+    // DM <-> Pipeline: Program Buffer - HART instruction execution i/f
+    output logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]         pipe2dm_pbuf_addr_o,        // Program Buffer address
+    input  logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]        dm2pipe_pbuf_instr_i,       // Program Buffer instruction
+
+    // DM <-> Pipeline: HART Abstract Data regs i/f
+    output logic                                        pipe2dm_dreg_req_o,         // Abstract Data Register request
+    output logic                                        pipe2dm_dreg_wr_o,          // Abstract Data Register write
+    output logic [`SCR1_XLEN-1:0]                       pipe2dm_dreg_wdata_o,       // Abstract Data Register write data
+    input  logic                                        dm2pipe_dreg_resp_i,        // Abstract Data Register response
+    input  logic                                        dm2pipe_dreg_fail_i,        // Abstract Data Register fail - possibly not needed?
+    input  logic [`SCR1_XLEN-1:0]                       dm2pipe_dreg_rdata_i,       // Abstract Data Register read data
+
+    // DM <-> Pipeling: PC i/f
+    output logic [`SCR1_XLEN-1:0]                       pipe2dm_pc_sample_o,        // Current PC for sampling
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    input   logic [SCR1_IRQ_LINES_NUM-1:0]              soc2pipe_irq_lines_i,       // External interrupt request lines
+`else // SCR1_IPIC_EN
+    input   logic                                       soc2pipe_irq_ext_i,         // External interrupt request
+`endif // SCR1_IPIC_EN
+    input   logic                                       soc2pipe_irq_soft_i,        // Software generated interrupt request
+    input   logic                                       soc2pipe_irq_mtimer_i,      // Machine timer interrupt request
+
+    // Memory-mapped external timer
+    input   logic [63:0]                                soc2pipe_mtimer_val_i,      // Machine timer value
+
+`ifdef SCR1_CLKCTRL_EN
+    // CLK_CTRL interface
+    output  logic                                       pipe2clkctl_sleep_req_o,    // CLK disable request to CLK gating circuit
+    output  logic                                       pipe2clkctl_wake_req_o,     // CLK enable request to CLK gating circuit
+    input   logic                                       clkctl2pipe_clk_alw_on_i,   // Not gated CLK
+    input   logic                                       clkctl2pipe_clk_dbgc_i,     // CLK for HDU (not gated for now)
+    input   logic                                       clkctl2pipe_clk_en_i,       // CLK enabled flag
+`endif // SCR1_CLKCTRL_EN
+
+    // Fuse
+    input   logic [`SCR1_XLEN-1:0]                      soc2pipe_fuse_mhartid_i     // Fuse MHARTID value
+);
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+
+// Pipeline control
+logic [`SCR1_XLEN-1:0]                      curr_pc;                // Current PC
+logic [`SCR1_XLEN-1:0]                      next_pc;                // Is written to MEPC on interrupt trap
+logic                                       new_pc_req;             // New PC request (jumps, branches, traps etc)
+logic [`SCR1_XLEN-1:0]                      new_pc;                 // New PC
+
+logic                                       stop_fetch;             // Stop IFU
+logic                                       exu_exc_req;            // Exception request
+logic                                       brkpt;                  // Breakpoint (sw) on current instruction
+logic                                       exu_init_pc;            // Reset exit
+logic                                       wfi_run2halt;           // Transition to WFI halted state
+logic                                       instret;                // Instruction retirement (with or without exception)
+logic                                       instret_nexc;           // Instruction retirement (without exception)
+`ifdef SCR1_IPIC_EN
+logic                                       ipic2csr_irq;           // IRQ request from IPIC
+`endif // SCR1_IPIC_EN
+`ifdef SCR1_TDU_EN
+logic                                       brkpt_hw;               // Hardware breakpoint on current instruction
+`endif // SCR1_TDU_EN
+`ifdef SCR1_CLKCTRL_EN
+logic                                       imem_txns_pending;      // There are pending imem transactions
+logic                                       wfi_halted;             // WFI halted state
+`endif // SCR1_CLKCTRL_EN
+
+// IFU <-> IDU
+logic                                       ifu2idu_vd;             // IFU request
+logic [`SCR1_IMEM_DWIDTH-1:0]               ifu2idu_instr;          // IFU instruction
+logic                                       ifu2idu_imem_err;       // IFU instruction access fault
+logic                                       ifu2idu_err_rvi_hi;     // 1 - imem fault when trying to fetch second half of an unaligned RVI instruction
+logic                                       idu2ifu_rdy;            // IDU ready for new data
+
+// IDU <-> EXU
+logic                                       idu2exu_req;            // IDU request
+type_scr1_exu_cmd_s                         idu2exu_cmd;            // IDU command (see scr1_riscv_isa_decoding.svh)
+logic                                       idu2exu_use_rs1;        // Instruction uses rs1
+logic                                       idu2exu_use_rs2;        // Instruction uses rs2
+logic                                       idu2exu_use_rd;         // Instruction uses rd
+logic                                       idu2exu_use_imm;        // Instruction uses immediate
+logic                                       exu2idu_rdy;            // EXU ready for new data
+
+// EXU <-> MPRF
+logic [`SCR1_MPRF_AWIDTH-1:0]               exu2mprf_rs1_addr;      // MPRF rs1 read address
+logic [`SCR1_XLEN-1:0]                      mprf2exu_rs1_data;      // MPRF rs1 read data
+logic [`SCR1_MPRF_AWIDTH-1:0]               exu2mprf_rs2_addr;      // MPRF rs2 read address
+logic [`SCR1_XLEN-1:0]                      mprf2exu_rs2_data;      // MPRF rs2 read data
+logic                                       exu2mprf_w_req;         // MPRF write request
+logic [`SCR1_MPRF_AWIDTH-1:0]               exu2mprf_rd_addr;       // MPRF rd write address
+logic [`SCR1_XLEN-1:0]                      exu2mprf_rd_data;       // MPRF rd write data
+
+// EXU <-> CSR
+logic [SCR1_CSR_ADDR_WIDTH-1:0]             exu2csr_rw_addr;        // CSR read/write address
+logic                                       exu2csr_r_req;          // CSR read request
+logic [`SCR1_XLEN-1:0]                      csr2exu_r_data;         // CSR read data
+logic                                       exu2csr_w_req;          // CSR write request
+type_scr1_csr_cmd_sel_e                     exu2csr_w_cmd;          // CSR write command
+logic [`SCR1_XLEN-1:0]                      exu2csr_w_data;         // CSR write data
+logic                                       csr2exu_rw_exc;         // CSR read/write access exception
+
+// EXU <-> CSR event interface
+logic                                       exu2csr_take_irq;       // Take IRQ trap
+logic                                       exu2csr_take_exc;       // Take exception trap
+logic                                       exu2csr_mret_update;    // MRET update CSR
+logic                                       exu2csr_mret_instr;     // MRET instruction
+type_scr1_exc_code_e                        exu2csr_exc_code;       // Exception code (see scr1_arch_types.svh)
+logic [`SCR1_XLEN-1:0]                      exu2csr_trap_val;       // Trap value
+logic [`SCR1_XLEN-1:0]                      csr2exu_new_pc;         // Exception/IRQ/MRET new PC
+logic                                       csr2exu_irq;            // IRQ request
+logic                                       csr2exu_ip_ie;          // Some IRQ pending and locally enabled
+logic                                       csr2exu_mstatus_mie_up; // MSTATUS or MIE update in the current cycle
+
+`ifdef SCR1_IPIC_EN
+// CSR <-> IPIC
+logic                                       csr2ipic_r_req;         // IPIC read request
+logic                                       csr2ipic_w_req;         // IPIC write request
+logic [2:0]                                 csr2ipic_addr;          // IPIC address
+logic [`SCR1_XLEN-1:0]                      csr2ipic_wdata;         // IPIC write data
+logic [`SCR1_XLEN-1:0]                      ipic2csr_rdata;         // IPIC read data
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_TDU_EN
+// CSR <-> TDU
+logic                                       csr2tdu_req;           // Request to TDU
+type_scr1_csr_cmd_sel_e                     csr2tdu_cmd;           // TDU command
+logic [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]        csr2tdu_addr;          // TDU address
+logic [`SCR1_XLEN-1:0]                      csr2tdu_wdata;         // TDU write data
+logic [`SCR1_XLEN-1:0]                      tdu2csr_rdata;         // TDU read data
+type_scr1_csr_resp_e                        tdu2csr_resp;          // TDU response
+ `ifdef SCR1_DBG_EN
+                                                                    // Qualified TDU input signals from pipe_rst_n
+                                                                    // reset domain:
+logic                                       csr2tdu_req_qlfy;      //     Request to TDU
+ `endif // SCR1_DBG_EN
+
+// EXU/LSU <-> TDU
+type_scr1_brkm_instr_mon_s                  exu2tdu_i_mon;         // Instruction monitor
+type_scr1_brkm_lsu_mon_s                    lsu2tdu_d_mon;         // Data monitor
+logic [SCR1_TDU_ALLTRIG_NUM-1:0]            tdu2exu_i_match;       // Instruction breakpoint(s) match
+logic [SCR1_TDU_MTRIG_NUM-1:0]              tdu2lsu_d_match;       // Data breakpoint(s) match
+logic                                       tdu2exu_i_x_req;       // Instruction breakpoint exception
+logic                                       tdu2lsu_i_x_req;       // Instruction breakpoint exception
+logic                                       tdu2lsu_d_x_req;       // Data breakpoint exception
+logic [SCR1_TDU_ALLTRIG_NUM-1:0]            exu2tdu_bp_retire;     // Instruction with breakpoint flag retire
+ `ifdef SCR1_DBG_EN
+                                                                    // Qualified TDU input signals from pipe_rst_n
+                                                                    // reset domain:
+type_scr1_brkm_instr_mon_s                  exu2tdu_i_mon_qlfy;         // Instruction monitor
+type_scr1_brkm_lsu_mon_s                    lsu2tdu_d_mon_qlfy;         // Data monitor
+logic [SCR1_TDU_ALLTRIG_NUM-1:0]            exu2tdu_bp_retire_qlfy;     // Instruction with breakpoint flag retire
+ `endif // SCR1_DBG_EN
+`endif // SCR1_TDU_EN
+
+`ifdef SCR1_DBG_EN
+// Debug signals:
+logic                                       fetch_pbuf;             // Fetch instructions provided by Program Buffer (via HDU)
+logic                                       csr2hdu_req;            // Request to HDU
+type_scr1_csr_cmd_sel_e                     csr2hdu_cmd;            // HDU command
+logic [SCR1_HDU_DEBUGCSR_ADDR_WIDTH-1:0]    csr2hdu_addr;           // HDU address
+logic [`SCR1_XLEN-1:0]                      csr2hdu_wdata;          // HDU write data
+logic [`SCR1_XLEN-1:0]                      hdu2csr_rdata;          // HDU read data
+type_scr1_csr_resp_e                        hdu2csr_resp;           // HDU response
+                                                                    // Qualified HDU input signals from pipe_rst_n
+                                                                    // reset domain:
+logic                                       csr2hdu_req_qlfy;       //     Request to HDU
+
+logic                                       hwbrk_dsbl;             // Disables TDU
+logic                                       hdu_hwbrk_dsbl;         // Disables TDU
+logic                                       tdu2hdu_dmode_req;      // TDU requests transition to debug mode
+
+logic                                       exu_no_commit;          // Forbid instruction commitment
+logic                                       exu_irq_dsbl;           // Disable IRQ
+logic                                       exu_pc_advmt_dsbl;      // Forbid PC advancement
+logic                                       exu_dmode_sstep_en;     // Enable single-step
+
+logic                                       dbg_halted;             // Debug halted state
+logic                                       dbg_run2halt;           // Transition to debug halted state
+logic                                       dbg_halt2run;           // Transition to run state
+logic                                       dbg_run_start;          // First cycle of run state
+logic [`SCR1_XLEN-1:0]                      dbg_new_pc;             // New PC as starting point for HART Resume
+
+logic                                       ifu2hdu_pbuf_rdy;
+logic                                       hdu2ifu_pbuf_vd;
+logic                                       hdu2ifu_pbuf_err;
+logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]       hdu2ifu_pbuf_instr;
+
+// Qualified HDU input signals from pipe_rst_n reset domain:
+logic                                       ifu2hdu_pbuf_rdy_qlfy;
+logic                                       exu_busy_qlfy;
+logic                                       instret_qlfy;
+logic                                       exu_init_pc_qlfy;
+logic                                       exu_exc_req_qlfy;
+logic                                       brkpt_qlfy;
+
+`endif // SCR1_DBG_EN
+
+logic                                       exu_busy;
+
+
+`ifndef SCR1_CLKCTRL_EN
+logic                                       pipe2clkctl_wake_req_o;
+`endif // SCR1_CLKCTRL_EN
+
+//-------------------------------------------------------------------------------
+// Pipeline logic
+//-------------------------------------------------------------------------------
+assign stop_fetch   = wfi_run2halt
+`ifdef SCR1_DBG_EN
+                    | fetch_pbuf
+`endif // SCR1_DBG_EN
+                    ;
+
+`ifdef SCR1_CLKCTRL_EN
+assign pipe2clkctl_sleep_req_o = wfi_halted & ~imem_txns_pending;
+assign pipe2clkctl_wake_req_o  = csr2exu_ip_ie
+`ifdef SCR1_DBG_EN
+                    | dm2pipe_active_i
+`endif // SCR1_DBG_EN
+                    ;
+`endif // SCR1_CLKCTRL_EN
+
+`ifdef SCR1_DBG_EN
+assign pipe2dm_pc_sample_o = curr_pc;
+`endif // SCR1_DBG_EN
+
+//-------------------------------------------------------------------------------
+// Instruction fetch unit
+//-------------------------------------------------------------------------------
+scr1_pipe_ifu i_pipe_ifu (
+    .rst_n                    (pipe_rst_n         ),
+    .clk                      (clk                ),
+
+    // Instruction memory interface
+    .imem2ifu_req_ack_i       (imem2pipe_req_ack_i),
+    .ifu2imem_req_o           (pipe2imem_req_o    ),
+    .ifu2imem_cmd_o           (pipe2imem_cmd_o    ),
+    .ifu2imem_addr_o          (pipe2imem_addr_o   ),
+    .imem2ifu_rdata_i         (imem2pipe_rdata_i  ),
+    .imem2ifu_resp_i          (imem2pipe_resp_i   ),
+
+    // New PC interface
+    .exu2ifu_pc_new_req_i     (new_pc_req         ),
+    .exu2ifu_pc_new_i         (new_pc             ),
+    .pipe2ifu_stop_fetch_i    (stop_fetch         ),
+
+`ifdef SCR1_DBG_EN
+    // IFU <-> HDU Program Buffer interface
+    .hdu2ifu_pbuf_fetch_i     (fetch_pbuf         ),
+    .ifu2hdu_pbuf_rdy_o       (ifu2hdu_pbuf_rdy   ),
+    .hdu2ifu_pbuf_vd_i        (hdu2ifu_pbuf_vd    ),
+    .hdu2ifu_pbuf_err_i       (hdu2ifu_pbuf_err   ),
+    .hdu2ifu_pbuf_instr_i     (hdu2ifu_pbuf_instr ),
+`endif // SCR1_DBG_EN
+`ifdef SCR1_CLKCTRL_EN
+    .ifu2pipe_imem_txns_pnd_o (imem_txns_pending  ),
+`endif // SCR1_CLKCTRL_EN
+
+    // IFU <-> IDU interface
+    .idu2ifu_rdy_i            (idu2ifu_rdy        ),
+    .ifu2idu_instr_o          (ifu2idu_instr      ),
+    .ifu2idu_imem_err_o       (ifu2idu_imem_err   ),
+    .ifu2idu_err_rvi_hi_o     (ifu2idu_err_rvi_hi ),
+    .ifu2idu_vd_o             (ifu2idu_vd         )
+);
+
+//-------------------------------------------------------------------------------
+// Instruction decode unit
+//-------------------------------------------------------------------------------
+scr1_pipe_idu i_pipe_idu (
+`ifdef SCR1_TRGT_SIMULATION
+    .rst_n                  (pipe_rst_n        ),
+    .clk                    (clk               ),
+`endif // SCR1_TRGT_SIMULATION
+    .idu2ifu_rdy_o          (idu2ifu_rdy       ),
+    .ifu2idu_instr_i        (ifu2idu_instr     ),
+    .ifu2idu_imem_err_i     (ifu2idu_imem_err  ),
+    .ifu2idu_err_rvi_hi_i   (ifu2idu_err_rvi_hi),
+    .ifu2idu_vd_i           (ifu2idu_vd        ),
+
+    .idu2exu_req_o          (idu2exu_req       ),
+    .idu2exu_cmd_o          (idu2exu_cmd       ),
+    .idu2exu_use_rs1_o      (idu2exu_use_rs1   ),
+    .idu2exu_use_rs2_o      (idu2exu_use_rs2   ),
+    .idu2exu_use_rd_o       (idu2exu_use_rd    ),
+    .idu2exu_use_imm_o      (idu2exu_use_imm   ),
+    .exu2idu_rdy_i          (exu2idu_rdy       )
+);
+
+//-------------------------------------------------------------------------------
+// Execution unit
+//-------------------------------------------------------------------------------
+scr1_pipe_exu i_pipe_exu (
+    .rst_n                          (pipe_rst_n              ),
+    .clk                            (clk                     ),
+`ifdef SCR1_CLKCTRL_EN
+    .clk_alw_on                     (clkctl2pipe_clk_alw_on_i),
+    .clk_pipe_en                    (clkctl2pipe_clk_en_i),
+`endif // SCR1_CLKCTRL_EN
+
+    // IDU <-> EXU interface
+    .idu2exu_req_i                  (idu2exu_req             ),
+    .exu2idu_rdy_o                  (exu2idu_rdy             ),
+    .idu2exu_cmd_i                  (idu2exu_cmd             ),
+    .idu2exu_use_rs1_i              (idu2exu_use_rs1         ),
+    .idu2exu_use_rs2_i              (idu2exu_use_rs2         ),
+`ifndef SCR1_NO_EXE_STAGE
+    .idu2exu_use_rd_i               (idu2exu_use_rd          ),
+    .idu2exu_use_imm_i              (idu2exu_use_imm         ),
+`endif // SCR1_NO_EXE_STAGE
+
+    // EXU <-> MPRF interface
+    .exu2mprf_rs1_addr_o            (exu2mprf_rs1_addr       ),
+    .mprf2exu_rs1_data_i            (mprf2exu_rs1_data       ),
+    .exu2mprf_rs2_addr_o            (exu2mprf_rs2_addr       ),
+    .mprf2exu_rs2_data_i            (mprf2exu_rs2_data       ),
+    .exu2mprf_w_req_o               (exu2mprf_w_req          ),
+    .exu2mprf_rd_addr_o             (exu2mprf_rd_addr        ),
+    .exu2mprf_rd_data_o             (exu2mprf_rd_data        ),
+
+    // EXU <-> CSR read/write interface
+    .exu2csr_rw_addr_o              (exu2csr_rw_addr         ),
+    .exu2csr_r_req_o                (exu2csr_r_req           ),
+    .csr2exu_r_data_i               (csr2exu_r_data          ),
+    .exu2csr_w_req_o                (exu2csr_w_req           ),
+    .exu2csr_w_cmd_o                (exu2csr_w_cmd           ),
+    .exu2csr_w_data_o               (exu2csr_w_data          ),
+    .csr2exu_rw_exc_i               (csr2exu_rw_exc          ),
+
+    // EXU <-> CSR event interface
+    .exu2csr_take_irq_o             (exu2csr_take_irq        ),
+    .exu2csr_take_exc_o             (exu2csr_take_exc        ),
+    .exu2csr_mret_update_o          (exu2csr_mret_update     ),
+    .exu2csr_mret_instr_o           (exu2csr_mret_instr      ),
+    .exu2csr_exc_code_o             (exu2csr_exc_code        ),
+    .exu2csr_trap_val_o             (exu2csr_trap_val        ),
+    .csr2exu_new_pc_i               (csr2exu_new_pc          ),
+    .csr2exu_irq_i                  (csr2exu_irq             ),
+    .csr2exu_ip_ie_i                (csr2exu_ip_ie           ),
+    .csr2exu_mstatus_mie_up_i       (csr2exu_mstatus_mie_up  ),
+
+    // EXU <-> DMEM interface
+    .exu2dmem_req_o                 (pipe2dmem_req_o         ),
+    .exu2dmem_cmd_o                 (pipe2dmem_cmd_o         ),
+    .exu2dmem_width_o               (pipe2dmem_width_o       ),
+    .exu2dmem_addr_o                (pipe2dmem_addr_o        ),
+    .exu2dmem_wdata_o               (pipe2dmem_wdata_o       ),
+    .dmem2exu_req_ack_i             (dmem2pipe_req_ack_i     ),
+    .dmem2exu_rdata_i               (dmem2pipe_rdata_i       ),
+    .dmem2exu_resp_i                (dmem2pipe_resp_i        ),
+
+`ifdef SCR1_DBG_EN
+    // EXU <-> HDU interface
+    .hdu2exu_no_commit_i            (exu_no_commit           ),
+    .hdu2exu_irq_dsbl_i             (exu_irq_dsbl            ),
+    .hdu2exu_pc_advmt_dsbl_i        (exu_pc_advmt_dsbl       ),
+    .hdu2exu_dmode_sstep_en_i       (exu_dmode_sstep_en      ),
+    .hdu2exu_pbuf_fetch_i           (fetch_pbuf              ),
+    .hdu2exu_dbg_halted_i           (dbg_halted              ),
+    .hdu2exu_dbg_run2halt_i         (dbg_run2halt            ),
+    .hdu2exu_dbg_halt2run_i         (dbg_halt2run            ),
+    .hdu2exu_dbg_run_start_i        (dbg_run_start           ),
+    .hdu2exu_dbg_new_pc_i           (dbg_new_pc              ),
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+    // EXU <-> TDU interface
+    .exu2tdu_imon_o                 (exu2tdu_i_mon           ),
+    .tdu2exu_ibrkpt_match_i         (tdu2exu_i_match         ),
+    .tdu2exu_ibrkpt_exc_req_i       (tdu2exu_i_x_req         ),
+    .lsu2tdu_dmon_o                 (lsu2tdu_d_mon           ),
+    .tdu2lsu_ibrkpt_exc_req_i       (tdu2lsu_i_x_req         ),
+    .tdu2lsu_dbrkpt_match_i         (tdu2lsu_d_match         ),
+    .tdu2lsu_dbrkpt_exc_req_i       (tdu2lsu_d_x_req         ),
+    .exu2tdu_ibrkpt_ret_o           (exu2tdu_bp_retire       ),
+    .exu2hdu_ibrkpt_hw_o            (brkpt_hw                ),
+`endif // SCR1_TDU_EN
+
+    // EXU control
+    .exu2pipe_exc_req_o             (exu_exc_req             ),
+    .exu2pipe_brkpt_o               (brkpt                   ),
+    .exu2pipe_init_pc_o             (exu_init_pc             ),
+    .exu2pipe_wfi_run2halt_o        (wfi_run2halt            ),
+    .exu2pipe_instret_o             (instret                 ),
+    .exu2csr_instret_no_exc_o       (instret_nexc            ),
+    .exu2pipe_exu_busy_o            (exu_busy                ),
+
+    // PC interface
+`ifdef SCR1_CLKCTRL_EN
+    .exu2pipe_wfi_halted_o          (wfi_halted              ),
+`endif // SCR1_CLKCTRL_EN
+    .exu2pipe_pc_curr_o             (curr_pc                 ),
+    .exu2csr_pc_next_o              (next_pc                 ),
+    .exu2ifu_pc_new_req_o           (new_pc_req              ),
+    .exu2ifu_pc_new_o               (new_pc                  )
+);
+
+//-------------------------------------------------------------------------------
+// Multi-port register file
+//-------------------------------------------------------------------------------
+scr1_pipe_mprf i_pipe_mprf (
+`ifdef SCR1_MPRF_RST_EN
+    .rst_n                  (pipe_rst_n       ),
+`endif // SCR1_MPRF_RST_EN
+    .clk                    (clk              ),
+
+    // EXU <-> MPRF interface
+    .exu2mprf_rs1_addr_i    (exu2mprf_rs1_addr),
+    .mprf2exu_rs1_data_o    (mprf2exu_rs1_data),
+    .exu2mprf_rs2_addr_i    (exu2mprf_rs2_addr),
+    .mprf2exu_rs2_data_o    (mprf2exu_rs2_data),
+    .exu2mprf_w_req_i       (exu2mprf_w_req   ),
+    .exu2mprf_rd_addr_i     (exu2mprf_rd_addr ),
+    .exu2mprf_rd_data_i     (exu2mprf_rd_data )
+);
+
+//-------------------------------------------------------------------------------
+// Control and status registers
+//-------------------------------------------------------------------------------
+scr1_pipe_csr i_pipe_csr (
+    .rst_n                      (pipe_rst_n              ),
+    .clk                        (clk                     ),
+`ifdef SCR1_CLKCTRL_EN
+    .clk_alw_on                 (clkctl2pipe_clk_alw_on_i),
+`endif // SCR1_CLKCTRL_EN
+
+    // EXU <-> CSR read/write interface
+    .exu2csr_r_req_i            (exu2csr_r_req           ),
+    .exu2csr_rw_addr_i          (exu2csr_rw_addr         ),
+    .csr2exu_r_data_o           (csr2exu_r_data          ),
+    .exu2csr_w_req_i            (exu2csr_w_req           ),
+    .exu2csr_w_cmd_i            (exu2csr_w_cmd           ),
+    .exu2csr_w_data_i           (exu2csr_w_data          ),
+    .csr2exu_rw_exc_o           (csr2exu_rw_exc          ),
+
+    // EXU <-> CSR event interface
+    .exu2csr_take_irq_i         (exu2csr_take_irq        ),
+    .exu2csr_take_exc_i         (exu2csr_take_exc        ),
+    .exu2csr_mret_update_i      (exu2csr_mret_update     ),
+    .exu2csr_mret_instr_i       (exu2csr_mret_instr      ),
+    .exu2csr_exc_code_i         (exu2csr_exc_code        ),
+    .exu2csr_trap_val_i         (exu2csr_trap_val        ),
+    .csr2exu_new_pc_o           (csr2exu_new_pc          ),
+    .csr2exu_irq_o              (csr2exu_irq             ),
+    .csr2exu_ip_ie_o            (csr2exu_ip_ie           ),
+    .csr2exu_mstatus_mie_up_o   (csr2exu_mstatus_mie_up  ),
+
+`ifdef SCR1_IPIC_EN
+    // CSR <-> IPIC interface
+    .csr2ipic_r_req_o           (csr2ipic_r_req          ),
+    .csr2ipic_w_req_o           (csr2ipic_w_req          ),
+    .csr2ipic_addr_o            (csr2ipic_addr           ),
+    .csr2ipic_wdata_o           (csr2ipic_wdata          ),
+    .ipic2csr_rdata_i           (ipic2csr_rdata          ),
+`endif // SCR1_IPIC_EN
+
+    // CSR <-> PC interface
+    .exu2csr_pc_curr_i          (curr_pc                 ),
+    .exu2csr_pc_next_i          (next_pc                 ),
+`ifndef SCR1_CSR_REDUCED_CNT
+    .exu2csr_instret_no_exc_i   (instret_nexc            ),
+`endif // SCR1_CSR_REDUCED_CNT
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    .soc2csr_irq_ext_i          (ipic2csr_irq            ),
+`else // SCR1_IPIC_EN
+    .soc2csr_irq_ext_i          (soc2pipe_irq_ext_i      ),
+`endif // SCR1_IPIC_EN
+    .soc2csr_irq_soft_i         (soc2pipe_irq_soft_i     ),
+    .soc2csr_irq_mtimer_i       (soc2pipe_irq_mtimer_i   ),
+
+    // Memory-mapped external timer
+    .soc2csr_mtimer_val_i       (soc2pipe_mtimer_val_i   ),
+
+`ifdef SCR1_DBG_EN
+    // CSR <-> HDU interface
+    .csr2hdu_req_o              (csr2hdu_req             ),
+    .csr2hdu_cmd_o              (csr2hdu_cmd             ),
+    .csr2hdu_addr_o             (csr2hdu_addr            ),
+    .csr2hdu_wdata_o            (csr2hdu_wdata           ),
+    .hdu2csr_rdata_i            (hdu2csr_rdata           ),
+    .hdu2csr_resp_i             (hdu2csr_resp            ),
+    .hdu2csr_no_commit_i        (exu_no_commit           ),
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TDU_EN
+    // CSR <-> TDU interface
+    .csr2tdu_req_o              (csr2tdu_req             ),
+    .csr2tdu_cmd_o              (csr2tdu_cmd             ),
+    .csr2tdu_addr_o             (csr2tdu_addr            ),
+    .csr2tdu_wdata_o            (csr2tdu_wdata           ),
+    .tdu2csr_rdata_i            (tdu2csr_rdata           ),
+    .tdu2csr_resp_i             (tdu2csr_resp            ),
+`endif // SCR1_TDU_EN
+    .soc2csr_fuse_mhartid_i     (soc2pipe_fuse_mhartid_i )
+);
+
+//-------------------------------------------------------------------------------
+// Integrated programmable interrupt controller
+//-------------------------------------------------------------------------------
+`ifdef SCR1_IPIC_EN
+scr1_ipic i_pipe_ipic (
+    .rst_n                  (pipe_rst_n              ),
+`ifdef SCR1_CLKCTRL_EN
+    .clk                    (clkctl2pipe_clk_alw_on_i),
+`else // SCR1_CLKCTRL_EN
+    .clk                    (clk                     ),
+`endif // SCR1_CLKCTRL_EN
+    .soc2ipic_irq_lines_i   (soc2pipe_irq_lines_i    ),
+    .csr2ipic_r_req_i       (csr2ipic_r_req          ),
+    .csr2ipic_w_req_i       (csr2ipic_w_req          ),
+    .csr2ipic_addr_i        (csr2ipic_addr           ),
+    .csr2ipic_wdata_i       (csr2ipic_wdata          ),
+    .ipic2csr_rdata_o       (ipic2csr_rdata          ),
+    .ipic2csr_irq_m_req_o   (ipic2csr_irq            )
+);
+`endif // SCR1_IPIC_EN
+
+//-------------------------------------------------------------------------------
+// Breakpoint module
+//-------------------------------------------------------------------------------
+`ifdef SCR1_TDU_EN
+scr1_pipe_tdu i_pipe_tdu (
+    // Common signals
+ `ifdef SCR1_DBG_EN
+    .rst_n                      (dbg_rst_n             ),
+ `else
+    .rst_n                      (rst_n                 ),
+ `endif // SCR1_DBG_EN
+    .clk                        (clk                   ),
+    .clk_en                     (1'b1                  ),
+ `ifdef SCR1_DBG_EN
+    .tdu_dsbl_i                 (hwbrk_dsbl            ),
+ `else // SCR1_DBG_EN
+    .tdu_dsbl_i                 (1'b0                  ),
+ `endif // SCR1_DBG_EN
+
+    // TDU <-> CSR interface
+ `ifdef SCR1_DBG_EN
+    .csr2tdu_req_i              (csr2tdu_req_qlfy      ),
+    .csr2tdu_cmd_i              (csr2tdu_cmd           ),
+    .csr2tdu_addr_i             (csr2tdu_addr          ),
+    .csr2tdu_wdata_i            (csr2tdu_wdata         ),
+ `else // SCR1_DBG_EN
+    .csr2tdu_req_i              (csr2tdu_req           ),
+    .csr2tdu_cmd_i              (csr2tdu_cmd           ),
+    .csr2tdu_addr_i             (csr2tdu_addr          ),
+    .csr2tdu_wdata_i            (csr2tdu_wdata         ),
+ `endif // SCR1_DBG_EN
+    .tdu2csr_rdata_o            (tdu2csr_rdata         ),
+    .tdu2csr_resp_o             (tdu2csr_resp          ),
+
+    // TDU <-> EXU interface
+ `ifdef SCR1_DBG_EN
+    .exu2tdu_imon_i             (exu2tdu_i_mon_qlfy    ),
+ `else // SCR1_DBG_EN
+    .exu2tdu_imon_i             (exu2tdu_i_mon         ),
+ `endif // SCR1_DBG_EN
+    .tdu2exu_ibrkpt_match_o     (tdu2exu_i_match       ),
+    .tdu2exu_ibrkpt_exc_req_o   (tdu2exu_i_x_req       ),
+ `ifdef SCR1_DBG_EN
+    .exu2tdu_bp_retire_i        (exu2tdu_bp_retire_qlfy),
+ `else // SCR1_DBG_EN
+    .exu2tdu_bp_retire_i        (exu2tdu_bp_retire     ),
+ `endif // SCR1_DBG_EN
+
+    // TDU <-> LSU interface
+    .tdu2lsu_ibrkpt_exc_req_o   (tdu2lsu_i_x_req       ),
+ `ifdef SCR1_DBG_EN
+    .lsu2tdu_dmon_i             (lsu2tdu_d_mon_qlfy    ),
+ `else // SCR1_DBG_EN
+    .lsu2tdu_dmon_i             (lsu2tdu_d_mon         ),
+ `endif // SCR1_DBG_EN
+    .tdu2lsu_dbrkpt_match_o     (tdu2lsu_d_match       ),
+    .tdu2lsu_dbrkpt_exc_req_o   (tdu2lsu_d_x_req       ),
+    // EPU I/F
+ `ifdef SCR1_DBG_EN
+    .tdu2hdu_dmode_req_o        (tdu2hdu_dmode_req     )
+ `else // SCR1_DBG_EN
+    .tdu2hdu_dmode_req_o        (                      )
+ `endif // SCR1_DBG_EN
+);
+
+ `ifdef SCR1_DBG_EN
+assign hwbrk_dsbl               = (~dbg_en) | hdu_hwbrk_dsbl;
+//
+assign csr2tdu_req_qlfy         = dbg_en & csr2tdu_req & pipe2hdu_rdc_qlfy_i;
+//
+assign exu2tdu_i_mon_qlfy.vd    = exu2tdu_i_mon.vd & pipe2hdu_rdc_qlfy_i;
+assign exu2tdu_i_mon_qlfy.req   = exu2tdu_i_mon.req;
+assign exu2tdu_i_mon_qlfy.addr  = exu2tdu_i_mon.addr;
+assign lsu2tdu_d_mon_qlfy.vd    = lsu2tdu_d_mon.vd & pipe2hdu_rdc_qlfy_i;
+assign lsu2tdu_d_mon_qlfy.load  = lsu2tdu_d_mon.load;
+assign lsu2tdu_d_mon_qlfy.store = lsu2tdu_d_mon.store;
+assign lsu2tdu_d_mon_qlfy.addr  = lsu2tdu_d_mon.addr;
+assign exu2tdu_bp_retire_qlfy   = exu2tdu_bp_retire & {$bits(exu2tdu_bp_retire){pipe2hdu_rdc_qlfy_i}};
+ `endif // SCR1_DBG_EN
+
+`endif // SCR1_TDU_EN
+
+//-------------------------------------------------------------------------------
+// HART Debug Unit (HDU)
+//-------------------------------------------------------------------------------
+`ifdef SCR1_DBG_EN
+scr1_pipe_hdu i_pipe_hdu (
+    // Common signals
+    .rst_n                      (dbg_rst_n             ),
+    .clk_en                     (dm2pipe_active_i      ),
+`ifdef SCR1_CLKCTRL_EN
+    .clk_pipe_en                (clkctl2pipe_clk_en_i  ),
+    .clk                        (clkctl2pipe_clk_dbgc_i),
+`else
+    .clk                        (clk                   ),
+`endif // SCR1_CLKCTRL_EN
+
+    // Control/status registers i/f
+    .csr2hdu_req_i              (csr2hdu_req_qlfy      ),
+    .csr2hdu_cmd_i              (csr2hdu_cmd           ),
+    .csr2hdu_addr_i             (csr2hdu_addr          ),
+    .csr2hdu_wdata_i            (csr2hdu_wdata         ),
+    .hdu2csr_resp_o             (hdu2csr_resp          ),
+    .hdu2csr_rdata_o            (hdu2csr_rdata         ),
+
+    // HART Run Control i/f
+    .pipe2hdu_rdc_qlfy_i        (pipe2hdu_rdc_qlfy_i   ),
+    .dm2hdu_cmd_req_i           (dm2pipe_cmd_req_i     ),
+    .dm2hdu_cmd_i               (dm2pipe_cmd_i         ),
+    .hdu2dm_cmd_resp_o          (pipe2dm_cmd_resp_o    ),
+    .hdu2dm_cmd_rcode_o         (pipe2dm_cmd_rcode_o   ),
+    .hdu2dm_hart_event_o        (pipe2dm_hart_event_o  ),
+    .hdu2dm_hart_status_o       (pipe2dm_hart_status_o ),
+
+    // Program Buffer - HART instruction execution i/f
+    .hdu2dm_pbuf_addr_o         (pipe2dm_pbuf_addr_o   ),
+    .dm2hdu_pbuf_instr_i        (dm2pipe_pbuf_instr_i  ),
+
+    // HART Abstract Data regs i/f
+    .hdu2dm_dreg_req_o          (pipe2dm_dreg_req_o    ),
+    .hdu2dm_dreg_wr_o           (pipe2dm_dreg_wr_o     ),
+    .hdu2dm_dreg_wdata_o        (pipe2dm_dreg_wdata_o  ),
+    .dm2hdu_dreg_resp_i         (dm2pipe_dreg_resp_i   ),
+    .dm2hdu_dreg_fail_i         (dm2pipe_dreg_fail_i   ),
+    .dm2hdu_dreg_rdata_i        (dm2pipe_dreg_rdata_i  ),
+    //
+`ifdef SCR1_TDU_EN
+    // HDU <-> TDU interface
+    .hdu2tdu_hwbrk_dsbl_o       (hdu_hwbrk_dsbl        ),
+    .tdu2hdu_dmode_req_i        (tdu2hdu_dmode_req     ),
+    .exu2hdu_ibrkpt_hw_i        (brkpt_hw              ),
+`endif // SCR1_TDU_EN
+
+    // HART Run Status
+    .pipe2hdu_exu_busy_i        (exu_busy_qlfy         ),
+    .pipe2hdu_instret_i         (instret_qlfy          ),
+    .pipe2hdu_init_pc_i         (exu_init_pc_qlfy      ),
+
+    // HART Halt Status
+    .pipe2hdu_exu_exc_req_i     (exu_exc_req_qlfy      ),
+    .pipe2hdu_brkpt_i           (brkpt_qlfy            ),
+
+    // HART Run Control
+    .hdu2exu_pbuf_fetch_o       (fetch_pbuf            ),
+    .hdu2exu_no_commit_o        (exu_no_commit         ),
+    .hdu2exu_irq_dsbl_o         (exu_irq_dsbl          ),
+    .hdu2exu_pc_advmt_dsbl_o    (exu_pc_advmt_dsbl     ),
+    .hdu2exu_dmode_sstep_en_o   (exu_dmode_sstep_en    ),
+
+    // HART state
+    .hdu2exu_dbg_halted_o       (dbg_halted            ),
+    .hdu2exu_dbg_run2halt_o     (dbg_run2halt          ),
+    .hdu2exu_dbg_halt2run_o     (dbg_halt2run          ),
+    .hdu2exu_dbg_run_start_o    (dbg_run_start         ),
+
+    // PC interface
+    .pipe2hdu_pc_curr_i         (curr_pc               ),
+    .hdu2exu_dbg_new_pc_o       (dbg_new_pc            ),
+
+    // Prgram Buffer Instruction interface
+    .ifu2hdu_pbuf_instr_rdy_i   (ifu2hdu_pbuf_rdy_qlfy ),
+    .hdu2ifu_pbuf_instr_vd_o    (hdu2ifu_pbuf_vd       ),
+    .hdu2ifu_pbuf_instr_err_o   (hdu2ifu_pbuf_err      ),
+    .hdu2ifu_pbuf_instr_o       (hdu2ifu_pbuf_instr    )
+);
+
+assign csr2hdu_req_qlfy         = csr2hdu_req & dbg_en & pipe2hdu_rdc_qlfy_i;
+//
+assign exu_busy_qlfy            = exu_busy          & {$bits(exu_busy){pipe2hdu_rdc_qlfy_i}};
+assign instret_qlfy             = instret           & {$bits(instret){pipe2hdu_rdc_qlfy_i}};
+assign exu_init_pc_qlfy         = exu_init_pc       & {$bits(exu_init_pc){pipe2hdu_rdc_qlfy_i}};
+assign exu_exc_req_qlfy         = exu_exc_req       & {$bits(exu_exc_req){pipe2hdu_rdc_qlfy_i}};
+assign brkpt_qlfy               = brkpt             & {$bits(brkpt){pipe2hdu_rdc_qlfy_i}};
+assign ifu2hdu_pbuf_rdy_qlfy    = ifu2hdu_pbuf_rdy  & {$bits(ifu2hdu_pbuf_rdy){pipe2hdu_rdc_qlfy_i}};
+
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Tracelog
+//-------------------------------------------------------------------------------
+
+scr1_tracelog i_tracelog (
+    .rst_n                          (pipe_rst_n                         ),
+    .clk                            (clk                                ),
+    .soc2pipe_fuse_mhartid_i        (soc2pipe_fuse_mhartid_i            ),
+
+    // MPRF
+    .mprf2trace_int_i               (i_pipe_mprf.mprf_int               ),
+    .mprf2trace_wr_en_i             (i_pipe_mprf.exu2mprf_w_req_i       ),
+    .mprf2trace_wr_addr_i           (i_pipe_mprf.exu2mprf_rd_addr_i     ),
+    .mprf2trace_wr_data_i           (i_pipe_mprf.exu2mprf_rd_data_i     ),
+
+    // EXU
+    .exu2trace_update_pc_en_i       (i_pipe_exu.update_pc_en            ),
+    .exu2trace_update_pc_i          (i_pipe_exu.update_pc               ),
+
+    // IFU
+    .ifu2trace_instr_i              (i_pipe_ifu.ifu2idu_instr_o         ),
+
+    // CSR
+    .csr2trace_mstatus_mie_i        (i_pipe_csr.csr_mstatus_mie_ff      ),
+    .csr2trace_mstatus_mpie_i       (i_pipe_csr.csr_mstatus_mpie_ff     ),
+    .csr2trace_mtvec_base_i         (i_pipe_csr.csr_mtvec_base          ),
+    .csr2trace_mtvec_mode_i         (i_pipe_csr.csr_mtvec_mode          ),
+    .csr2trace_mie_meie_i           (i_pipe_csr.csr_mie_meie_ff         ),
+    .csr2trace_mie_mtie_i           (i_pipe_csr.csr_mie_mtie_ff         ),
+    .csr2trace_mie_msie_i           (i_pipe_csr.csr_mie_msie_ff         ),
+    .csr2trace_mip_meip_i           (i_pipe_csr.csr_mip_meip            ),
+    .csr2trace_mip_mtip_i           (i_pipe_csr.csr_mip_mtip            ),
+    .csr2trace_mip_msip_i           (i_pipe_csr.csr_mip_msip            ),
+    .csr2trace_mepc_i               (i_pipe_csr.csr_mepc_ff             ),
+    .csr2trace_mcause_irq_i         (i_pipe_csr.csr_mcause_i_ff         ),
+    .csr2trace_mcause_ec_i          (i_pipe_csr.csr_mcause_ec_ff        ),
+    .csr2trace_mtval_i              (i_pipe_csr.csr_mtval_ff            ),
+    .csr2trace_mstatus_mie_up_i     (i_pipe_csr.csr2exu_mstatus_mie_up_o),
+
+    // Events
+    .csr2trace_e_exc_i              (i_pipe_csr.e_exc                   ),
+    .csr2trace_e_irq_i              (i_pipe_csr.e_irq                   ),
+    .pipe2trace_e_wake_i            (pipe2clkctl_wake_req_o             ),
+    .csr2trace_e_mret_i             (i_pipe_csr.e_mret                  )
+);
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_pipe_top
diff --git a/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_tracelog.sv b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_tracelog.sv
new file mode 100644
index 0000000..1d86001
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/pipeline/scr1_tracelog.sv
@@ -0,0 +1,455 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_tracelog.sv>
+/// @brief      Core tracelog module
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_csr.svh"
+
+`ifdef SCR1_TRGT_SIMULATION
+
+module scr1_tracelog (
+    input   logic                                 rst_n,                        // Tracelog reset
+    input   logic                                 clk,                          // Tracelog clock
+    input   logic [`SCR1_XLEN-1:0]                soc2pipe_fuse_mhartid_i,      // Fuse MHARTID
+
+    // MPRF
+`ifdef  SCR1_MPRF_RAM
+    input   logic   [`SCR1_XLEN-1:0]            mprf2trace_int_i   [1:`SCR1_MPRF_SIZE-1], // MPRF registers content
+`else // SCR1_MPRF_RAM
+    input   type_scr1_mprf_v [1:`SCR1_MPRF_SIZE-1] mprf2trace_int_i,             // MPRF registers content
+`endif // SCR1_MPRF_RAM
+    input   logic                                 mprf2trace_wr_en_i,           // MPRF write enable
+    input   logic [`SCR1_MPRF_AWIDTH-1:0]         mprf2trace_wr_addr_i,         // MPRF write address
+    input   logic [`SCR1_XLEN-1:0]                mprf2trace_wr_data_i,         // MPRF write data
+
+    // EXU
+    input   logic                                 exu2trace_update_pc_en_i,     // PC updated flag
+    input   logic [`SCR1_XLEN-1:0]                exu2trace_update_pc_i,        // Next PC value
+
+    // IFU
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]         ifu2trace_instr_i,            // Current instruction from IFU stage
+
+    // CSR
+    input   logic                                 csr2trace_mstatus_mie_i,      // CSR MSTATUS.mie bit
+    input   logic                                 csr2trace_mstatus_mpie_i,     // CSR MSTATUS.mpie bit
+    input   logic [`SCR1_XLEN-1:6]                csr2trace_mtvec_base_i,       // CSR MTVEC.
+    input   logic                                 csr2trace_mtvec_mode_i,       // CSR MTVEC.
+    input   logic                                 csr2trace_mie_meie_i,         // CSR MIE.meie bit
+    input   logic                                 csr2trace_mie_mtie_i,         // CSR MIE.mtie bit
+    input   logic                                 csr2trace_mie_msie_i,         // CSR MIE.msie bit
+    input   logic                                 csr2trace_mip_meip_i,         // CSR MIP.meip bit
+    input   logic                                 csr2trace_mip_mtip_i,         // CSR MIP.mtip bit
+    input   logic                                 csr2trace_mip_msip_i,         // CSR MIP.msip bit
+ `ifdef SCR1_RVC_EXT
+    input   logic [`SCR1_XLEN-1:1]                csr2trace_mepc_i,             // CSR MEPC register
+ `else // SCR1_RVC_EXT
+    input   logic [`SCR1_XLEN-1:2]                csr2trace_mepc_i,             // CSR MEPC register
+ `endif // SCR1_RVC_EXT
+    input   logic                                 csr2trace_mcause_irq_i,       // CSR MCAUSE.interrupt bit
+    input   type_scr1_exc_code_e                  csr2trace_mcause_ec_i,        // CSR MCAUSE.exception_code bit
+    input   logic [`SCR1_XLEN-1:0]                csr2trace_mtval_i,            // CSR MTVAL register
+    input   logic                                 csr2trace_mstatus_mie_up_i,   // CSR MSTATUS.mie update flag
+
+    // Events
+    input   logic                                 csr2trace_e_exc_i,            // exception event
+    input   logic                                 csr2trace_e_irq_i,            // interrupt event
+    input   logic                                 pipe2trace_e_wake_i,          // pipe wakeup event
+    input   logic                                 csr2trace_e_mret_i            // MRET instruction
+);
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef struct {
+    logic [`SCR1_XLEN-1:0]      INT_00_ZERO ;
+    logic [`SCR1_XLEN-1:0]      INT_01_RA   ;
+    logic [`SCR1_XLEN-1:0]      INT_02_SP   ;
+    logic [`SCR1_XLEN-1:0]      INT_03_GP   ;
+    logic [`SCR1_XLEN-1:0]      INT_04_TP   ;
+    logic [`SCR1_XLEN-1:0]      INT_05_T0   ;
+    logic [`SCR1_XLEN-1:0]      INT_06_T1   ;
+    logic [`SCR1_XLEN-1:0]      INT_07_T2   ;
+    logic [`SCR1_XLEN-1:0]      INT_08_S0   ;
+    logic [`SCR1_XLEN-1:0]      INT_09_S1   ;
+    logic [`SCR1_XLEN-1:0]      INT_10_A0   ;
+    logic [`SCR1_XLEN-1:0]      INT_11_A1   ;
+    logic [`SCR1_XLEN-1:0]      INT_12_A2   ;
+    logic [`SCR1_XLEN-1:0]      INT_13_A3   ;
+    logic [`SCR1_XLEN-1:0]      INT_14_A4   ;
+    logic [`SCR1_XLEN-1:0]      INT_15_A5   ;
+`ifndef SCR1_RVE_EXT
+    logic [`SCR1_XLEN-1:0]      INT_16_A6   ;
+    logic [`SCR1_XLEN-1:0]      INT_17_A7   ;
+    logic [`SCR1_XLEN-1:0]      INT_18_S2   ;
+    logic [`SCR1_XLEN-1:0]      INT_19_S3   ;
+    logic [`SCR1_XLEN-1:0]      INT_20_S4   ;
+    logic [`SCR1_XLEN-1:0]      INT_21_S5   ;
+    logic [`SCR1_XLEN-1:0]      INT_22_S6   ;
+    logic [`SCR1_XLEN-1:0]      INT_23_S7   ;
+    logic [`SCR1_XLEN-1:0]      INT_24_S8   ;
+    logic [`SCR1_XLEN-1:0]      INT_25_S9   ;
+    logic [`SCR1_XLEN-1:0]      INT_26_S10  ;
+    logic [`SCR1_XLEN-1:0]      INT_27_S11  ;
+    logic [`SCR1_XLEN-1:0]      INT_28_T3   ;
+    logic [`SCR1_XLEN-1:0]      INT_29_T4   ;
+    logic [`SCR1_XLEN-1:0]      INT_30_T5   ;
+    logic [`SCR1_XLEN-1:0]      INT_31_T6   ;
+`endif // SCR1_RVE_EXT
+} type_scr1_ireg_name_s;
+
+typedef struct packed {
+    logic [`SCR1_XLEN-1:0]  mstatus;
+    logic [`SCR1_XLEN-1:0]  mtvec;
+    logic [`SCR1_XLEN-1:0]  mie;
+    logic [`SCR1_XLEN-1:0]  mip;
+    logic [`SCR1_XLEN-1:0]  mepc;
+    logic [`SCR1_XLEN-1:0]  mcause;
+    logic [`SCR1_XLEN-1:0]  mtval;
+} type_scr1_csr_trace_s;
+
+//-------------------------------------------------------------------------------
+// Local Signal Declaration
+//-------------------------------------------------------------------------------
+
+type_scr1_ireg_name_s               mprf_int_alias;
+
+`ifdef SCR1_TRACE_LOG_EN
+
+time                                current_time;
+
+// Tracelog control signals
+logic                               trace_flag;
+logic                               trace_update;
+logic                               trace_update_r;
+byte                                event_type;
+
+logic [`SCR1_XLEN-1:0]              trace_pc;
+logic [`SCR1_XLEN-1:0]              trace_npc;
+logic [`SCR1_IMEM_DWIDTH-1:0]       trace_instr;
+
+type_scr1_csr_trace_s               csr_trace1;
+
+// File handlers
+int unsigned                        trace_fhandler_core;
+
+// MPRF signals
+logic                               mprf_up;
+logic [`SCR1_MPRF_AWIDTH-1:0]       mprf_addr;
+logic [`SCR1_XLEN-1:0]              mprf_wdata;
+
+string                              hart;
+string                              test_name;
+
+`endif // SCR1_TRACE_LOG_EN
+
+//-------------------------------------------------------------------------------
+// Local tasks
+//-------------------------------------------------------------------------------
+
+`ifdef SCR1_TRACE_LOG_EN
+
+task trace_write_common;
+    $fwrite(trace_fhandler_core, "%16d  ", current_time);
+    // $fwrite(trace_fhandler_core, " 0  ");
+    $fwrite(trace_fhandler_core, " %s  ",  event_type);
+    $fwrite(trace_fhandler_core, " %8x  ", trace_pc);
+    $fwrite(trace_fhandler_core, " %8x  ", trace_instr);
+    $fwrite(trace_fhandler_core, " %8x  ", trace_npc);
+endtask // trace_write_common
+
+task trace_write_int_walias;
+    case (mprf_addr)
+        0  :  $fwrite(trace_fhandler_core, " x00_zero  ");
+        1  :  $fwrite(trace_fhandler_core, " x01_ra    ");
+        2  :  $fwrite(trace_fhandler_core, " x02_sp    ");
+        3  :  $fwrite(trace_fhandler_core, " x03_gp    ");
+        4  :  $fwrite(trace_fhandler_core, " x04_tp    ");
+        5  :  $fwrite(trace_fhandler_core, " x05_t0    ");
+        6  :  $fwrite(trace_fhandler_core, " x06_t1    ");
+        7  :  $fwrite(trace_fhandler_core, " x07_t2    ");
+        8  :  $fwrite(trace_fhandler_core, " x08_s0    ");
+        9  :  $fwrite(trace_fhandler_core, " x09_s1    ");
+        10 :  $fwrite(trace_fhandler_core, " x10_a0    ");
+        11 :  $fwrite(trace_fhandler_core, " x11_a1    ");
+        12 :  $fwrite(trace_fhandler_core, " x12_a2    ");
+        13 :  $fwrite(trace_fhandler_core, " x13_a3    ");
+        14 :  $fwrite(trace_fhandler_core, " x14_a4    ");
+        15 :  $fwrite(trace_fhandler_core, " x15_a5    ");
+`ifndef SCR1_RVE_EXT
+        16 :  $fwrite(trace_fhandler_core, " x16_a6    ");
+        17 :  $fwrite(trace_fhandler_core, " x17_a7    ");
+        18 :  $fwrite(trace_fhandler_core, " x18_s2    ");
+        19 :  $fwrite(trace_fhandler_core, " x19_s3    ");
+        20 :  $fwrite(trace_fhandler_core, " x20_s4    ");
+        21 :  $fwrite(trace_fhandler_core, " x21_s5    ");
+        22 :  $fwrite(trace_fhandler_core, " x22_s6    ");
+        23 :  $fwrite(trace_fhandler_core, " x23_s7    ");
+        24 :  $fwrite(trace_fhandler_core, " x24_s8    ");
+        25 :  $fwrite(trace_fhandler_core, " x25_s9    ");
+        26 :  $fwrite(trace_fhandler_core, " x26_s10   ");
+        27 :  $fwrite(trace_fhandler_core, " x27_s11   ");
+        28 :  $fwrite(trace_fhandler_core, " x28_t3    ");
+        29 :  $fwrite(trace_fhandler_core, " x29_t4    ");
+        30 :  $fwrite(trace_fhandler_core, " x30_t5    ");
+        31 :  $fwrite(trace_fhandler_core, " x31_t6    ");
+`endif // SCR1_RVE_EXT
+        default: begin
+              $fwrite(trace_fhandler_core, " xxx       ");
+        end
+    endcase
+endtask
+
+`endif // SCR1_TRACE_LOG_EN
+
+//-------------------------------------------------------------------------------
+// MPRF Registers assignment
+//-------------------------------------------------------------------------------
+assign mprf_int_alias.INT_00_ZERO   = '0;
+assign mprf_int_alias.INT_01_RA     = mprf2trace_int_i[1];
+assign mprf_int_alias.INT_02_SP     = mprf2trace_int_i[2];
+assign mprf_int_alias.INT_03_GP     = mprf2trace_int_i[3];
+assign mprf_int_alias.INT_04_TP     = mprf2trace_int_i[4];
+assign mprf_int_alias.INT_05_T0     = mprf2trace_int_i[5];
+assign mprf_int_alias.INT_06_T1     = mprf2trace_int_i[6];
+assign mprf_int_alias.INT_07_T2     = mprf2trace_int_i[7];
+assign mprf_int_alias.INT_08_S0     = mprf2trace_int_i[8];
+assign mprf_int_alias.INT_09_S1     = mprf2trace_int_i[9];
+assign mprf_int_alias.INT_10_A0     = mprf2trace_int_i[10];
+assign mprf_int_alias.INT_11_A1     = mprf2trace_int_i[11];
+assign mprf_int_alias.INT_12_A2     = mprf2trace_int_i[12];
+assign mprf_int_alias.INT_13_A3     = mprf2trace_int_i[13];
+assign mprf_int_alias.INT_14_A4     = mprf2trace_int_i[14];
+assign mprf_int_alias.INT_15_A5     = mprf2trace_int_i[15];
+`ifndef SCR1_RVE_EXT
+assign mprf_int_alias.INT_16_A6     = mprf2trace_int_i[16];
+assign mprf_int_alias.INT_17_A7     = mprf2trace_int_i[17];
+assign mprf_int_alias.INT_18_S2     = mprf2trace_int_i[18];
+assign mprf_int_alias.INT_19_S3     = mprf2trace_int_i[19];
+assign mprf_int_alias.INT_20_S4     = mprf2trace_int_i[20];
+assign mprf_int_alias.INT_21_S5     = mprf2trace_int_i[21];
+assign mprf_int_alias.INT_22_S6     = mprf2trace_int_i[22];
+assign mprf_int_alias.INT_23_S7     = mprf2trace_int_i[23];
+assign mprf_int_alias.INT_24_S8     = mprf2trace_int_i[24];
+assign mprf_int_alias.INT_25_S9     = mprf2trace_int_i[25];
+assign mprf_int_alias.INT_26_S10    = mprf2trace_int_i[26];
+assign mprf_int_alias.INT_27_S11    = mprf2trace_int_i[27];
+assign mprf_int_alias.INT_28_T3     = mprf2trace_int_i[28];
+assign mprf_int_alias.INT_29_T4     = mprf2trace_int_i[29];
+assign mprf_int_alias.INT_30_T5     = mprf2trace_int_i[30];
+assign mprf_int_alias.INT_31_T6     = mprf2trace_int_i[31];
+`endif // SCR1_RVE_EXT
+
+//-------------------------------------------------------------------------------
+// Legacy time counter
+//-------------------------------------------------------------------------------
+// The counter is left for compatibility with the current UVM environment
+
+int     time_cnt;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        time_cnt    <= 0;
+    end else begin
+        time_cnt    <= time_cnt + 1;
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Initial part pipeline tracelog
+//-------------------------------------------------------------------------------
+
+`ifdef SCR1_TRACE_LOG_EN
+// Files opening and writing initial header
+initial begin
+    $timeformat(-9, 0, " ns", 10);
+    #1 hart.hextoa(soc2pipe_fuse_mhartid_i);
+
+    trace_fhandler_core = $fopen({"tracelog_core_", hart, ".log"}, "w");
+
+    // Writing initial header
+    $fwrite(trace_fhandler_core,  "# RTL_ID %h\n", SCR1_CSR_MIMPID);
+    $fwrite(trace_fhandler_core,  "#\n");
+    // $fwrite(trace_fhandler_core,  "# R - return from trap:\n");
+    // $fwrite(trace_fhandler_core,  "#    1 - MRET\n");
+    // $fwrite(trace_fhandler_core,  "#    0 - no return\n");
+    $fwrite(trace_fhandler_core,  "# Events:\n");
+    $fwrite(trace_fhandler_core,  "#    N - no event\n");
+    $fwrite(trace_fhandler_core,  "#    E - exception\n");
+    $fwrite(trace_fhandler_core,  "#    I - interrupt\n");
+    $fwrite(trace_fhandler_core,  "#    W - wakeup\n");
+end
+
+// Core reset logging and header printing
+always @(posedge rst_n) begin
+    $fwrite(trace_fhandler_core, "# =====================================================================================\n");
+`ifndef VERILATOR
+    $fwrite(trace_fhandler_core, "# %14t : Core Reset\n", $time());
+`else
+    $fwrite(trace_fhandler_core, "# : Core Reset\n");
+`endif
+    $fwrite(trace_fhandler_core, "# =====================================================================================\n");
+    $fwrite(trace_fhandler_core,  "# Test: %s\n", test_name);
+    $fwrite(trace_fhandler_core,  "#           Time  ");
+    // $fwrite(trace_fhandler_core,  " R  ");
+    $fwrite(trace_fhandler_core,  " Ev ");
+    $fwrite(trace_fhandler_core,  " Curr_PC   ");
+    $fwrite(trace_fhandler_core,  " Instr     ");
+    $fwrite(trace_fhandler_core,  " Next_PC   ");
+    $fwrite(trace_fhandler_core,  " Reg       ");
+    $fwrite(trace_fhandler_core,  " Value     ");
+    $fwrite(trace_fhandler_core, "\n");
+    $fwrite(trace_fhandler_core, "# =====================================================================================\n");
+end
+
+//-------------------------------------------------------------------------------
+// Common trace part
+//-------------------------------------------------------------------------------
+
+assign trace_flag   = 1'b1;
+assign trace_update = (exu2trace_update_pc_en_i | mprf2trace_wr_en_i) & trace_flag;
+
+always_ff @(posedge clk) begin
+    if (~rst_n) begin
+        current_time    <= 0;
+        event_type      <= "N";
+
+        trace_pc        <= 'x;
+        trace_npc       <= 'x;
+        trace_instr     <= 'x;
+
+        trace_update_r  <= 1'b0;
+
+        mprf_up         <= '0;
+        mprf_addr       <= '0;
+        mprf_wdata      <= '0;
+    end else begin
+        trace_update_r <= trace_update;
+        if (trace_update) begin
+`ifdef VERILATOR
+            current_time  <= time_cnt;
+`else
+            current_time  <= $time();
+`endif
+            trace_pc      <= trace_npc;
+            trace_npc     <= exu2trace_update_pc_i;
+            trace_instr   <= ifu2trace_instr_i;
+
+            if (csr2trace_e_exc_i) begin
+                // Exception
+                event_type  <= "E";
+            end
+            else if (csr2trace_e_irq_i) begin
+                // IRQ
+                event_type  <= "I";
+            end
+            else if (pipe2trace_e_wake_i) begin
+                // Wake
+                event_type <= "W";
+            end
+            // if (csr2trace_e_mret_i) begin
+            //     // MRET
+            //     event_type  <= "R";
+            // end
+            else begin
+                // No event
+                event_type <= "N";
+            end
+        end
+
+        // Write log signals
+        mprf_up    <= mprf2trace_wr_en_i;
+        mprf_addr  <= mprf2trace_wr_en_i ? mprf2trace_wr_addr_i : 'x;
+        mprf_wdata <= mprf2trace_wr_en_i ? mprf2trace_wr_data_i : 'x;
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Core MPRF logging
+//-------------------------------------------------------------------------------
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+    end else begin
+        if (trace_update_r) begin
+
+            trace_write_common();
+
+            case (event_type)
+                "W"     : begin
+                    // Wakeup
+                    if (csr_trace1.mip & csr_trace1.mie) begin
+                        $fwrite(trace_fhandler_core, " mip        %08x\n", csr_trace1.mip );
+                        trace_write_common();
+                        $fwrite(trace_fhandler_core, " mie        %08x", csr_trace1.mie );
+                    end
+                end
+                "N"     : begin
+                    // Regular
+                    if (mprf_up && mprf_addr != 0) begin
+                        // $fwrite(trace_fhandler_core, " x%2d      %08x", mprf_addr, mprf_wdata);
+                        trace_write_int_walias();
+                        $fwrite(trace_fhandler_core, " %08x", mprf_wdata);
+                    end else begin
+                        $fwrite(trace_fhandler_core, " ---        --------");
+                    end
+                end
+                "R"     : begin
+                    // MRET
+                    $fwrite(trace_fhandler_core, " mstatus    %08x", csr_trace1.mstatus);
+                end
+                "E", "I": begin
+                    // IRQ/Exception
+                    $fwrite(trace_fhandler_core, " mstatus    %08x\n", csr_trace1.mstatus);
+                    trace_write_common();
+                    $fwrite(trace_fhandler_core, " mepc       %08x\n", csr_trace1.mepc);
+                    trace_write_common();
+                    $fwrite(trace_fhandler_core, " mcause     %08x\n", csr_trace1.mcause);
+                    trace_write_common();
+                    $fwrite(trace_fhandler_core, " mtval      %08x",   csr_trace1.mtval);
+                end
+                default : begin
+                    $fwrite(trace_fhandler_core,  "\n");
+                end
+            endcase
+            $fwrite(trace_fhandler_core,  "\n");
+        end
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Core CSR logging
+//-------------------------------------------------------------------------------
+
+always_comb begin
+    csr_trace1.mtvec        = {csr2trace_mtvec_base_i, 4'd0, 2'(csr2trace_mtvec_mode_i)};
+    csr_trace1.mepc         =
+`ifdef SCR1_RVC_EXT
+                              {csr2trace_mepc_i, 1'b0};
+`else // SCR1_RVC_EXT
+                              {csr2trace_mepc_i, 2'b00};
+`endif // SCR1_RVC_EXT
+    csr_trace1.mcause       = {csr2trace_mcause_irq_i, type_scr1_csr_mcause_ec_v'(csr2trace_mcause_ec_i)};
+    csr_trace1.mtval        = csr2trace_mtval_i;
+
+    csr_trace1.mstatus      = '0;
+    csr_trace1.mie          = '0;
+    csr_trace1.mip          = '0;
+
+    csr_trace1.mstatus[SCR1_CSR_MSTATUS_MIE_OFFSET]     = csr2trace_mstatus_mie_i;
+    csr_trace1.mstatus[SCR1_CSR_MSTATUS_MPIE_OFFSET]    = csr2trace_mstatus_mpie_i;
+    csr_trace1.mstatus[SCR1_CSR_MSTATUS_MPP_OFFSET+1:SCR1_CSR_MSTATUS_MPP_OFFSET]   = SCR1_CSR_MSTATUS_MPP;
+    csr_trace1.mie[SCR1_CSR_MIE_MSIE_OFFSET]            = csr2trace_mie_msie_i;
+    csr_trace1.mie[SCR1_CSR_MIE_MTIE_OFFSET]            = csr2trace_mie_mtie_i;
+    csr_trace1.mie[SCR1_CSR_MIE_MEIE_OFFSET]            = csr2trace_mie_meie_i;
+    csr_trace1.mip[SCR1_CSR_MIE_MSIE_OFFSET]            = csr2trace_mip_msip_i;
+    csr_trace1.mip[SCR1_CSR_MIE_MTIE_OFFSET]            = csr2trace_mip_mtip_i;
+    csr_trace1.mip[SCR1_CSR_MIE_MEIE_OFFSET]            = csr2trace_mip_meip_i;
+end
+
+`endif // SCR1_TRACE_LOG_EN
+
+endmodule : scr1_tracelog
+
+`endif // SCR1_TRGT_SIMULATION
diff --git a/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_cg.sv b/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_cg.sv
new file mode 100644
index 0000000..b0f6154
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_cg.sv
@@ -0,0 +1,32 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_cg.sv>
+/// @brief      SCR1 clock gate primitive
+///
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_CLKCTRL_EN
+module scr1_cg (
+    input   logic   clk,
+    input   logic   clk_en,
+    input   logic   test_mode,
+    output  logic   clk_out
+);
+
+// The code below is a clock gate model for simulation.
+// For synthesis, it should be replaced by implementation-specific
+// clock gate code.
+
+logic latch_en;
+
+always_latch begin
+    if (~clk) begin
+        latch_en <= test_mode | clk_en;
+    end
+end
+
+assign clk_out  = latch_en & clk;
+
+endmodule : scr1_cg
+
+`endif // SCR1_CLKCTRL_EN
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_reset_cells.sv b/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_reset_cells.sv
new file mode 100644
index 0000000..1af347c
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/primitives/scr1_reset_cells.sv
@@ -0,0 +1,231 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_sync_rstn.sv>
+/// @brief      Cells for reset handling
+///
+
+//--------------------------------------------------------------------
+// Reset Buffer Cell
+//--------------------------------------------------------------------
+module scr1_reset_buf_cell (
+    input   logic           rst_n,
+    input   logic           clk,
+    input   logic           test_mode,
+    input   logic           test_rst_n,
+    input   logic           reset_n_in,
+    output  logic           reset_n_out,
+    output  logic           reset_n_status
+);
+
+logic       reset_n_ff;
+logic       reset_n_status_ff;
+logic       rst_n_mux;
+
+assign rst_n_mux = (test_mode == 1'b1) ? test_rst_n : rst_n;
+
+always_ff @(negedge rst_n_mux, posedge clk) begin
+    if (~rst_n_mux) begin
+        reset_n_ff <= 1'b0;
+    end else begin
+        reset_n_ff <= reset_n_in;
+    end
+end
+
+assign reset_n_out = (test_mode == 1'b1) ? test_rst_n : reset_n_ff;
+
+always_ff @(negedge rst_n_mux, posedge clk) begin
+    if (~rst_n_mux) begin
+        reset_n_status_ff <= 1'b0;
+    end else begin
+        reset_n_status_ff <= reset_n_in;
+    end
+end
+assign reset_n_status = reset_n_status_ff;
+
+endmodule : scr1_reset_buf_cell
+
+//--------------------------------------------------------------------
+// Reset CDC Synchronization Cell
+//--------------------------------------------------------------------
+module scr1_reset_sync_cell #(
+    parameter int unsigned STAGES_AMOUNT = 2
+) (
+    input   logic           rst_n,
+    input   logic           clk,
+    input   logic           test_rst_n,
+    input   logic           test_mode,
+    input   logic           rst_n_in,
+    output  logic           rst_n_out
+);
+
+logic [STAGES_AMOUNT-1:0]   rst_n_dff;
+logic                       local_rst_n_in;
+
+assign local_rst_n_in = (test_mode == 1'b1) ? test_rst_n : rst_n;
+
+generate
+
+if (STAGES_AMOUNT == 1)
+
+begin : gen_reset_sync_cell_single
+    always_ff @(negedge local_rst_n_in, posedge clk) begin
+        if (~local_rst_n_in) begin
+            rst_n_dff <= 1'b0;
+        end else begin
+            rst_n_dff <= rst_n_in;
+        end
+    end
+end : gen_reset_sync_cell_single
+
+else // STAGES_AMOUNT > 1
+
+begin : gen_reset_sync_cell_multi
+    always_ff @(negedge local_rst_n_in, posedge clk)
+    begin
+        if (~local_rst_n_in) begin
+            rst_n_dff <= '0;
+        end else begin
+            rst_n_dff <= {rst_n_dff[STAGES_AMOUNT-2:0], rst_n_in};
+        end
+    end
+end : gen_reset_sync_cell_multi
+
+endgenerate
+
+assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : rst_n_dff[STAGES_AMOUNT-1];
+
+endmodule : scr1_reset_sync_cell
+
+//--------------------------------------------------------------------
+// Data CDC/RDC Synchronization Cell
+//--------------------------------------------------------------------
+module scr1_data_sync_cell #(
+    parameter int unsigned  STAGES_AMOUNT = 1
+) (
+    input   logic           rst_n,
+    input   logic           clk,
+    input   logic           data_in,
+    output  logic           data_out
+);
+
+logic [STAGES_AMOUNT-1:0] data_dff;
+
+generate
+
+if (STAGES_AMOUNT == 1)
+
+begin : gen_data_sync_cell_single
+    always_ff @(negedge rst_n, posedge clk)
+    begin
+        if (~rst_n) begin
+            data_dff <= 1'b0;
+        end else begin
+            data_dff <= data_in;
+        end
+    end
+end : gen_data_sync_cell_single
+
+else // STAGES_AMOUNT > 1
+
+begin : gen_data_sync_cell_multi
+    always_ff @(negedge rst_n, posedge clk)
+    begin
+        if (~rst_n) begin
+            data_dff <= '0;
+        end else begin
+            data_dff <= {data_dff[STAGES_AMOUNT-2:0], data_in};
+        end
+    end
+end : gen_data_sync_cell_multi
+
+endgenerate
+
+assign data_out = data_dff[STAGES_AMOUNT-1];
+
+endmodule : scr1_data_sync_cell
+
+//--------------------------------------------------------------------
+// Reset / RDC Qualifyer Adapter Cell
+//   (Reset Generation Cell w/ RDC Qualifyer Adaptation circuitry)
+//--------------------------------------------------------------------
+// Total stages amount =
+//    1 Front Sync stage \
+//  + 1 (delay introduced by the reset output buffer register)
+//--------------------------------------------------------------------
+module scr1_reset_qlfy_adapter_cell_sync (
+    input   logic           rst_n,
+    input   logic           clk,
+    input   logic           test_rst_n,
+    input   logic           test_mode,
+    input   logic           reset_n_in_sync,
+    output  logic           reset_n_out_qlfy,
+    output  logic           reset_n_out,
+    output  logic           reset_n_status
+);
+
+logic rst_n_mux;
+logic reset_n_front_ff;
+
+// Front sync stage
+assign rst_n_mux = (test_mode == 1'b1) ? test_rst_n : rst_n;
+
+always_ff @(negedge rst_n_mux, posedge clk) begin
+    if (~rst_n_mux) begin
+        reset_n_front_ff    <= 1'b0;
+    end else begin
+        reset_n_front_ff    <= reset_n_in_sync;
+    end
+end
+
+//   Sync reset output for all reset qualifier chains targeting this reset domain
+// (for reset-domain-crossings with the given reset domain as a destination).
+assign reset_n_out_qlfy = reset_n_front_ff;
+
+// Reset output buffer
+scr1_reset_buf_cell
+i_reset_output_buf (
+    .rst_n              (rst_n),
+    .clk                (clk),
+    .test_mode          (test_mode),
+    .test_rst_n         (test_rst_n),
+    .reset_n_in         (reset_n_front_ff),
+    .reset_n_out        (reset_n_out),
+    .reset_n_status     (reset_n_status)
+);
+
+endmodule : scr1_reset_qlfy_adapter_cell_sync
+
+module scr1_reset_and2_cell (
+    input   logic [1:0]     rst_n_in,
+    input   logic           test_rst_n,
+    input   logic           test_mode,
+    output  logic           rst_n_out
+);
+
+assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : (&rst_n_in);
+
+endmodule : scr1_reset_and2_cell
+
+
+module scr1_reset_and3_cell (
+    input   logic [2:0]     rst_n_in,
+    input   logic           test_rst_n,
+    input   logic           test_mode,
+    output  logic           rst_n_out
+);
+
+assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : (&rst_n_in);
+
+endmodule : scr1_reset_and3_cell
+
+
+module scr1_reset_mux2_cell (
+    input   logic [1:0]     rst_n_in,
+    input   logic           select,
+    input   logic           test_rst_n,
+    input   logic           test_mode,
+    output  logic           rst_n_out
+);
+
+assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : rst_n_in[select];
+
+endmodule : scr1_reset_mux2_cell
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_clk_ctrl.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_clk_ctrl.sv
new file mode 100644
index 0000000..09b72f4
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_clk_ctrl.sv
@@ -0,0 +1,55 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_clk_ctrl.sv>
+/// @brief      SCR1 clock control
+///
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_CLKCTRL_EN
+module scr1_clk_ctrl (
+    input   logic   clk,                            // Clock control module clock
+    input   logic   rst_n,                          // Clock control module reset
+    input   logic   test_mode,                      // DFT Test Mode
+    input   logic   test_rst_n,                     // DFT Test reset
+
+    input   logic   pipe2clkctl_sleep_req_i,        // CLK disable request from pipe
+    input   logic   pipe2clkctl_wake_req_i,         // CLK enable request from pipe
+
+    output  logic   clkctl2pipe_clk_alw_on_o,       // Not gated pipe CLK
+    output  logic   clkctl2pipe_clk_o,              // Gated pipe
+    output  logic   clkctl2pipe_clk_en_o,           // CLK enabled flag
+    output  logic   clkctl2pipe_clk_dbgc_o          // CLK for pipe debug subsystem
+);
+
+logic ctrl_rst_n;
+
+assign clkctl2pipe_clk_alw_on_o = clk;
+assign clkctl2pipe_clk_dbgc_o   = clk;
+assign ctrl_rst_n   = (test_mode) ? test_rst_n : rst_n;
+
+always_ff @(posedge clk, negedge ctrl_rst_n) begin
+    if (~ctrl_rst_n) begin
+        clkctl2pipe_clk_en_o <= 1'b1;
+    end else begin
+        if (clkctl2pipe_clk_en_o) begin
+            if (pipe2clkctl_sleep_req_i & ~pipe2clkctl_wake_req_i) begin
+                clkctl2pipe_clk_en_o <= 1'b0;
+            end
+        end else begin // ~clkctl2pipe_clk_en_o
+            if (pipe2clkctl_wake_req_i) begin
+                clkctl2pipe_clk_en_o <= 1'b1;
+            end
+        end // pipeline
+    end
+end
+
+scr1_cg i_scr1_cg_pipe (
+    .clk        (clk                 ),
+    .clk_en     (clkctl2pipe_clk_en_o),
+    .test_mode  (test_mode           ),
+    .clk_out    (clkctl2pipe_clk_o   )
+);
+
+endmodule : scr1_clk_ctrl
+
+`endif // SCR1_CLKCTRL_EN
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_core_top.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_core_top.sv
new file mode 100644
index 0000000..582e4bb
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_core_top.sv
@@ -0,0 +1,519 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_core_top.sv>
+/// @brief      SCR1 core top
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_memif.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_tapc.svh"
+`include "scr1_dm.svh"
+`include "scr1_hdu.svh"
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_IPIC_EN
+`include "scr1_ipic.svh"
+`endif // SCR1_IPIC_EN
+
+module scr1_core_top (
+    // Common
+    input   logic                                   pwrup_rst_n,                // Power-Up reset
+    input   logic                                   rst_n,                      // Regular reset
+    input   logic                                   cpu_rst_n,                  // CPU reset
+    input   logic                                   test_mode,                  // DFT Test Mode
+    input   logic                                   test_rst_n,                 // DFT Test Reset
+    input   logic                                   clk,                        // Core clock
+    output  logic                                   core_rst_n_o,               // Core reset
+    output  logic                                   core_rdc_qlfy_o,            // Core RDC qualifier
+`ifdef SCR1_DBG_EN
+    output  logic                                   sys_rst_n_o,                // System reset
+    output  logic                                   sys_rdc_qlfy_o,             // System RDC qualifier
+`endif // SCR1_DBG_EN
+
+    // Fuses
+    input   logic [`SCR1_XLEN-1:0]                  core_fuse_mhartid_i,        // Fuse MHARTID value
+`ifdef SCR1_DBG_EN
+    input   logic [31:0]                            tapc_fuse_idcode_i,         // Fuse IDCODE value
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    input   logic [SCR1_IRQ_LINES_NUM-1:0]          core_irq_lines_i,           // External interrupt request lines
+`else
+    input   logic                                   core_irq_ext_i,             // External interrupt request
+`endif // SCR1_IPIC_EN
+    input   logic                                   core_irq_soft_i,            // Software generated interrupt request
+    input   logic                                   core_irq_mtimer_i,          // Machine timer interrupt request
+
+    // Memory-mapped external timer
+    input   logic [63:0]                            core_mtimer_val_i,          // Machine timer value
+
+`ifdef SCR1_DBG_EN
+    // Debug Interface
+    input   logic                                   tapc_trst_n,                // Test Reset (TRSTn)
+    input   logic                                   tapc_tck,                   // Test Clock (TCK)
+    input   logic                                   tapc_tms,                   // Test Mode Select (TMS)
+    input   logic                                   tapc_tdi,                   // Test Data Input (TDI)
+    output  logic                                   tapc_tdo,                   // Test Data Output (TDO)
+    output  logic                                   tapc_tdo_en,                // TDO Enable, signal for TDO buffer control
+`endif // SCR1_DBG_EN
+
+    // Instruction Memory Interface
+    input   logic                                   imem2core_req_ack_i,        // IMEM request acknowledge
+    output  logic                                   core2imem_req_o,            // IMEM request
+    output  type_scr1_mem_cmd_e                     core2imem_cmd_o,            // IMEM command
+    output  logic [`SCR1_IMEM_AWIDTH-1:0]           core2imem_addr_o,           // IMEM address
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]           imem2core_rdata_i,          // IMEM read data
+    input   type_scr1_mem_resp_e                    imem2core_resp_i,           // IMEM response
+
+    // Data Memory Interface
+    input   logic                                   dmem2core_req_ack_i,        // DMEM request acknowledge
+    output  logic                                   core2dmem_req_o,            // DMEM request
+    output  type_scr1_mem_cmd_e                     core2dmem_cmd_o,            // DMEM command
+    output  type_scr1_mem_width_e                   core2dmem_width_o,          // DMEM data width
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]           core2dmem_addr_o,           // DMEM address
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]           core2dmem_wdata_o,          // DMEM write data
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]           dmem2core_rdata_i,          // DMEM read data
+    input   type_scr1_mem_resp_e                    dmem2core_resp_i            // DMEM response
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters
+//-------------------------------------------------------------------------------
+localparam int unsigned SCR1_CORE_TOP_RST_SYNC_STAGES_NUM               = 2;
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+
+// Reset Logic
+`ifdef SCR1_DBG_EN
+`else // SCR1_DBG_EN
+logic                                           core_rst_n_in_sync;
+logic                                           core_rst_n_qlfy;
+logic                                           core_rst_n_status;
+`endif // SCR1_DBG_EN
+logic                                           core_rst_n;
+logic                                           core_rst_n_status_sync;
+logic                                           core_rst_status;
+logic                                           core2hdu_rdc_qlfy;
+logic                                           core2dm_rdc_qlfy;
+logic                                           pwrup_rst_n_sync;
+logic                                           rst_n_sync;
+logic                                           cpu_rst_n_sync;
+
+`ifdef SCR1_DBG_EN
+// TAPC-DM Interface
+logic                                           tapc_dmi_ch_sel;
+logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]            tapc_dmi_ch_id;
+logic                                           tapc_dmi_ch_capture;
+logic                                           tapc_dmi_ch_shift;
+logic                                           tapc_dmi_ch_update;
+logic                                           tapc_dmi_ch_tdi;
+logic                                           tapc_dmi_ch_tdo;
+//
+logic                                           tapc_dmi_ch_sel_tapout;
+logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]            tapc_dmi_ch_id_tapout;
+logic                                           tapc_dmi_ch_capture_tapout;
+logic                                           tapc_dmi_ch_shift_tapout;
+logic                                           tapc_dmi_ch_update_tapout;
+logic                                           tapc_dmi_ch_tdi_tapout;
+logic                                           tapc_dmi_ch_tdo_tapin;
+//
+logic                                           dmi_req;
+logic                                           dmi_wr;
+logic [SCR1_DBG_DMI_ADDR_WIDTH-1:0]             dmi_addr;
+logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]             dmi_wdata;
+logic                                           dmi_resp;
+logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]             dmi_rdata;
+// TAPC-SCU Interface
+logic                                           tapc_scu_ch_sel;
+logic                                           tapc_scu_ch_sel_tapout;
+logic                                           tapc_scu_ch_tdo;
+logic                                           tapc_ch_tdo;
+// SCU nets
+logic                                           sys_rst_n;
+logic                                           sys_rst_status;
+logic                                           hdu_rst_n;
+logic                                           hdu2dm_rdc_qlfy;
+logic                                           ndm_rst_n;
+logic                                           dm_rst_n;
+logic                                           hart_rst_n;
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_DBG_EN
+// DM-Pipeline Interface
+// HART Run Control i/f
+logic                                           dm_active;
+logic                                           dm_cmd_req;
+type_scr1_hdu_dbgstates_e                       dm_cmd;
+logic                                           dm_cmd_resp;
+logic                                           dm_cmd_resp_qlfy;
+logic                                           dm_cmd_rcode;
+logic                                           dm_hart_event;
+logic                                           dm_hart_event_qlfy;
+type_scr1_hdu_hartstatus_s                      dm_hart_status;
+type_scr1_hdu_hartstatus_s                      dm_hart_status_qlfy;
+// Program Buffer - HART instruction execution i/f
+logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]            dm_pbuf_addr;
+logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]            dm_pbuf_addr_qlfy;
+logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]           dm_pbuf_instr;
+// HART Abstract Data regs i/f
+logic                                           dm_dreg_req;
+logic                                           dm_dreg_req_qlfy;
+logic                                           dm_dreg_wr;
+logic [SCR1_HDU_DATA_REG_WIDTH-1:0]             dm_dreg_wdata;
+logic                                           dm_dreg_resp;
+logic                                           dm_dreg_fail;
+logic [SCR1_HDU_DATA_REG_WIDTH-1:0]             dm_dreg_rdata;
+
+logic [`SCR1_XLEN-1 : 0]                        dm_pc_sample;
+logic [`SCR1_XLEN-1 : 0]                        dm_pc_sample_qlfy;
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_CLKCTRL_EN
+// Global clock gating logic
+logic                                           sleep_pipe;
+logic                                           wake_pipe;
+logic                                           clk_pipe;
+logic                                           clk_pipe_en;
+logic                                           clk_dbgc;
+logic                                           clk_alw_on;
+`endif // SCR1_CLKCTRL_EN
+
+
+//-------------------------------------------------------------------------------
+// Reset Logic
+//-------------------------------------------------------------------------------
+`ifdef SCR1_DBG_EN
+scr1_scu    i_scu (
+    // Global signals
+    .pwrup_rst_n                (pwrup_rst_n        ),
+    .rst_n                      (rst_n              ),
+    .cpu_rst_n                  (cpu_rst_n          ),
+    .test_mode                  (test_mode          ),
+    .test_rst_n                 (test_rst_n         ),
+    .clk                        (clk                ),
+
+    // TAPC scan-chains
+    .tapcsync2scu_ch_sel_i      (tapc_scu_ch_sel    ),
+    .tapcsync2scu_ch_id_i       ('0                 ),
+    .tapcsync2scu_ch_capture_i  (tapc_dmi_ch_capture),
+    .tapcsync2scu_ch_shift_i    (tapc_dmi_ch_shift  ),
+    .tapcsync2scu_ch_update_i   (tapc_dmi_ch_update ),
+    .tapcsync2scu_ch_tdi_i      (tapc_dmi_ch_tdi    ),
+    .scu2tapcsync_ch_tdo_o      (tapc_scu_ch_tdo    ),
+
+    // Input sync resets:
+    .ndm_rst_n_i                (ndm_rst_n          ),
+    .hart_rst_n_i               (hart_rst_n         ),
+
+    // Generated resets
+    .sys_rst_n_o                (sys_rst_n          ),
+    .core_rst_n_o               (core_rst_n         ),
+    .dm_rst_n_o                 (dm_rst_n           ),
+    .hdu_rst_n_o                (hdu_rst_n          ),
+
+    // Resets statuses
+    .sys_rst_status_o           (sys_rst_status     ),
+    .core_rst_status_o          (core_rst_status    ),
+
+    // Reset Domain Crossing (RDC) qualifiers
+    .sys_rdc_qlfy_o             (sys_rdc_qlfy_o     ),
+    .core_rdc_qlfy_o            (core_rdc_qlfy_o    ),
+    .core2hdu_rdc_qlfy_o        (core2hdu_rdc_qlfy  ),
+    .core2dm_rdc_qlfy_o         (core2dm_rdc_qlfy   ),
+    .hdu2dm_rdc_qlfy_o          (hdu2dm_rdc_qlfy    )
+);
+
+assign sys_rst_n_o      = sys_rst_n;
+
+// Reset inputs are assumed synchronous
+assign pwrup_rst_n_sync = pwrup_rst_n;
+
+`else // SCR1_DBG_EN
+
+// Reset inputs are assumed synchronous
+assign pwrup_rst_n_sync   = pwrup_rst_n;
+assign rst_n_sync         = rst_n;
+assign cpu_rst_n_sync     = cpu_rst_n;
+assign core_rst_n_in_sync = rst_n_sync & cpu_rst_n_sync;
+
+// Core Reset: core_rst_n
+scr1_reset_qlfy_adapter_cell_sync i_core_rstn_qlfy_adapter_cell_sync (
+    .rst_n              (pwrup_rst_n_sync  ),
+    .clk                (clk               ),
+    .test_rst_n         (test_rst_n        ),
+    .test_mode          (test_mode         ),
+    .reset_n_in_sync    (core_rst_n_in_sync),
+    .reset_n_out_qlfy   (core_rst_n_qlfy   ),
+    .reset_n_out        (core_rst_n        ),
+    .reset_n_status     (core_rst_n_status )
+);
+
+scr1_data_sync_cell #(
+    .STAGES_AMOUNT      (SCR1_CORE_TOP_RST_SYNC_STAGES_NUM)
+) i_core_rstn_status_sync (
+    .rst_n               (pwrup_rst_n_sync      ),
+    .clk                 (clk                   ),
+    .data_in             (core_rst_n_status     ),
+    .data_out            (core_rst_n_status_sync)
+);
+
+assign core_rst_status      = ~core_rst_n_status_sync;
+assign core_rdc_qlfy_o      = core_rst_n_qlfy;
+
+`endif // SCR1_DBG_EN
+assign core_rst_n_o         = core_rst_n;
+
+//-------------------------------------------------------------------------------
+// SCR1 pipeline
+//-------------------------------------------------------------------------------
+scr1_pipe_top i_pipe_top (
+    // Control
+    .pipe_rst_n                     (core_rst_n             ),
+`ifdef SCR1_DBG_EN
+    .pipe2hdu_rdc_qlfy_i            (core2hdu_rdc_qlfy      ),
+    .dbg_rst_n                      (hdu_rst_n              ),
+`endif // SCR1_DBG_EN
+`ifndef SCR1_CLKCTRL_EN
+    .clk                            (clk                    ),
+`else // SCR1_CLKCTRL_EN
+    .clk                            (clk_pipe               ),
+    .pipe2clkctl_sleep_req_o        (sleep_pipe             ),
+    .pipe2clkctl_wake_req_o         (wake_pipe              ),
+    .clkctl2pipe_clk_alw_on_i       (clk_alw_on             ),
+    .clkctl2pipe_clk_dbgc_i         (clk_dbgc               ),
+    .clkctl2pipe_clk_en_i           (clk_pipe_en            ),
+`endif // SCR1_CLKCTRL_EN
+
+    // Instruction memory interface
+    .pipe2imem_req_o                (core2imem_req_o        ),
+    .pipe2imem_cmd_o                (core2imem_cmd_o        ),
+    .pipe2imem_addr_o               (core2imem_addr_o       ),
+    .imem2pipe_req_ack_i            (imem2core_req_ack_i    ),
+    .imem2pipe_rdata_i              (imem2core_rdata_i      ),
+    .imem2pipe_resp_i               (imem2core_resp_i       ),
+
+    // Data memory interface
+    .pipe2dmem_req_o                (core2dmem_req_o        ),
+    .pipe2dmem_cmd_o                (core2dmem_cmd_o        ),
+    .pipe2dmem_width_o              (core2dmem_width_o      ),
+    .pipe2dmem_addr_o               (core2dmem_addr_o       ),
+    .pipe2dmem_wdata_o              (core2dmem_wdata_o      ),
+    .dmem2pipe_req_ack_i            (dmem2core_req_ack_i    ),
+    .dmem2pipe_rdata_i              (dmem2core_rdata_i      ),
+    .dmem2pipe_resp_i               (dmem2core_resp_i       ),
+
+`ifdef SCR1_DBG_EN
+    // Debug interface:
+    .dbg_en                         (1'b1                   ),
+    // Debug interface:
+    // DM <-> Pipeline: HART Run Control i/f
+    .dm2pipe_active_i               (dm_active              ),
+    .dm2pipe_cmd_req_i              (dm_cmd_req             ),
+    .dm2pipe_cmd_i                  (dm_cmd                 ),
+    .pipe2dm_cmd_resp_o             (dm_cmd_resp            ),
+    .pipe2dm_cmd_rcode_o            (dm_cmd_rcode           ),
+    .pipe2dm_hart_event_o           (dm_hart_event          ),
+    .pipe2dm_hart_status_o          (dm_hart_status         ),
+
+    // DM <-> Pipeline: Program Buffer - HART instruction execution i/f
+    .pipe2dm_pbuf_addr_o            (dm_pbuf_addr           ),
+    .dm2pipe_pbuf_instr_i           (dm_pbuf_instr          ),
+
+    // DM <-> Pipeline: HART Abstract Data regs i/f
+    .pipe2dm_dreg_req_o             (dm_dreg_req            ),
+    .pipe2dm_dreg_wr_o              (dm_dreg_wr             ),
+    .pipe2dm_dreg_wdata_o           (dm_dreg_wdata          ),
+    .dm2pipe_dreg_resp_i            (dm_dreg_resp           ),
+    .dm2pipe_dreg_fail_i            (dm_dreg_fail           ),
+    .dm2pipe_dreg_rdata_i           (dm_dreg_rdata          ),
+
+    // DM <-> Pipeline: PC i/f
+    .pipe2dm_pc_sample_o            (dm_pc_sample           ),
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    .soc2pipe_irq_lines_i           (core_irq_lines_i       ),
+`else // SCR1_IPIC_EN
+    .soc2pipe_irq_ext_i             (core_irq_ext_i         ),
+`endif // SCR1_IPIC_EN
+    .soc2pipe_irq_soft_i            (core_irq_soft_i        ),
+    .soc2pipe_irq_mtimer_i          (core_irq_mtimer_i      ),
+
+    // Memory-mapped external timer
+    .soc2pipe_mtimer_val_i          (core_mtimer_val_i      ),
+
+    // Fuse
+    .soc2pipe_fuse_mhartid_i        (core_fuse_mhartid_i    )
+);
+
+
+`ifdef SCR1_DBG_EN
+//-------------------------------------------------------------------------------
+// TAP Controller (TAPC)
+//-------------------------------------------------------------------------------
+scr1_tapc i_tapc (
+    // JTAG signals
+    .tapc_trst_n                    (tapc_trst_n               ),
+    .tapc_tck                       (tapc_tck                  ),
+    .tapc_tms                       (tapc_tms                  ),
+    .tapc_tdi                       (tapc_tdi                  ),
+    .tapc_tdo                       (tapc_tdo                  ),
+    .tapc_tdo_en                    (tapc_tdo_en               ),
+
+    // Fuses
+    .soc2tapc_fuse_idcode_i         (tapc_fuse_idcode_i        ),
+
+    // DMI/SCU scan-chains
+    .tapc2tapcsync_scu_ch_sel_o     (tapc_scu_ch_sel_tapout    ),
+    .tapc2tapcsync_dmi_ch_sel_o     (tapc_dmi_ch_sel_tapout    ),
+    .tapc2tapcsync_ch_id_o          (tapc_dmi_ch_id_tapout     ),
+    .tapc2tapcsync_ch_capture_o     (tapc_dmi_ch_capture_tapout),
+    .tapc2tapcsync_ch_shift_o       (tapc_dmi_ch_shift_tapout  ),
+    .tapc2tapcsync_ch_update_o      (tapc_dmi_ch_update_tapout ),
+    .tapc2tapcsync_ch_tdi_o         (tapc_dmi_ch_tdi_tapout    ),
+    .tapcsync2tapc_ch_tdo_i         (tapc_dmi_ch_tdo_tapin     )
+);
+
+scr1_tapc_synchronizer i_tapc_synchronizer (
+    // System common signals
+    .pwrup_rst_n                    (pwrup_rst_n_sync          ),
+    .dm_rst_n                       (dm_rst_n                  ),
+    .clk                            (clk                       ),
+
+    // JTAG common signals
+    .tapc_trst_n                    (tapc_trst_n               ),
+    .tapc_tck                       (tapc_tck                  ),
+
+    // DMI/SCU scan-chains
+    .tapc2tapcsync_scu_ch_sel_i     (tapc_scu_ch_sel_tapout    ),
+    .tapcsync2scu_ch_sel_o          (tapc_scu_ch_sel           ),
+    .tapc2tapcsync_dmi_ch_sel_i     (tapc_dmi_ch_sel_tapout    ),
+    .tapcsync2dmi_ch_sel_o          (tapc_dmi_ch_sel           ),
+
+    .tapc2tapcsync_ch_id_i          (tapc_dmi_ch_id_tapout     ),
+    .tapcsync2core_ch_id_o          (tapc_dmi_ch_id            ),
+    .tapc2tapcsync_ch_capture_i     (tapc_dmi_ch_capture_tapout),
+    .tapcsync2core_ch_capture_o     (tapc_dmi_ch_capture       ),
+    .tapc2tapcsync_ch_shift_i       (tapc_dmi_ch_shift_tapout  ),
+    .tapcsync2core_ch_shift_o       (tapc_dmi_ch_shift         ),
+    .tapc2tapcsync_ch_update_i      (tapc_dmi_ch_update_tapout ),
+    .tapcsync2core_ch_update_o      (tapc_dmi_ch_update        ),
+    .tapc2tapcsync_ch_tdi_i         (tapc_dmi_ch_tdi_tapout    ),
+    .tapcsync2core_ch_tdi_o         (tapc_dmi_ch_tdi           ),
+    .tapc2tapcsync_ch_tdo_i         (tapc_dmi_ch_tdo_tapin     ),
+    .tapcsync2core_ch_tdo_o         (tapc_ch_tdo               )
+);
+assign tapc_ch_tdo = (tapc_scu_ch_tdo & tapc_scu_ch_sel)
+                   | (tapc_dmi_ch_tdo & tapc_dmi_ch_sel);
+
+scr1_dmi i_dmi (
+    .rst_n                      (dm_rst_n           ),
+    .clk                        (clk                ),
+
+    // TAP scan-chains
+    .tapcsync2dmi_ch_sel_i      (tapc_dmi_ch_sel    ),
+    .tapcsync2dmi_ch_id_i       (tapc_dmi_ch_id     ),
+    .tapcsync2dmi_ch_capture_i  (tapc_dmi_ch_capture),
+    .tapcsync2dmi_ch_shift_i    (tapc_dmi_ch_shift  ),
+    .tapcsync2dmi_ch_update_i   (tapc_dmi_ch_update ),
+    .tapcsync2dmi_ch_tdi_i      (tapc_dmi_ch_tdi    ),
+    .dmi2tapcsync_ch_tdo_o      (tapc_dmi_ch_tdo    ),
+
+    // DMI
+    .dm2dmi_resp_i              (dmi_resp           ),
+    .dm2dmi_rdata_i             (dmi_rdata          ),
+    .dmi2dm_req_o               (dmi_req            ),
+    .dmi2dm_wr_o                (dmi_wr             ),
+    .dmi2dm_addr_o              (dmi_addr           ),
+    .dmi2dm_wdata_o             (dmi_wdata          )
+);
+
+`endif // SCR1_DBG_EN
+
+
+`ifdef SCR1_DBG_EN
+
+//-------------------------------------------------------------------------------
+// Debug Module (DM)
+//-------------------------------------------------------------------------------
+assign dm_cmd_resp_qlfy    = dm_cmd_resp   & {$bits(dm_cmd_resp){hdu2dm_rdc_qlfy}};
+assign dm_hart_event_qlfy  = dm_hart_event & {$bits(dm_hart_event){hdu2dm_rdc_qlfy}};
+assign dm_hart_status_qlfy.dbg_state = hdu2dm_rdc_qlfy ? dm_hart_status.dbg_state
+                                                       : SCR1_HDU_DBGSTATE_RESET;
+assign dm_hart_status_qlfy.except    = dm_hart_status.except;
+assign dm_hart_status_qlfy.ebreak    = dm_hart_status.ebreak;
+assign dm_pbuf_addr_qlfy   = dm_pbuf_addr  & {$bits(dm_pbuf_addr){hdu2dm_rdc_qlfy}};
+assign dm_dreg_req_qlfy    = dm_dreg_req   & {$bits(dm_dreg_req){hdu2dm_rdc_qlfy}};
+assign dm_pc_sample_qlfy   = dm_pc_sample  & {$bits(dm_pc_sample){core2dm_rdc_qlfy}};
+
+scr1_dm i_dm (
+    // Common signals
+    .rst_n                      (dm_rst_n               ),
+    .clk                        (clk                    ),
+
+    // DM internal interface
+    .dmi2dm_req_i               (dmi_req                ),
+    .dmi2dm_wr_i                (dmi_wr                 ),
+    .dmi2dm_addr_i              (dmi_addr               ),
+    .dmi2dm_wdata_i             (dmi_wdata              ),
+    .dm2dmi_resp_o              (dmi_resp               ),
+    .dm2dmi_rdata_o             (dmi_rdata              ),
+
+    // DM <-> Pipeline: HART Run Control i/f
+    .ndm_rst_n_o                (ndm_rst_n              ),
+    .hart_rst_n_o               (hart_rst_n             ),
+    .dm2pipe_active_o           (dm_active              ),
+    .dm2pipe_cmd_req_o          (dm_cmd_req             ),
+    .dm2pipe_cmd_o              (dm_cmd                 ),
+    .pipe2dm_cmd_resp_i         (dm_cmd_resp_qlfy       ),
+    .pipe2dm_cmd_rcode_i        (dm_cmd_rcode           ),
+    .pipe2dm_hart_event_i       (dm_hart_event_qlfy     ),
+    .pipe2dm_hart_status_i      (dm_hart_status_qlfy    ),
+
+    .soc2dm_fuse_mhartid_i      (core_fuse_mhartid_i    ),
+    .pipe2dm_pc_sample_i        (dm_pc_sample_qlfy      ),
+
+    // DM <-> Pipeline: HART Abstract Command / Program Buffer i/f
+    .pipe2dm_pbuf_addr_i        (dm_pbuf_addr_qlfy      ),
+    .dm2pipe_pbuf_instr_o       (dm_pbuf_instr          ),
+
+    // DM <-> Pipeline: HART Abstract Data regs i/f
+    .pipe2dm_dreg_req_i         (dm_dreg_req_qlfy       ),
+    .pipe2dm_dreg_wr_i          (dm_dreg_wr             ),
+    .pipe2dm_dreg_wdata_i       (dm_dreg_wdata          ),
+    .dm2pipe_dreg_resp_o        (dm_dreg_resp           ),
+    .dm2pipe_dreg_fail_o        (dm_dreg_fail           ),
+    .dm2pipe_dreg_rdata_o       (dm_dreg_rdata          )
+);
+`endif // SCR1_DBG_EN
+
+
+`ifdef SCR1_CLKCTRL_EN
+//-------------------------------------------------------------------------------
+// Global clock gating logic
+//-------------------------------------------------------------------------------
+scr1_clk_ctrl i_clk_ctrl (
+    .clk                            (clk        ),
+    .rst_n                          (core_rst_n ),
+    .test_mode                      (test_mode  ),
+    .test_rst_n                     (test_rst_n ),
+
+    // Sleep/wake interface
+    .pipe2clkctl_sleep_req_i        (sleep_pipe ),
+    .pipe2clkctl_wake_req_i         (wake_pipe  ),
+
+    // Clocks
+    .clkctl2pipe_clk_alw_on_o       (clk_alw_on ),
+    .clkctl2pipe_clk_o              (clk_pipe   ),
+    .clkctl2pipe_clk_en_o           (clk_pipe_en),
+    .clkctl2pipe_clk_dbgc_o         (clk_dbgc   )
+);
+`endif // SCR1_CLKCTRL_EN
+
+endmodule : scr1_core_top
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_dm.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_dm.sv
new file mode 100644
index 0000000..3dfd254
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_dm.sv
@@ -0,0 +1,1427 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_dm.sv>
+/// @brief      Debug Module (DM)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Allows debugger to perform a system reset (ndm_rst)
+ // - Allows debugger to control the HART's state
+ // - Provides debugger with information about the current HART's state
+ // - Provides debugger with Abstract Command interface that allows to:
+ //   - Access MPRF registers
+ //   - Access CSR registers
+ //   - Access memory with the same view and permission as the hart has
+ // - Provides debugger with Abstract Command status information (busy flag and error code)
+ // - Provides debugger with Program Buffer functionality that allows to execute
+ //   small programs on a halted HART
+ //
+ // Structure:
+ // - DM <-> DMI interface
+ // - DM registers:
+ //   - DMCONTROL
+ //   - DMSTATUS
+ // - Abstract Command Control logic
+ // - Abstract Command FSM
+ // - Abstract Command Status logic
+ // - Abstract Instruction logic
+ // - Abstract registers:
+ //   - COMMAND
+ //   - ABSTRACTAUTO
+ //   - PROGBUF0..5
+ //   - DATA0..1
+ // - DHI FSM
+ // - HART command registers
+ // - DHI interface
+ //
+//
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_csr.svh"
+`include "scr1_dm.svh"
+
+module scr1_dm (
+    // System
+    input  logic                                    rst_n,                      // DM reset
+    input  logic                                    clk,                        // DM clock
+
+    // DM internal interface
+    input  logic                                    dmi2dm_req_i,               // DMI request
+    input  logic                                    dmi2dm_wr_i,                // DMI write
+    input  logic [SCR1_DBG_DMI_ADDR_WIDTH-1:0]      dmi2dm_addr_i,              // DMI address
+    input  logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]      dmi2dm_wdata_i,             // DMI write data
+    output logic                                    dm2dmi_resp_o,              // DMI response
+    output logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]      dm2dmi_rdata_o,             // DMI read data
+
+    // DM <-> Pipeline: HART Run Control i/f
+    output logic                                    ndm_rst_n_o,                // Non-DM Reset output
+    output logic                                    hart_rst_n_o,               // HART reset output
+    output logic                                    dm2pipe_active_o,           // Debug Module active flag
+    output logic                                    dm2pipe_cmd_req_o,          // Request to pipe
+    output type_scr1_hdu_dbgstates_e                dm2pipe_cmd_o,              // Command to pipe
+    input  logic                                    pipe2dm_cmd_resp_i,         // Response to Debug Module
+    input  logic                                    pipe2dm_cmd_rcode_i,        // HART Command return code: 0 - Ok; 1 - Error
+    input  logic                                    pipe2dm_hart_event_i,       // HART event flag
+    input  type_scr1_hdu_hartstatus_s               pipe2dm_hart_status_i,      // HART Status
+
+    input  logic [`SCR1_XLEN-1:0]                   soc2dm_fuse_mhartid_i,      // RO MHARTID value
+    input  logic [`SCR1_XLEN-1:0]                   pipe2dm_pc_sample_i,        // RO PC value for sampling
+
+    // HART Abstract Command / Program Buffer i/f
+    input  logic [SCR1_HDU_PBUF_ADDR_WIDTH-1:0]     pipe2dm_pbuf_addr_i,        // Program Buffer address
+    output logic [SCR1_HDU_CORE_INSTR_WIDTH-1:0]    dm2pipe_pbuf_instr_o,       // Program Buffer instruction
+
+    // HART Abstract Data regs i/f
+    input  logic                                    pipe2dm_dreg_req_i,         // Abstract Data Register request
+    input  logic                                    pipe2dm_dreg_wr_i,          // Abstract Data Register write
+    input  logic [`SCR1_XLEN-1:0]                   pipe2dm_dreg_wdata_i,       // Abstract Data Register write data
+    output logic                                    dm2pipe_dreg_resp_o,        // Abstract Data Register response
+    output logic                                    dm2pipe_dreg_fail_o,        // Abstract Data Register fail - possibly not needed ?
+    output logic [`SCR1_XLEN-1:0]                   dm2pipe_dreg_rdata_o        // Abstract Data Register read data
+);
+
+//------------------------------------------------------------------------------
+// Local types declaration
+//------------------------------------------------------------------------------
+
+typedef enum logic [3:0] {
+    ABS_STATE_IDLE,
+    ABS_STATE_ERR,
+    ABS_STATE_EXEC,
+    ABS_STATE_XREG_RW,
+    ABS_STATE_MEM_SAVE_XREG,
+    ABS_STATE_MEM_SAVE_XREG_FORADDR,
+    ABS_STATE_MEM_RW,
+    ABS_STATE_MEM_RETURN_XREG,
+    ABS_STATE_MEM_RETURN_XREG_FORADDR,
+    ABS_STATE_CSR_RO,
+    ABS_STATE_CSR_SAVE_XREG,
+    ABS_STATE_CSR_RW,
+    ABS_STATE_CSR_RETURN_XREG
+} type_scr1_abs_fsm_e;
+
+typedef enum logic [2:0] {
+    DHI_STATE_IDLE,
+    DHI_STATE_EXEC,
+    DHI_STATE_EXEC_RUN,
+    DHI_STATE_EXEC_HALT,
+    DHI_STATE_HALT_REQ,
+    DHI_STATE_RESUME_REQ,
+    DHI_STATE_RESUME_RUN
+} type_scr1_dhi_fsm_e;
+
+typedef enum logic [SCR1_DBG_ABSTRACTCS_CMDERR_WDTH:0] {
+    ABS_ERR_NONE      = (SCR1_DBG_ABSTRACTCS_CMDERR_WDTH+1)'('d0),
+    ABS_ERR_BUSY      = (SCR1_DBG_ABSTRACTCS_CMDERR_WDTH+1)'('d1),
+    ABS_ERR_CMD       = (SCR1_DBG_ABSTRACTCS_CMDERR_WDTH+1)'('d2),
+    ABS_ERR_EXCEPTION = (SCR1_DBG_ABSTRACTCS_CMDERR_WDTH+1)'('d3),
+    ABS_ERR_NOHALT    = (SCR1_DBG_ABSTRACTCS_CMDERR_WDTH+1)'('d4)
+} type_scr1_abs_err_e;
+
+
+//------------------------------------------------------------------------------
+// Local parameters declaration
+//------------------------------------------------------------------------------
+
+// Abstract instruction opcode parameters
+localparam      SCR1_OP_SYSTEM      = 7'b111_0011;
+localparam      SCR1_OP_LOAD        = 7'b000_0011;
+localparam      SCR1_OP_STORE       = 7'b010_0011;
+
+// Abstract instruction funct3 parameters
+localparam      SCR1_FUNCT3_CSRRW       = 3'b001;
+localparam      SCR1_FUNCT3_CSRRS       = 3'b010;
+localparam      SCR1_FUNCT3_SB          = 3'b000;
+localparam      SCR1_FUNCT3_SH          = 3'b001;
+localparam      SCR1_FUNCT3_SW          = 3'b010;
+localparam      SCR1_FUNCT3_LW          = 3'b010;
+localparam      SCR1_FUNCT3_LBU         = 3'b100;
+localparam      SCR1_FUNCT3_LHU         = 3'b101;
+
+// DMCONTROL parameters
+//------------------------------------------------------------------------------
+localparam      DMCONTROL_HARTRESET     = 1'd0;
+localparam      DMCONTROL_RESERVEDB     = 1'd0;
+localparam      DMCONTROL_HASEL         = 1'd0;
+localparam      DMCONTROL_HARTSELLO     = 1'd0;
+localparam      DMCONTROL_HARTSELHI     = 1'd0;
+localparam      DMCONTROL_RESERVEDA     = 1'd0;
+
+// DMSTATUS parameters
+//------------------------------------------------------------------------------
+localparam      DMSTATUS_RESERVEDC      = 1'd0;
+localparam      DMSTATUS_IMPEBREAK      = 1'd1;
+localparam      DMSTATUS_RESERVEDB      = 1'd0;
+localparam      DMSTATUS_ALLUNAVAIL     = 1'd0;
+localparam      DMSTATUS_ANYUNAVAIL     = 1'd0;
+localparam      DMSTATUS_ALLANYUNAVAIL  = 1'd0;
+localparam      DMSTATUS_ALLANYNONEXIST = 1'b0;
+localparam      DMSTATUS_AUTHENTICATED  = 1'd1;
+localparam      DMSTATUS_AUTHBUSY       = 1'd0;
+localparam      DMSTATUS_RESERVEDA      = 1'd0;
+localparam      DMSTATUS_DEVTREEVALID   = 1'd0;
+localparam      DMSTATUS_VERSION        = 2'd2;
+
+// HARTINFO parameters
+//------------------------------------------------------------------------------
+localparam      HARTINFO_RESERVEDB      = 1'd0;
+localparam      HARTINFO_NSCRATCH       = 4'd1;
+localparam      HARTINFO_RESERVEDA      = 1'd0;
+localparam      HARTINFO_DATAACCESS     = 1'd0;
+localparam      HARTINFO_DATASIZE       = 4'd1;
+localparam      HARTINFO_DATAADDR       = 12'h7b2;
+
+// ABSTRACTCS parameters
+//------------------------------------------------------------------------------
+localparam      ABSTRACTCS_RESERVEDD    = 1'd0;
+localparam      ABSTRACTCS_PROGBUFSIZE  = 5'd6;
+localparam      ABSTRACTCS_RESERVEDC    = 1'd0;
+localparam      ABSTRACTCS_RESERVEDB    = 1'd0;
+localparam      ABSTRACTCS_RESERVEDA    = 1'd0;
+localparam      ABSTRACTCS_DATACOUNT    = 4'd2;
+
+localparam      ABS_CMD_HARTREG         = 1'd0;
+localparam      ABS_CMD_HARTMEM         = 2'd2;
+localparam      ABS_CMD_HARTREG_CSR     = 4'b0000;
+localparam      ABS_CMD_HARTREG_INTFPU  = 4'b0001;
+localparam      ABS_CMD_HARTREG_INT     = 7'b000_0000;
+localparam      ABS_CMD_HARTREG_FPU     = 7'b000_0001;
+localparam      ABS_EXEC_EBREAK         = 32'b000000000001_00000_000_00000_1110011;
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// DM <-> DMI interface internal signals
+//------------------------------------------------------------------------------
+
+// Register selection signals
+logic                                             dmi_req_dmcontrol;
+logic                                             dmi_req_abstractcs;
+logic                                             dmi_req_abstractauto;
+logic                                             dmi_req_command;
+logic                                             dmi_rpt_command;
+logic                                             dmi_req_data0;
+logic                                             dmi_req_data1;
+logic                                             dmi_req_progbuf0;
+logic                                             dmi_req_progbuf1;
+logic                                             dmi_req_progbuf2;
+logic                                             dmi_req_progbuf3;
+logic                                             dmi_req_progbuf4;
+logic                                             dmi_req_progbuf5;
+
+logic                                             dmi_req_any;
+
+// Registers write request signals
+logic                                             dmcontrol_wr_req;
+logic                                             abstractcs_wr_req;
+logic                                             data0_wr_req;
+logic                                             data1_wr_req;
+logic                                             dreg_wr_req;
+logic                                             command_wr_req;
+logic                                             autoexec_wr_req;
+logic                                             progbuf0_wr_req;
+logic                                             progbuf1_wr_req;
+logic                                             progbuf2_wr_req;
+logic                                             progbuf3_wr_req;
+logic                                             progbuf4_wr_req;
+logic                                             progbuf5_wr_req;
+
+// DM registers
+//------------------------------------------------------------------------------
+
+// DM clock enable signals
+logic                                             clk_en_dm;
+logic                                             clk_en_dm_ff;
+
+// DMCONTROL register signals
+logic                                             dmcontrol_haltreq_ff;
+logic                                             dmcontrol_haltreq_next;
+logic                                             dmcontrol_resumereq_ff;
+logic                                             dmcontrol_resumereq_next;
+logic                                             dmcontrol_ackhavereset_ff;
+logic                                             dmcontrol_ackhavereset_next;
+logic                                             dmcontrol_ndmreset_ff;
+logic                                             dmcontrol_ndmreset_next;
+logic                                             dmcontrol_dmactive_ff;
+logic                                             dmcontrol_dmactive_next;
+
+// Auxilary Skip Reset On Powerup register
+logic                                             havereset_skip_pwrup_ff;
+logic                                             havereset_skip_pwrup_next;
+
+// DMSTATUS register signals
+logic                                             dmstatus_allany_havereset_ff;
+logic                                             dmstatus_allany_havereset_next;
+logic                                             dmstatus_allany_resumeack_ff;
+logic                                             dmstatus_allany_resumeack_next;
+logic                                             dmstatus_allany_halted_ff;
+logic                                             dmstatus_allany_halted_next;
+
+// Abstract command control logic signals
+//------------------------------------------------------------------------------
+
+logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]               abs_cmd;
+
+logic                                             abs_cmd_csr_ro;
+logic [SCR1_DBG_COMMAND_TYPE_WDTH:0]              abs_cmd_type;
+logic                                             abs_cmd_regacs;
+logic [SCR1_DBG_COMMAND_ACCESSREG_REGNO_HI-12:0]  abs_cmd_regtype;
+logic [6:0]                                       abs_cmd_regfile;
+logic                                             abs_cmd_regwr;
+logic [SCR1_DBG_COMMAND_ACCESSREG_SIZE_WDTH:0]    abs_cmd_regsize;
+logic                                             abs_cmd_execprogbuf;
+logic                                             abs_cmd_regvalid;
+logic [2:0]                                       abs_cmd_memsize;
+logic                                             abs_cmd_memwr;
+logic                                             abs_cmd_memvalid;
+
+logic                                             abs_cmd_regsize_vd;
+logic                                             abs_cmd_memsize_vd;
+
+logic                                             abs_cmd_wr_ff;
+logic                                             abs_cmd_wr_next;
+logic                                             abs_cmd_postexec_ff;
+logic                                             abs_cmd_postexec_next;
+logic [11:0]                                      abs_cmd_regno;
+logic [11:0]                                      abs_cmd_regno_ff;
+logic [1:0]                                       abs_cmd_size_ff;
+logic [1:0]                                       abs_cmd_size_next;
+
+logic                                             abs_reg_access_csr;
+logic                                             abs_reg_access_mprf;
+
+logic                                             abs_cmd_hartreg_vd;
+logic                                             abs_cmd_hartmem_vd;
+
+logic                                             abs_cmd_reg_access_req;
+logic                                             abs_cmd_csr_access_req;
+logic                                             abs_cmd_mprf_access_req;
+logic                                             abs_cmd_execprogbuf_req;
+
+logic                                             abs_cmd_csr_ro_access_vd;
+logic                                             abs_cmd_csr_rw_access_vd;
+logic                                             abs_cmd_mprf_access_vd;
+logic                                             abs_cmd_mem_access_vd;
+
+// Abstract FSM signals
+//------------------------------------------------------------------------------
+
+type_scr1_abs_fsm_e                               abs_fsm_ff;
+type_scr1_abs_fsm_e                               abs_fsm_next;
+logic                                             abs_fsm_idle;
+logic                                             abs_fsm_exec;
+logic                                             abs_fsm_csr_ro;
+logic                                             abs_fsm_err;
+logic                                             abs_fsm_use_addr;
+
+// Abstract registers
+//------------------------------------------------------------------------------
+
+logic                                             clk_en_abs;
+
+// ABSTRACTCS register signals
+logic                                             abstractcs_busy;
+logic                                             abstractcs_ro_en;
+
+// COMMAND register signals
+logic [`SCR1_XLEN-1:0]                            abs_command_ff;
+logic [`SCR1_XLEN-1:0]                            abs_command_next;
+
+// ABSTRACTAUTO register signals
+logic                                             abs_autoexec_ff;
+logic                                             abs_autoexec_next;
+
+// Program buffer registers
+logic [`SCR1_XLEN-1:0]                            abs_progbuf0_ff;
+logic [`SCR1_XLEN-1:0]                            abs_progbuf1_ff;
+logic [`SCR1_XLEN-1:0]                            abs_progbuf2_ff;
+logic [`SCR1_XLEN-1:0]                            abs_progbuf3_ff;
+logic [`SCR1_XLEN-1:0]                            abs_progbuf4_ff;
+logic [`SCR1_XLEN-1:0]                            abs_progbuf5_ff;
+
+// Data 0/1 registers
+logic                                             data0_xreg_save;
+logic [`SCR1_XLEN-1:0]                            abs_data0_ff;
+logic [`SCR1_XLEN-1:0]                            abs_data0_next;
+logic [`SCR1_XLEN-1:0]                            abs_data1_ff;
+logic [`SCR1_XLEN-1:0]                            abs_data1_next;
+
+// Abstract command status logic signals
+//------------------------------------------------------------------------------
+
+// Abstract error exception flag register
+logic                                             abs_err_exc_upd;
+logic                                             abs_err_exc_ff;
+logic                                             abs_err_exc_next;
+
+logic                                             abs_err_acc_busy_upd;
+logic                                             abs_err_acc_busy_ff;
+logic                                             abs_err_acc_busy_next;
+
+type_scr1_abs_err_e                               abstractcs_cmderr_ff;
+type_scr1_abs_err_e                               abstractcs_cmderr_next;
+
+// Abstract instruction signals
+//------------------------------------------------------------------------------
+
+// Abstract instruction execution request register
+logic                                             abs_exec_req_next;
+logic                                             abs_exec_req_ff;
+
+// Abstract instruction register
+logic [4:0]                                       abs_instr_rd;
+logic [4:0]                                       abs_instr_rs1;
+logic [4:0]                                       abs_instr_rs2;
+logic [2:0]                                       abs_instr_mem_funct3;
+logic [`SCR1_XLEN-1:0]                            abs_exec_instr_next;
+logic [`SCR1_XLEN-1:0]                            abs_exec_instr_ff;
+
+// DHI FSM signals
+//------------------------------------------------------------------------------
+
+type_scr1_dhi_fsm_e                               dhi_fsm_next;
+type_scr1_dhi_fsm_e                               dhi_fsm_ff;
+type_scr1_dhi_fsm_e                               dhi_req;
+
+logic                                             dhi_fsm_idle;
+logic                                             dhi_fsm_exec;
+logic                                             dhi_fsm_exec_halt;
+logic                                             dhi_fsm_halt_req;
+logic                                             dhi_fsm_resume_req;
+
+// DHI interface signals
+//------------------------------------------------------------------------------
+
+logic                                             cmd_resp_ok;
+logic                                             hart_rst_unexp;
+logic                                             halt_req_vd;
+logic                                             resume_req_vd;
+
+logic                                             dhi_resp;
+logic                                             dhi_resp_exc;
+
+logic                                             hart_pbuf_ebreak_ff;
+logic                                             hart_pbuf_ebreak_next;
+
+// HART command registers
+//------------------------------------------------------------------------------
+
+logic                                             hart_cmd_req_ff;
+logic                                             hart_cmd_req_next;
+
+type_scr1_hdu_dbgstates_e                         hart_cmd_ff;
+type_scr1_hdu_dbgstates_e                         hart_cmd_next;
+
+// HART state signals
+//------------------------------------------------------------------------------
+
+logic                                             hart_state_reset;
+logic                                             hart_state_run;
+logic                                             hart_state_drun;
+logic                                             hart_state_dhalt;
+
+//------------------------------------------------------------------------------
+// DM <-> DMI interface
+//------------------------------------------------------------------------------
+
+// Register selection logic
+//------------------------------------------------------------------------------
+
+always_comb begin
+    dmi_req_dmcontrol    = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_DMCONTROL);
+    dmi_req_abstractcs   = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_ABSTRACTCS);
+    dmi_req_abstractauto = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_ABSTRACTAUTO);
+    dmi_req_data0        = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_DATA0);
+    dmi_req_data1        = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_DATA1);
+    dmi_req_command      = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_COMMAND);
+    dmi_rpt_command      = (abs_autoexec_ff & dmi_req_data0);
+    dmi_req_progbuf0     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF0);
+    dmi_req_progbuf1     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF1);
+    dmi_req_progbuf2     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF2);
+    dmi_req_progbuf3     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF3);
+    dmi_req_progbuf4     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF4);
+    dmi_req_progbuf5     = dmi2dm_req_i & (dmi2dm_addr_i == SCR1_DBG_PROGBUF5);
+end
+
+assign dmi_req_any = dmi_req_command  | dmi_rpt_command  | dmi_req_abstractauto
+                   | dmi_req_data0    | dmi_req_data1    | dmi_req_progbuf0
+                   | dmi_req_progbuf1 | dmi_req_progbuf2 | dmi_req_progbuf3
+                   | dmi_req_progbuf4 | dmi_req_progbuf5;
+
+
+// Read data multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    dm2dmi_rdata_o = '0;
+
+    case (dmi2dm_addr_i)
+        SCR1_DBG_DMSTATUS: begin
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_RESERVEDC_HI:
+                           SCR1_DBG_DMSTATUS_RESERVEDC_LO]     = DMSTATUS_RESERVEDC;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_IMPEBREAK]        = DMSTATUS_IMPEBREAK;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_RESERVEDB_HI:
+                           SCR1_DBG_DMSTATUS_RESERVEDB_LO]     = DMSTATUS_RESERVEDB;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLHAVERESET]     = dmstatus_allany_havereset_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYHAVERESET]     = dmstatus_allany_havereset_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLRESUMEACK]     = dmstatus_allany_resumeack_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYRESUMEACK]     = dmstatus_allany_resumeack_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLNONEXISTENT]   = DMSTATUS_ALLANYNONEXIST;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYNONEXISTENT]   = DMSTATUS_ALLANYNONEXIST;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLUNAVAIL]       = DMSTATUS_ALLANYUNAVAIL;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYUNAVAIL]       = DMSTATUS_ALLANYUNAVAIL;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLRUNNING]       = ~dmstatus_allany_halted_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYRUNNING]       = ~dmstatus_allany_halted_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ALLHALTED]        = dmstatus_allany_halted_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_ANYHALTED]        = dmstatus_allany_halted_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_AUTHENTICATED]    = DMSTATUS_AUTHENTICATED;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_AUTHBUSY]         = DMSTATUS_AUTHBUSY;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_RESERVEDA]        = DMSTATUS_RESERVEDA;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_DEVTREEVALID]     = DMSTATUS_DEVTREEVALID;
+            dm2dmi_rdata_o[SCR1_DBG_DMSTATUS_VERSION_HI:
+                           SCR1_DBG_DMSTATUS_VERSION_LO]       = DMSTATUS_VERSION;;
+        end
+
+        SCR1_DBG_DMCONTROL: begin
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_HALTREQ]         = dmcontrol_haltreq_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_RESUMEREQ]       = dmcontrol_resumereq_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_HARTRESET]       = DMCONTROL_HARTRESET;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_ACKHAVERESET]    = dmcontrol_ackhavereset_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_RESERVEDB]       = DMCONTROL_RESERVEDB;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_HASEL]           = DMCONTROL_HASEL;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_HARTSELLO_HI:
+                           SCR1_DBG_DMCONTROL_HARTSELLO_LO]    = DMCONTROL_HARTSELLO;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_HARTSELHI_HI:
+                           SCR1_DBG_DMCONTROL_HARTSELHI_LO]    = DMCONTROL_HARTSELHI;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_RESERVEDA_HI:
+                           SCR1_DBG_DMCONTROL_RESERVEDA_LO]    = DMCONTROL_RESERVEDA;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_NDMRESET]        = dmcontrol_ndmreset_ff;
+            dm2dmi_rdata_o[SCR1_DBG_DMCONTROL_DMACTIVE]        = dmcontrol_dmactive_ff;
+        end
+
+        SCR1_DBG_ABSTRACTCS: begin
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_RESERVEDD_HI:
+                           SCR1_DBG_ABSTRACTCS_RESERVEDD_LO]   = ABSTRACTCS_RESERVEDD;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_HI:
+                           SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_LO] = ABSTRACTCS_PROGBUFSIZE;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_RESERVEDC_HI:
+                           SCR1_DBG_ABSTRACTCS_RESERVEDC_LO]   = ABSTRACTCS_RESERVEDC;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_BUSY]           = abstractcs_busy;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_RESERVEDB]      = ABSTRACTCS_RESERVEDB;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_CMDERR_HI:
+                           SCR1_DBG_ABSTRACTCS_CMDERR_LO]      = abstractcs_cmderr_ff;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_RESERVEDA_HI:
+                           SCR1_DBG_ABSTRACTCS_RESERVEDA_LO]   = ABSTRACTCS_RESERVEDA;
+            dm2dmi_rdata_o[SCR1_DBG_ABSTRACTCS_DATACOUNT_HI:
+                           SCR1_DBG_ABSTRACTCS_DATACOUNT_LO]   = ABSTRACTCS_DATACOUNT;
+        end
+
+        SCR1_DBG_HARTINFO: begin
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_RESERVEDB_HI:
+                           SCR1_DBG_HARTINFO_RESERVEDB_LO]     = HARTINFO_RESERVEDB;
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_NSCRATCH_HI:
+                           SCR1_DBG_HARTINFO_NSCRATCH_LO]      = HARTINFO_NSCRATCH;
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_RESERVEDA_HI:
+                           SCR1_DBG_HARTINFO_RESERVEDA_LO]     = HARTINFO_RESERVEDA;
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_DATAACCESS]       = HARTINFO_DATAACCESS;
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_DATASIZE_HI:
+                           SCR1_DBG_HARTINFO_DATASIZE_LO]      = HARTINFO_DATASIZE;
+            dm2dmi_rdata_o[SCR1_DBG_HARTINFO_DATAADDR_HI:
+                           SCR1_DBG_HARTINFO_DATAADDR_LO]      = HARTINFO_DATAADDR;
+        end
+
+        SCR1_DBG_ABSTRACTAUTO: dm2dmi_rdata_o[0] = abs_autoexec_ff;
+        SCR1_DBG_DATA0       : dm2dmi_rdata_o    = abs_data0_ff;
+        SCR1_DBG_DATA1       : dm2dmi_rdata_o    = abs_data1_ff;
+        SCR1_DBG_PROGBUF0    : dm2dmi_rdata_o    = abs_progbuf0_ff;
+        SCR1_DBG_PROGBUF1    : dm2dmi_rdata_o    = abs_progbuf1_ff;
+        SCR1_DBG_PROGBUF2    : dm2dmi_rdata_o    = abs_progbuf2_ff;
+        SCR1_DBG_PROGBUF3    : dm2dmi_rdata_o    = abs_progbuf3_ff;
+        SCR1_DBG_PROGBUF4    : dm2dmi_rdata_o    = abs_progbuf4_ff;
+        SCR1_DBG_PROGBUF5    : dm2dmi_rdata_o    = abs_progbuf5_ff;
+        SCR1_DBG_HALTSUM0    : dm2dmi_rdata_o[0] = dmstatus_allany_halted_ff;
+
+        default: begin
+            dm2dmi_rdata_o = '0;
+        end
+    endcase
+end
+
+// Response
+assign dm2dmi_resp_o = 1'b1;
+
+// Write requests signals
+//------------------------------------------------------------------------------
+
+assign dmcontrol_wr_req  = dmi_req_dmcontrol    & dmi2dm_wr_i;
+assign data0_wr_req      = dmi_req_data0        & dmi2dm_wr_i;
+assign data1_wr_req      = dmi_req_data1        & dmi2dm_wr_i;
+assign dreg_wr_req       = pipe2dm_dreg_req_i   & pipe2dm_dreg_wr_i;
+assign command_wr_req    = dmi_req_command      & dmi2dm_wr_i;
+assign autoexec_wr_req   = dmi_req_abstractauto & dmi2dm_wr_i;
+assign progbuf0_wr_req   = dmi_req_progbuf0     & dmi2dm_wr_i;
+assign progbuf1_wr_req   = dmi_req_progbuf1     & dmi2dm_wr_i;
+assign progbuf2_wr_req   = dmi_req_progbuf2     & dmi2dm_wr_i;
+assign progbuf3_wr_req   = dmi_req_progbuf3     & dmi2dm_wr_i;
+assign progbuf4_wr_req   = dmi_req_progbuf4     & dmi2dm_wr_i;
+assign progbuf5_wr_req   = dmi_req_progbuf5     & dmi2dm_wr_i;
+assign abstractcs_wr_req = dmi_req_abstractcs   & dmi2dm_wr_i;
+
+// HART state signals
+//------------------------------------------------------------------------------
+
+assign hart_state_reset = (pipe2dm_hart_status_i.dbg_state == SCR1_HDU_DBGSTATE_RESET);
+assign hart_state_run   = (pipe2dm_hart_status_i.dbg_state == SCR1_HDU_DBGSTATE_RUN);
+assign hart_state_dhalt = (pipe2dm_hart_status_i.dbg_state == SCR1_HDU_DBGSTATE_DHALTED);
+assign hart_state_drun  = (pipe2dm_hart_status_i.dbg_state == SCR1_HDU_DBGSTATE_DRUN);
+
+//------------------------------------------------------------------------------
+// DM registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - DM clock enable register
+ // - Auxilary Skip Reset On Powerup register
+ // - DMCONTROL register
+ // - DMSTATUS register
+
+// DM clock enable logic
+//------------------------------------------------------------------------------
+
+assign clk_en_dm = dmcontrol_wr_req | dmcontrol_dmactive_ff | clk_en_dm_ff;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        clk_en_dm_ff <= 1'b0;
+    end else if (clk_en_dm) begin
+        clk_en_dm_ff <= dmcontrol_dmactive_ff;
+    end
+end
+
+assign dm2pipe_active_o = clk_en_dm_ff;
+
+// DMCONTROL register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        dmcontrol_dmactive_ff     <= 1'b0;
+        dmcontrol_ndmreset_ff     <= 1'b0;
+        dmcontrol_ackhavereset_ff <= 1'b0;
+        dmcontrol_haltreq_ff      <= 1'b0;
+        dmcontrol_resumereq_ff    <= 1'b0;
+    end else if (clk_en_dm) begin
+        dmcontrol_dmactive_ff     <= dmcontrol_dmactive_next;
+        dmcontrol_ndmreset_ff     <= dmcontrol_ndmreset_next;
+        dmcontrol_ackhavereset_ff <= dmcontrol_ackhavereset_next;
+        dmcontrol_haltreq_ff      <= dmcontrol_haltreq_next;
+        dmcontrol_resumereq_ff    <= dmcontrol_resumereq_next;
+    end
+end
+
+assign dmcontrol_dmactive_next = dmcontrol_wr_req
+                               ? dmi2dm_wdata_i[SCR1_DBG_DMCONTROL_DMACTIVE]
+                               : dmcontrol_dmactive_ff;
+
+always_comb begin
+    dmcontrol_ndmreset_next     = dmcontrol_ndmreset_ff;
+    dmcontrol_ackhavereset_next = dmcontrol_ackhavereset_ff;
+    dmcontrol_haltreq_next      = dmcontrol_haltreq_ff;
+    dmcontrol_resumereq_next    = dmcontrol_resumereq_ff;
+    if (~dmcontrol_dmactive_ff) begin
+        dmcontrol_ndmreset_next     = 1'b0;
+        dmcontrol_ackhavereset_next = 1'b0;
+        dmcontrol_haltreq_next      = 1'b0;
+        dmcontrol_resumereq_next    = 1'b0;
+    end else if (dmcontrol_wr_req) begin
+        dmcontrol_ndmreset_next     = dmi2dm_wdata_i[SCR1_DBG_DMCONTROL_NDMRESET];
+        dmcontrol_ackhavereset_next = dmi2dm_wdata_i[SCR1_DBG_DMCONTROL_ACKHAVERESET];
+        dmcontrol_haltreq_next      = dmi2dm_wdata_i[SCR1_DBG_DMCONTROL_HALTREQ];
+        dmcontrol_resumereq_next    = dmi2dm_wdata_i[SCR1_DBG_DMCONTROL_RESUMEREQ];
+    end
+end
+
+// Reset signal for system controlled by Debug Module
+assign hart_rst_n_o = ~dmcontrol_ndmreset_ff;
+assign ndm_rst_n_o  = ~dmcontrol_ndmreset_ff;
+
+// Skip reset on powerup register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        havereset_skip_pwrup_ff <= 1'b1;
+    end else if (clk_en_dm) begin
+        havereset_skip_pwrup_ff <= havereset_skip_pwrup_next;
+    end
+end
+
+assign havereset_skip_pwrup_next = ~dmcontrol_dmactive_ff  ? 1'b1
+                                 : havereset_skip_pwrup_ff ? hart_state_reset & ndm_rst_n_o & hart_rst_n_o
+                                                           : havereset_skip_pwrup_ff;
+
+// DMSTATUS register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        dmstatus_allany_havereset_ff <= 1'b0;
+        dmstatus_allany_resumeack_ff <= 1'b0;
+        dmstatus_allany_halted_ff    <= 1'b0;
+    end else if (clk_en_dm) begin
+        dmstatus_allany_havereset_ff <= dmstatus_allany_havereset_next;
+        dmstatus_allany_resumeack_ff <= dmstatus_allany_resumeack_next;
+        dmstatus_allany_halted_ff    <= dmstatus_allany_halted_next;
+    end
+end
+
+assign dmstatus_allany_havereset_next = ~dmcontrol_dmactive_ff                      ? 1'b0
+                                      : ~havereset_skip_pwrup_ff & hart_state_reset ? 1'b1
+                                      : dmcontrol_ackhavereset_ff                   ? 1'b0
+                                                                                    : dmstatus_allany_havereset_ff;
+assign dmstatus_allany_resumeack_next = ~dmcontrol_dmactive_ff  ? 1'b0
+                                      : ~dmcontrol_resumereq_ff ? 1'b0
+                                      : hart_state_run          ? 1'b1
+                                                                : dmstatus_allany_resumeack_ff;
+
+assign dmstatus_allany_halted_next    = ~dmcontrol_dmactive_ff ? 1'b0
+                                      : hart_state_dhalt       ? 1'b1
+                                      : hart_state_run         ? 1'b0
+                                                               : dmstatus_allany_halted_ff;
+
+//------------------------------------------------------------------------------
+// Abstract Command control logic
+//------------------------------------------------------------------------------
+//
+ // Consists of the following functional units:
+ // - Abstract command decoder
+ // - Abstract command access valid flags
+ // - Abstract command control registers
+
+assign clk_en_abs = clk_en_dm & dmcontrol_dmactive_ff;
+
+// Abstract command decoder
+//------------------------------------------------------------------------------
+
+assign abs_cmd = dmi_req_command ? dmi2dm_wdata_i : abs_command_ff;
+
+always_comb begin
+    abs_cmd_regno       = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_REGNO_LO +: 12];
+
+    abs_cmd_csr_ro      = (abs_cmd_regno == SCR1_CSR_ADDR_MISA)
+                        | (abs_cmd_regno == SCR1_CSR_ADDR_MVENDORID)
+                        | (abs_cmd_regno == SCR1_CSR_ADDR_MARCHID)
+                        | (abs_cmd_regno == SCR1_CSR_ADDR_MIMPID)
+                        | (abs_cmd_regno == SCR1_CSR_ADDR_MHARTID)
+                        | (abs_cmd_regno == SCR1_HDU_DBGCSR_ADDR_DPC);
+
+    abs_cmd_type        = abs_cmd[SCR1_DBG_COMMAND_TYPE_HI:SCR1_DBG_COMMAND_TYPE_LO];
+    abs_cmd_regacs      = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_TRANSFER];
+    abs_cmd_regtype     = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_REGNO_HI:12];
+    abs_cmd_regfile     = abs_cmd[11:5];
+    abs_cmd_regsize     = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_SIZE_HI:
+                                  SCR1_DBG_COMMAND_ACCESSREG_SIZE_LO];
+    abs_cmd_regwr       = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_WRITE];
+    abs_cmd_execprogbuf = abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_POSTEXEC];
+
+    abs_cmd_regvalid    = ~(|{abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_RESERVEDB],
+                              abs_cmd[SCR1_DBG_COMMAND_ACCESSREG_RESERVEDA]});
+
+    abs_cmd_memsize     = abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_HI:
+                                  SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_LO];
+    abs_cmd_memwr       = abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_WRITE];
+
+    abs_cmd_memvalid    = ~(|{abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_AAMVIRTUAL],
+                              abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_AAMPOSTINC],
+                              abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_HI:
+                                      SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_HI],
+                              abs_cmd[SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_HI:
+                                      SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_HI]});
+end
+
+assign abs_reg_access_csr  = (abs_cmd_regtype == ABS_CMD_HARTREG_CSR);
+assign abs_reg_access_mprf = (abs_cmd_regtype == ABS_CMD_HARTREG_INTFPU)
+                           & (abs_cmd_regfile == ABS_CMD_HARTREG_INT);
+
+// Abstract command access request and valid flags
+//------------------------------------------------------------------------------
+
+assign abs_cmd_regsize_vd       = (abs_cmd_regsize == 3'h2);
+assign abs_cmd_memsize_vd       = (abs_cmd_memsize < 3'h3);
+
+assign abs_cmd_hartreg_vd       = (abs_cmd_type == ABS_CMD_HARTREG) & abs_cmd_regvalid;
+assign abs_cmd_hartmem_vd       = (abs_cmd_type == ABS_CMD_HARTMEM) & abs_cmd_memvalid;
+
+// Abstract command requests
+assign abs_cmd_reg_access_req   = abs_cmd_hartreg_vd     & abs_cmd_regacs;
+assign abs_cmd_csr_access_req   = abs_cmd_reg_access_req & abs_reg_access_csr;
+assign abs_cmd_mprf_access_req  = abs_cmd_reg_access_req & abs_reg_access_mprf;
+assign abs_cmd_execprogbuf_req  = abs_cmd_hartreg_vd     & abs_cmd_execprogbuf;
+
+// Abstract command access valid flags
+assign abs_cmd_csr_ro_access_vd = abs_cmd_csr_access_req  & abs_cmd_regsize_vd & ~abs_cmd_regwr
+                                & ~abs_cmd_execprogbuf    & abs_cmd_csr_ro     & hart_state_run;
+assign abs_cmd_csr_rw_access_vd = abs_cmd_csr_access_req  & abs_cmd_regsize_vd
+                                & (abs_cmd_regwr | ~abs_cmd_csr_ro_access_vd);
+assign abs_cmd_mprf_access_vd   = abs_cmd_mprf_access_req & abs_cmd_regsize_vd;
+assign abs_cmd_mem_access_vd    = abs_cmd_hartmem_vd & abs_cmd_memsize_vd;
+
+// Abstract command control registers
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_abs & abs_fsm_idle) begin
+        abs_cmd_postexec_ff <= abs_cmd_postexec_next;
+        abs_cmd_wr_ff       <= abs_cmd_wr_next;
+        abs_cmd_regno_ff    <= abs_cmd_regno;
+        abs_cmd_size_ff     <= abs_cmd_size_next;
+    end
+end
+
+always_comb begin
+    abs_cmd_wr_next       = 1'b0;
+    abs_cmd_postexec_next = 1'b0;
+    abs_cmd_size_next     = abs_cmd_size_ff;
+    if ((command_wr_req | dmi_rpt_command) & hart_state_dhalt & abs_fsm_idle) begin
+        if (abs_cmd_csr_rw_access_vd) begin
+            abs_cmd_wr_next       = abs_cmd_regwr;
+            abs_cmd_postexec_next = abs_cmd_execprogbuf;
+        end else if (abs_cmd_mprf_access_vd) begin
+            abs_cmd_wr_next       = abs_cmd_regwr;
+            abs_cmd_size_next     = abs_cmd_regsize[1:0];
+            abs_cmd_postexec_next = abs_cmd_execprogbuf;
+        end else if (abs_cmd_mem_access_vd) begin
+            abs_cmd_wr_next       = abs_cmd_memwr;
+            abs_cmd_size_next     = abs_cmd_memsize[1:0];
+        end
+    end
+end
+
+//------------------------------------------------------------------------------
+// Abstract command FSM
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) begin
+        if (~dmcontrol_dmactive_ff) begin
+            abs_fsm_ff <= ABS_STATE_IDLE;
+        end else begin
+            abs_fsm_ff <= abs_fsm_next;
+        end
+    end
+end
+
+always_comb begin
+    abs_fsm_next = abs_fsm_ff;
+
+    case (abs_fsm_ff)
+        ABS_STATE_IDLE: begin
+            if (command_wr_req | dmi_rpt_command) begin
+                case (1'b1)
+                    abs_cmd_csr_ro_access_vd: abs_fsm_next = ABS_STATE_CSR_RO;
+                    abs_cmd_csr_rw_access_vd: abs_fsm_next = hart_state_dhalt ? ABS_STATE_CSR_SAVE_XREG : ABS_STATE_ERR;
+                    abs_cmd_mprf_access_vd  : abs_fsm_next = hart_state_dhalt ? ABS_STATE_XREG_RW       : ABS_STATE_ERR;
+                    abs_cmd_execprogbuf_req : abs_fsm_next = ABS_STATE_EXEC;
+                    abs_cmd_mem_access_vd   : abs_fsm_next = hart_state_dhalt ? ABS_STATE_MEM_SAVE_XREG : ABS_STATE_ERR;
+                    default                 : abs_fsm_next = ABS_STATE_ERR;
+                endcase
+            end
+        end
+
+        ABS_STATE_EXEC: begin
+            if (dhi_resp) begin
+                if (dhi_resp_exc | abs_err_acc_busy_ff) begin
+                    abs_fsm_next = ABS_STATE_ERR;
+                end else begin
+                    abs_fsm_next = ABS_STATE_IDLE;
+                end
+            end
+        end
+
+        ABS_STATE_XREG_RW: begin
+            if (dhi_resp) begin
+                case (1'b1)
+                    abs_err_acc_busy_ff: abs_fsm_next = ABS_STATE_ERR;
+                    abs_cmd_postexec_ff: abs_fsm_next = ABS_STATE_EXEC;
+                    default            : abs_fsm_next = ABS_STATE_IDLE;
+                endcase
+            end
+        end
+
+        ABS_STATE_CSR_RO       : abs_fsm_next = abs_err_acc_busy_ff ? ABS_STATE_ERR             : ABS_STATE_IDLE;
+        ABS_STATE_CSR_SAVE_XREG: abs_fsm_next = dhi_resp            ? ABS_STATE_CSR_RW          : ABS_STATE_CSR_SAVE_XREG;
+        ABS_STATE_CSR_RW       : abs_fsm_next = dhi_resp            ? ABS_STATE_CSR_RETURN_XREG : ABS_STATE_CSR_RW;
+
+        ABS_STATE_CSR_RETURN_XREG: begin
+            if (dhi_resp) begin
+                case (1'b1)
+                    abs_err_exc_ff      : abs_fsm_next = ABS_STATE_ERR;
+                    abs_err_acc_busy_ff : abs_fsm_next = ABS_STATE_ERR;
+                    abs_cmd_postexec_ff : abs_fsm_next = ABS_STATE_EXEC;
+                    default             : abs_fsm_next = ABS_STATE_IDLE;
+                endcase
+            end
+        end
+
+        ABS_STATE_MEM_SAVE_XREG         : abs_fsm_next = dhi_resp ? ABS_STATE_MEM_SAVE_XREG_FORADDR   : ABS_STATE_MEM_SAVE_XREG;
+        ABS_STATE_MEM_SAVE_XREG_FORADDR : abs_fsm_next = dhi_resp ? ABS_STATE_MEM_RW                  : ABS_STATE_MEM_SAVE_XREG_FORADDR;
+        ABS_STATE_MEM_RW                : abs_fsm_next = dhi_resp ? ABS_STATE_MEM_RETURN_XREG         : ABS_STATE_MEM_RW;
+        ABS_STATE_MEM_RETURN_XREG       : abs_fsm_next = dhi_resp ? ABS_STATE_MEM_RETURN_XREG_FORADDR : ABS_STATE_MEM_RETURN_XREG;
+
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: begin
+            if (dhi_resp) begin
+                case (1'b1)
+                    abs_err_exc_ff: abs_fsm_next = ABS_STATE_ERR;
+                    abs_err_acc_busy_ff : abs_fsm_next = ABS_STATE_ERR;
+                    abs_cmd_postexec_ff : abs_fsm_next = ABS_STATE_EXEC;
+                    default             : abs_fsm_next = ABS_STATE_IDLE;
+                endcase
+            end
+        end
+
+        ABS_STATE_ERR: begin
+            if (abstractcs_wr_req & (abstractcs_cmderr_next == 3'b0)) begin
+                abs_fsm_next = ABS_STATE_IDLE;
+            end
+        end
+    endcase
+
+    if (~abs_fsm_idle & hart_state_reset) begin
+        abs_fsm_next    = ABS_STATE_ERR;
+    end
+end
+
+assign abs_fsm_idle     = (abs_fsm_ff == ABS_STATE_IDLE);
+assign abs_fsm_exec     = (abs_fsm_ff == ABS_STATE_EXEC);
+assign abs_fsm_csr_ro   = (abs_fsm_ff == ABS_STATE_CSR_RO);
+assign abs_fsm_err      = (abs_fsm_ff == ABS_STATE_ERR);
+assign abs_fsm_use_addr = (abs_fsm_ff == ABS_STATE_MEM_SAVE_XREG_FORADDR)
+                        | (abs_fsm_ff == ABS_STATE_MEM_RETURN_XREG_FORADDR);
+
+//------------------------------------------------------------------------------
+// Abstract command status logic
+//------------------------------------------------------------------------------
+
+// Abstract command access busy error register
+//------------------------------------------------------------------------------
+
+assign abs_err_acc_busy_upd = clk_en_abs & (abs_fsm_idle | dmi_req_any);
+
+always_ff @(posedge clk) begin
+    if (abs_err_acc_busy_upd) abs_err_acc_busy_ff <= abs_err_acc_busy_next;
+end
+
+assign abs_err_acc_busy_next = ~abs_fsm_idle & dmi_req_any;
+
+// Abstract command access exception error register
+//------------------------------------------------------------------------------
+
+assign abs_err_exc_upd = clk_en_abs & (abs_fsm_idle | (dhi_resp & dhi_resp_exc));
+
+always_ff @(posedge clk) begin
+    if (abs_err_exc_upd) abs_err_exc_ff <= abs_err_exc_next;
+end
+
+assign abs_err_exc_next = ~abs_fsm_idle & dhi_resp & dhi_resp_exc;
+
+//------------------------------------------------------------------------------
+// Abstract Instruction logic
+//------------------------------------------------------------------------------
+//
+ // Cosists of the following functional units:
+ // - Instruction execution request register
+ // - Instruction memory FUNCT3 field multiplexer
+ // - Instruction RS1 multiplexer
+ // - Instruction RD multiplexer
+ // - Abstract Instruction register
+
+// Abstract instruction execution request register
+//------------------------------------------------------------------------------
+
+assign abs_exec_req_next = ~(abs_fsm_idle | abs_fsm_csr_ro | abs_fsm_err) & ~dhi_resp;
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) begin
+        if (~dmcontrol_dmactive_ff) begin
+            abs_exec_req_ff <= 1'b0;
+        end else begin
+            abs_exec_req_ff <= abs_exec_req_next;
+        end
+    end
+end
+
+// Abstract instruction memory FUNCT3 field multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    case (abs_cmd_size_ff)
+        2'b00  : abs_instr_mem_funct3 = abs_cmd_wr_ff ? SCR1_FUNCT3_SB : SCR1_FUNCT3_LBU;
+        2'b01  : abs_instr_mem_funct3 = abs_cmd_wr_ff ? SCR1_FUNCT3_SH : SCR1_FUNCT3_LHU;
+        2'b10  : abs_instr_mem_funct3 = abs_cmd_wr_ff ? SCR1_FUNCT3_SW : SCR1_FUNCT3_LW;
+        default: abs_instr_mem_funct3 = SCR1_FUNCT3_SB;
+    endcase
+end
+
+// Abstract instruction RS1 multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    abs_instr_rs1 = 5'h0;
+    case (abs_fsm_ff)
+        ABS_STATE_XREG_RW                : abs_instr_rs1 = abs_cmd_wr_ff ? 5'h0 : abs_cmd_regno_ff[4:0];
+        ABS_STATE_CSR_SAVE_XREG          : abs_instr_rs1 = 5'h5;
+        ABS_STATE_MEM_SAVE_XREG          : abs_instr_rs1 = 5'h5;
+        ABS_STATE_CSR_RETURN_XREG        : abs_instr_rs1 = 5'h5;
+        ABS_STATE_MEM_RETURN_XREG        : abs_instr_rs1 = 5'h5;
+        ABS_STATE_CSR_RW                 : abs_instr_rs1 = abs_cmd_wr_ff ? 5'h5 : 5'h0;
+        ABS_STATE_MEM_SAVE_XREG_FORADDR  : abs_instr_rs1 = 5'h6;
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: abs_instr_rs1 = 5'h6;
+        ABS_STATE_MEM_RW                 : abs_instr_rs1 = 5'h6;
+        default                          : begin end
+    endcase
+end
+
+assign abs_instr_rs2 = 5'h5;
+
+// Abstract instruction RD multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    abs_instr_rd  = 5'h0;
+    case (abs_fsm_ff)
+        ABS_STATE_XREG_RW                : abs_instr_rd = abs_cmd_wr_ff ? abs_cmd_regno_ff[4:0] : 5'h0;
+        ABS_STATE_CSR_SAVE_XREG          : abs_instr_rd = abs_cmd_wr_ff ? 5'h5 : 5'h0;
+        ABS_STATE_MEM_SAVE_XREG          : abs_instr_rd = abs_cmd_wr_ff ? 5'h5 : 5'h0;
+        ABS_STATE_CSR_RW                 : abs_instr_rd = abs_cmd_wr_ff ? 5'h0 : 5'h5;
+        ABS_STATE_MEM_RW                 : abs_instr_rd = abs_cmd_wr_ff ? 5'h0 : 5'h5;
+        ABS_STATE_CSR_RETURN_XREG        : abs_instr_rd = 5'h5;
+        ABS_STATE_MEM_RETURN_XREG        : abs_instr_rd = 5'h5;
+        ABS_STATE_MEM_SAVE_XREG_FORADDR  : abs_instr_rd = 5'h6;
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: abs_instr_rd = 5'h6;
+        default                          : begin end
+    endcase
+end
+
+// Abstract instruction register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_abs) begin
+        abs_exec_instr_ff <= abs_exec_instr_next;
+    end
+end
+
+always_comb begin
+    abs_exec_instr_next = abs_exec_instr_ff;
+    case (abs_fsm_ff)
+        ABS_STATE_XREG_RW,
+        ABS_STATE_CSR_SAVE_XREG,
+        ABS_STATE_CSR_RETURN_XREG,
+        ABS_STATE_MEM_SAVE_XREG,
+        ABS_STATE_MEM_SAVE_XREG_FORADDR,
+        ABS_STATE_MEM_RETURN_XREG,
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: begin
+            abs_exec_instr_next = {SCR1_HDU_DBGCSR_ADDR_DSCRATCH0, abs_instr_rs1, SCR1_FUNCT3_CSRRW, abs_instr_rd, SCR1_OP_SYSTEM};
+        end
+
+        ABS_STATE_CSR_RW: begin
+            abs_exec_instr_next = abs_cmd_wr_ff
+                                ? {abs_cmd_regno_ff[11:0], abs_instr_rs1, SCR1_FUNCT3_CSRRW, abs_instr_rd, SCR1_OP_SYSTEM}
+                                : {abs_cmd_regno_ff[11:0], abs_instr_rs1, SCR1_FUNCT3_CSRRS, abs_instr_rd, SCR1_OP_SYSTEM};
+        end
+
+        ABS_STATE_MEM_RW: begin
+            abs_exec_instr_next = abs_cmd_wr_ff
+                                ? {7'h0,  abs_instr_rs2, abs_instr_rs1, abs_instr_mem_funct3, 5'h0,         SCR1_OP_STORE}
+                                : {12'h0,                abs_instr_rs1, abs_instr_mem_funct3, abs_instr_rd, SCR1_OP_LOAD};
+        end
+
+        default: begin end
+    endcase
+end
+
+//------------------------------------------------------------------------------
+// Abstract registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - ABSTRACTCS register
+ // - COMMAND register
+ // - ABSTRACTAUTO register
+ // - PROGBUF0..5 registers
+ // - DATA0..1 registers
+
+// ABSTRACTCS register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) begin
+        if (~dmcontrol_dmactive_ff) begin
+            abstractcs_cmderr_ff <= ABS_ERR_NONE;
+        end else begin
+            abstractcs_cmderr_ff <= abstractcs_cmderr_next;
+        end
+    end
+end
+
+always_comb begin
+    abstractcs_cmderr_next = abstractcs_cmderr_ff;
+
+    case (abs_fsm_ff)
+        ABS_STATE_IDLE: begin
+            if (command_wr_req | dmi_rpt_command) begin
+                if (abs_cmd_hartreg_vd) begin
+                    case (1'b1)
+                        abs_cmd_reg_access_req : begin
+                            case (1'b1)
+                                abs_cmd_csr_rw_access_vd: abstractcs_cmderr_next = hart_state_dhalt
+                                                                                 ? abstractcs_cmderr_ff
+                                                                                 : ABS_ERR_NOHALT;
+                                abs_cmd_mprf_access_vd  : abstractcs_cmderr_next = hart_state_dhalt
+                                                                                 ? abstractcs_cmderr_ff
+                                                                                 : ABS_ERR_NOHALT;
+                                abs_cmd_csr_ro_access_vd: abstractcs_cmderr_next = abstractcs_cmderr_ff;
+                                default                 : abstractcs_cmderr_next = ABS_ERR_CMD;
+                            endcase
+                        end
+                        abs_cmd_execprogbuf_req         : abstractcs_cmderr_next = abstractcs_cmderr_ff;
+                        default                         : abstractcs_cmderr_next = ABS_ERR_CMD;
+                    endcase
+                end else if (abs_cmd_hartmem_vd) begin
+                    abstractcs_cmderr_next = ~abs_cmd_memsize_vd ? ABS_ERR_CMD
+                                           : ~hart_state_dhalt   ? ABS_ERR_NOHALT
+                                                                 : abstractcs_cmderr_ff;
+                end else begin
+                    abstractcs_cmderr_next = ABS_ERR_CMD;
+                end
+            end
+        end
+
+        ABS_STATE_EXEC: begin
+            if (dhi_resp) begin
+                if (dhi_resp_exc) begin
+                    abstractcs_cmderr_next = ABS_ERR_EXCEPTION;
+                end else if (abs_err_acc_busy_ff) begin
+                    abstractcs_cmderr_next = ABS_ERR_BUSY;
+                end
+            end
+        end
+
+        ABS_STATE_XREG_RW,
+        ABS_STATE_CSR_RO: begin
+            if (abs_err_acc_busy_ff) begin
+                abstractcs_cmderr_next = ABS_ERR_BUSY;
+            end
+        end
+
+        ABS_STATE_CSR_RETURN_XREG,
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: begin
+            if (dhi_resp) begin
+                case (1'b1)
+                    abs_err_exc_ff     : abstractcs_cmderr_next = ABS_ERR_EXCEPTION;
+                    abs_err_acc_busy_ff: abstractcs_cmderr_next = ABS_ERR_BUSY;
+                    default:             abstractcs_cmderr_next = abstractcs_cmderr_ff;
+                endcase
+            end
+        end
+
+        ABS_STATE_ERR: begin
+            if (dmi_req_abstractcs & dmi2dm_wr_i) begin
+                abstractcs_cmderr_next = type_scr1_abs_err_e'(logic'(abstractcs_cmderr_ff)
+                                       & (~dmi2dm_wdata_i[SCR1_DBG_ABSTRACTCS_CMDERR_HI:
+                                                          SCR1_DBG_ABSTRACTCS_CMDERR_LO]));
+            end
+        end
+
+        default: begin
+        end
+    endcase
+
+    if (~abs_fsm_idle & hart_state_reset) begin
+        abstractcs_cmderr_next = ABS_ERR_EXCEPTION;
+    end
+end
+
+assign abstractcs_busy = ~abs_fsm_idle & ~abs_fsm_err;
+
+// Abstract COMMAND register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) abs_command_ff <= abs_command_next;
+end
+
+assign abs_command_next = ~dmcontrol_dmactive_ff          ? '0
+                        : (command_wr_req & abs_fsm_idle) ? dmi2dm_wdata_i
+                                                          : abs_command_ff;
+
+// Abstract ABSTRACTAUTO register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) abs_autoexec_ff <= abs_autoexec_next;
+end
+
+assign abs_autoexec_next = ~dmcontrol_dmactive_ff           ? 1'b0
+                         : (autoexec_wr_req & abs_fsm_idle) ? dmi2dm_wdata_i[0]
+                                                            : abs_autoexec_ff;
+
+// Program Buffer registers
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_abs & abs_fsm_idle) begin
+        if (progbuf0_wr_req) abs_progbuf0_ff <= dmi2dm_wdata_i;
+        if (progbuf1_wr_req) abs_progbuf1_ff <= dmi2dm_wdata_i;
+        if (progbuf2_wr_req) abs_progbuf2_ff <= dmi2dm_wdata_i;
+        if (progbuf3_wr_req) abs_progbuf3_ff <= dmi2dm_wdata_i;
+        if (progbuf4_wr_req) abs_progbuf4_ff <= dmi2dm_wdata_i;
+        if (progbuf5_wr_req) abs_progbuf5_ff <= dmi2dm_wdata_i;
+    end
+end
+
+// Data 0 register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_abs) begin
+        abs_data0_ff <= abs_data0_next;
+    end
+end
+
+assign data0_xreg_save = dreg_wr_req & ~abs_cmd_wr_ff;
+
+always_comb begin
+    abs_data0_next = abs_data0_ff;
+
+    case (abs_fsm_ff)
+        ABS_STATE_IDLE           : abs_data0_next = data0_wr_req    ? dmi2dm_wdata_i       : abs_data0_ff;
+        ABS_STATE_EXEC           : abs_data0_next = dreg_wr_req     ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+        ABS_STATE_CSR_SAVE_XREG  : abs_data0_next = dreg_wr_req     ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+        ABS_STATE_CSR_RETURN_XREG: abs_data0_next = dreg_wr_req     ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+        ABS_STATE_MEM_SAVE_XREG  : abs_data0_next = dreg_wr_req     ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+        ABS_STATE_MEM_RETURN_XREG: abs_data0_next = dreg_wr_req     ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+        ABS_STATE_XREG_RW        : abs_data0_next = data0_xreg_save ? pipe2dm_dreg_wdata_i : abs_data0_ff;
+
+        ABS_STATE_CSR_RO: begin
+            case (abs_cmd_regno_ff[11:0])
+                SCR1_CSR_ADDR_MISA     : abs_data0_next = SCR1_CSR_MISA;
+                SCR1_CSR_ADDR_MVENDORID: abs_data0_next = SCR1_CSR_MVENDORID;
+                SCR1_CSR_ADDR_MARCHID  : abs_data0_next = SCR1_CSR_MARCHID;
+                SCR1_CSR_ADDR_MIMPID   : abs_data0_next = SCR1_CSR_MIMPID;
+                SCR1_CSR_ADDR_MHARTID  : abs_data0_next = soc2dm_fuse_mhartid_i;
+                default                : abs_data0_next = pipe2dm_pc_sample_i;
+            endcase
+        end
+
+        default : begin end
+    endcase
+end
+
+// Data 1 register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_abs) begin
+        abs_data1_ff <= abs_data1_next;
+    end
+end
+
+always_comb begin
+    abs_data1_next = abs_data1_ff;
+    case (abs_fsm_ff)
+        ABS_STATE_IDLE                   : abs_data1_next = data1_wr_req ? dmi2dm_wdata_i       : abs_data1_ff;
+        ABS_STATE_MEM_SAVE_XREG_FORADDR  : abs_data1_next = dreg_wr_req  ? pipe2dm_dreg_wdata_i : abs_data1_ff;
+        ABS_STATE_MEM_RETURN_XREG_FORADDR: abs_data1_next = dreg_wr_req  ? pipe2dm_dreg_wdata_i : abs_data1_ff;
+        default                          : begin end
+    endcase
+end
+
+//------------------------------------------------------------------------------
+// Debug Hart Interface : control
+//------------------------------------------------------------------------------
+
+assign cmd_resp_ok    = pipe2dm_cmd_resp_i & ~pipe2dm_cmd_rcode_i;
+assign hart_rst_unexp = ~dhi_fsm_idle      & ~dhi_fsm_halt_req & hart_state_reset;
+
+assign halt_req_vd    = dmcontrol_haltreq_ff   & ~hart_state_dhalt;
+assign resume_req_vd  = dmcontrol_resumereq_ff & ~dmstatus_allany_resumeack_ff
+                      & hart_state_dhalt;
+
+// DHI fsm
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        dhi_fsm_ff   <= DHI_STATE_IDLE;
+    end else if (clk_en_dm) begin
+        dhi_fsm_ff <= dhi_fsm_next;
+    end
+end
+
+always_comb begin
+    dhi_fsm_next = dhi_fsm_ff;
+    if (~hart_rst_unexp & dmcontrol_dmactive_ff) begin
+        // Normal work
+        case (dhi_fsm_ff)
+            DHI_STATE_IDLE      : dhi_fsm_next = dhi_req;
+            DHI_STATE_EXEC      : dhi_fsm_next = cmd_resp_ok      ? DHI_STATE_EXEC_RUN   : DHI_STATE_EXEC;
+            DHI_STATE_EXEC_RUN  : dhi_fsm_next = hart_state_drun  ? DHI_STATE_EXEC_HALT  : DHI_STATE_EXEC_RUN;
+            DHI_STATE_HALT_REQ  : dhi_fsm_next = cmd_resp_ok      ? DHI_STATE_EXEC_HALT  : DHI_STATE_HALT_REQ;
+            DHI_STATE_EXEC_HALT : dhi_fsm_next = hart_state_dhalt ? DHI_STATE_IDLE       : DHI_STATE_EXEC_HALT;
+            DHI_STATE_RESUME_REQ: dhi_fsm_next = cmd_resp_ok      ? DHI_STATE_RESUME_RUN : DHI_STATE_RESUME_REQ;
+            DHI_STATE_RESUME_RUN: dhi_fsm_next = hart_state_run   ? DHI_STATE_IDLE       : DHI_STATE_RESUME_RUN;
+            default             : dhi_fsm_next = dhi_fsm_ff;
+        endcase
+    end else begin
+        // In case of DM reset or core unexpected reset
+        dhi_fsm_next = DHI_STATE_IDLE;
+    end
+end
+
+assign dhi_fsm_idle       = (dhi_fsm_ff == DHI_STATE_IDLE);
+assign dhi_fsm_halt_req   = (dhi_fsm_ff == DHI_STATE_HALT_REQ);
+assign dhi_fsm_exec       = (dhi_fsm_ff == DHI_STATE_EXEC);
+assign dhi_fsm_exec_halt  = (dhi_fsm_ff == DHI_STATE_EXEC_HALT);
+assign dhi_fsm_resume_req = (dhi_fsm_ff == DHI_STATE_RESUME_REQ);
+
+always_comb begin
+    case (1'b1)
+        abs_exec_req_ff: dhi_req = DHI_STATE_EXEC;
+        halt_req_vd    : dhi_req = DHI_STATE_HALT_REQ;
+        resume_req_vd  : dhi_req = DHI_STATE_RESUME_REQ;
+        default        : dhi_req = DHI_STATE_IDLE;
+    endcase
+end
+
+assign dhi_resp     = dhi_fsm_exec_halt    & hart_state_dhalt;
+assign dhi_resp_exc = pipe2dm_hart_event_i & pipe2dm_hart_status_i.except
+                                           & ~pipe2dm_hart_status_i.ebreak;
+
+// HART command registers
+//------------------------------------------------------------------------------
+
+// HART command request register
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        hart_cmd_req_ff <= 1'b0;
+    end else if (clk_en_dm) begin
+        hart_cmd_req_ff <= hart_cmd_req_next;
+    end
+end
+
+assign hart_cmd_req_next = (dhi_fsm_exec | dhi_fsm_halt_req | dhi_fsm_resume_req)
+                         & ~cmd_resp_ok & dmcontrol_dmactive_ff;
+
+// HART command register
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        hart_cmd_ff <= SCR1_HDU_DBGSTATE_RUN;
+    end else if (clk_en_dm) begin
+        hart_cmd_ff <= hart_cmd_next;
+    end
+end
+
+always_comb begin
+    hart_cmd_next = SCR1_HDU_DBGSTATE_RUN;
+    if (dmcontrol_dmactive_ff) begin
+        case (dhi_fsm_ff)
+            DHI_STATE_EXEC      : hart_cmd_next = SCR1_HDU_DBGSTATE_DRUN;
+            DHI_STATE_HALT_REQ  : hart_cmd_next = SCR1_HDU_DBGSTATE_DHALTED;
+            DHI_STATE_RESUME_REQ: hart_cmd_next = SCR1_HDU_DBGSTATE_RUN;
+            default             : hart_cmd_next = dm2pipe_cmd_o;
+        endcase
+    end
+end
+
+assign dm2pipe_cmd_req_o = hart_cmd_req_ff;
+assign dm2pipe_cmd_o     = hart_cmd_ff;
+
+//------------------------------------------------------------------------------
+// Debug Hart Interface : program buffer
+//------------------------------------------------------------------------------
+
+// Program Buffer execution EBREAK flag
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk) begin
+    if (clk_en_dm) hart_pbuf_ebreak_ff <= hart_pbuf_ebreak_next;
+end
+
+assign hart_pbuf_ebreak_next = abs_fsm_exec & (dm2pipe_pbuf_instr_o == ABS_EXEC_EBREAK);
+
+// Program Buffer instruction multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    dm2pipe_pbuf_instr_o = ABS_EXEC_EBREAK;
+
+    if (abs_fsm_exec & ~hart_pbuf_ebreak_ff) begin
+        case (pipe2dm_pbuf_addr_i)
+            3'h0: dm2pipe_pbuf_instr_o = abs_progbuf0_ff;
+            3'h1: dm2pipe_pbuf_instr_o = abs_progbuf1_ff;
+            3'h2: dm2pipe_pbuf_instr_o = abs_progbuf2_ff;
+            3'h3: dm2pipe_pbuf_instr_o = abs_progbuf3_ff;
+            3'h4: dm2pipe_pbuf_instr_o = abs_progbuf4_ff;
+            3'h5: dm2pipe_pbuf_instr_o = abs_progbuf5_ff;
+            default: ;
+        endcase
+    end else if (pipe2dm_pbuf_addr_i == 3'b0) begin
+        dm2pipe_pbuf_instr_o = abs_exec_instr_ff;
+    end
+end
+
+//------------------------------------------------------------------------------
+// Debug Hart Interface : abstract command data
+//------------------------------------------------------------------------------
+
+assign dm2pipe_dreg_resp_o  = 1'b1;
+assign dm2pipe_dreg_fail_o  = 1'b0;
+assign dm2pipe_dreg_rdata_o = abs_fsm_use_addr ? abs_data1_ff : abs_data0_ff;
+
+`ifdef SCR1_TRGT_SIMULATION
+//------------------------------------------------------------------------------
+// Assertions
+//------------------------------------------------------------------------------
+
+SVA_DM_X_CONTROL : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({dmi2dm_req_i, pipe2dm_dreg_req_i, pipe2dm_cmd_resp_i,
+                 pipe2dm_hart_event_i})
+) else $error("DM error: control signals is X - %0b", {dmi2dm_req_i,
+              pipe2dm_dreg_req_i, pipe2dm_cmd_resp_i, pipe2dm_hart_event_i});
+
+SVA_DM_X_DMI : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    dmi2dm_req_i |-> !$isunknown({dmi2dm_wr_i, dmi2dm_addr_i, dmi2dm_wdata_i})
+) else $error("DM error: data signals is X on dmi");
+
+SVA_DM_X_HART_PBUF : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown (pipe2dm_pbuf_addr_i)
+) else $error("DM error: data signals is X on hart_pbuf");
+
+SVA_DM_X_HART_DREG : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    pipe2dm_dreg_req_i |-> !$isunknown({pipe2dm_dreg_wr_i, pipe2dm_dreg_wdata_i})
+) else $error("DM error: data signals is X on hart_dreg");
+
+SVA_DM_X_HART_CMD : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    pipe2dm_cmd_resp_i |-> !$isunknown({pipe2dm_cmd_rcode_i})
+) else $error("DM error: data signals is X on dm2pipe_cmd_o");
+
+SVA_DM_X_HART_EVENT : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    pipe2dm_hart_event_i |-> !$isunknown(pipe2dm_hart_status_i)
+) else $error("DM error: data signals is X on pipe2dm_hart_event_i");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_dm
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_dmi.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_dmi.sv
new file mode 100644
index 0000000..ba62c2a
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_dmi.sv
@@ -0,0 +1,182 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_dmi.sv>
+/// @brief      Debug Module Interface (DMI)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Provides TAPC with access to Debug Module (DM) and DTMCS
+ //
+ // Structure:
+ // - DMI <-> TAP interface
+ // - DMI <-> DM interface
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_dm.svh"
+
+module scr1_dmi (
+    // System
+    input  logic                                    rst_n,                      // DMI unit reset
+    input  logic                                    clk,                        // DMI unit clock
+
+    // TAP interface
+    input  logic                                    tapcsync2dmi_ch_sel_i,      // Debug Transport Module Chain Select
+    input  logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]     tapcsync2dmi_ch_id_i,       // Debug Transport Module Chain ID
+    input  logic                                    tapcsync2dmi_ch_capture_i,  // Debug Transport Module Chain Capture
+    input  logic                                    tapcsync2dmi_ch_shift_i,    // Debug Transport Module Chain Shift
+    input  logic                                    tapcsync2dmi_ch_update_i,   // Debug Transport Module Chain Update
+    input  logic                                    tapcsync2dmi_ch_tdi_i,      // Debug Transport Module Chain TDI
+    output logic                                    dmi2tapcsync_ch_tdo_o,      // Debug Transport Module Chain TDO
+
+    // DM interface
+    input logic                                     dm2dmi_resp_i,              // DMI response
+    input logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]       dm2dmi_rdata_i,             // DMI read data
+    output logic                                    dmi2dm_req_o,               // DMI request
+    output logic                                    dmi2dm_wr_o,                // DMI write
+    output logic [SCR1_DBG_DMI_ADDR_WIDTH-1:0]      dmi2dm_addr_o,              // DMI address
+    output logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]      dmi2dm_wdata_o              // DMI write data
+);
+
+//------------------------------------------------------------------------------
+// Local parameters declaration
+//------------------------------------------------------------------------------
+
+// Debug Transport Module Status parameters
+//------------------------------------------------------------------------------
+
+localparam    DTMCS_RESERVEDB_HI = 5'd31;
+localparam    DTMCS_RESERVEDB_LO = 5'd18;
+localparam    DTMCS_DMIHARDRESET = 5'd17;
+localparam    DTMCS_DMIRESET     = 5'd16;
+localparam    DTMCS_RESERVEDA    = 5'd15;
+localparam    DTMCS_IDLE_HI      = 5'd14;
+localparam    DTMCS_IDLE_LO      = 5'd12;
+localparam    DTMCS_DMISTAT_HI   = 5'd11;
+localparam    DTMCS_DMISTAT_LO   = 5'd10;
+localparam    DTMCS_ABITS_HI     = 5'd9;
+localparam    DTMCS_ABITS_LO     = 5'd4;
+localparam    DTMCS_VERSION_HI   = 5'd3;
+localparam    DTMCS_VERSION_LO   = 5'd0;
+
+// Debug Module Interface parameters
+//------------------------------------------------------------------------------
+
+localparam    DMI_OP_LO   = 5'd0;
+localparam    DMI_OP_HI   = DMI_OP_LO   + SCR1_DBG_DMI_OP_WIDTH   - 1;
+localparam    DMI_DATA_LO = DMI_OP_HI   + 1;
+localparam    DMI_DATA_HI = DMI_DATA_LO + SCR1_DBG_DMI_DATA_WIDTH - 1;
+localparam    DMI_ADDR_LO = DMI_DATA_HI + 1;
+localparam    DMI_ADDR_HI = DMI_ADDR_LO + SCR1_DBG_DMI_ADDR_WIDTH - 1;
+
+//------------------------------------------------------------------------------
+// Local signals declaration
+//------------------------------------------------------------------------------
+
+// TAP data register
+logic                                               tap_dr_upd;
+logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0]        tap_dr_ff;
+logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0]        tap_dr_shift;
+logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0]        tap_dr_rdata;
+logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0]        tap_dr_next;
+
+// DM read data register
+logic                                               dm_rdata_upd;
+logic [SCR1_DBG_DMI_DATA_WIDTH-1:0]                 dm_rdata_ff;
+
+logic                                               tapc_dmi_access_req;
+logic                                               tapc_dtmcs_sel;
+
+//------------------------------------------------------------------------------
+// DMI <-> TAP interface
+//------------------------------------------------------------------------------
+
+// TAPC read data multiplexer
+//------------------------------------------------------------------------------
+
+assign tapc_dtmcs_sel = (tapcsync2dmi_ch_id_i == 1'd1);
+
+// DMI operation is always successful in the current implementation
+always_comb begin
+    tap_dr_rdata = '0;
+
+    if(tapc_dtmcs_sel) begin
+        tap_dr_rdata[DTMCS_RESERVEDB_HI:DTMCS_RESERVEDB_LO] = 'b0;
+        tap_dr_rdata[DTMCS_DMIHARDRESET]                    = 'b0;
+        tap_dr_rdata[DTMCS_DMIRESET]                        = 'b0;
+        tap_dr_rdata[DTMCS_RESERVEDA]                       = 'b0;
+        tap_dr_rdata[DTMCS_IDLE_HI:DTMCS_IDLE_LO]           = 'b0;
+        tap_dr_rdata[DTMCS_DMISTAT_HI:DTMCS_DMISTAT_LO]     = 'b0;
+        tap_dr_rdata[DTMCS_ABITS_HI  :DTMCS_ABITS_LO]       = SCR1_DBG_DMI_ADDR_WIDTH;
+        tap_dr_rdata[DTMCS_VERSION_LO]                      = 1'b1;
+    end else begin
+        tap_dr_rdata[DMI_ADDR_HI:DMI_ADDR_LO]               = 'b0;
+        tap_dr_rdata[DMI_DATA_HI:DMI_DATA_LO]               = dm_rdata_ff;
+        tap_dr_rdata[DMI_OP_HI  :DMI_OP_LO]                 = 'b0;
+    end
+end
+
+assign tap_dr_shift = tapc_dtmcs_sel
+                    ? {9'b0, tapcsync2dmi_ch_tdi_i, tap_dr_ff[SCR1_DBG_DMI_DR_DTMCS_WIDTH-1:1]}
+                    : {tapcsync2dmi_ch_tdi_i, tap_dr_ff[SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:1]};
+
+// TAP data register
+//------------------------------------------------------------------------------
+
+assign tap_dr_upd = tapcsync2dmi_ch_capture_i | tapcsync2dmi_ch_shift_i;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        tap_dr_ff <= '0;
+    end else if(tap_dr_upd) begin
+        tap_dr_ff <= tap_dr_next;
+    end
+end
+
+assign tap_dr_next = tapcsync2dmi_ch_capture_i ? tap_dr_rdata
+                   : tapcsync2dmi_ch_shift_i   ? tap_dr_shift
+                                               : tap_dr_ff;
+
+assign dmi2tapcsync_ch_tdo_o = tap_dr_ff[0];
+
+//------------------------------------------------------------------------------
+// DMI <-> DM interface
+//------------------------------------------------------------------------------
+
+assign tapc_dmi_access_req = tapcsync2dmi_ch_update_i & tapcsync2dmi_ch_sel_i
+                           & (tapcsync2dmi_ch_id_i == 2'd2);
+
+always_comb begin
+    dmi2dm_req_o           = 1'b0;
+    dmi2dm_wr_o            = 1'b0;
+    dmi2dm_addr_o          = 1'b0;
+    dmi2dm_wdata_o         = 1'b0;
+
+    if(tapc_dmi_access_req) begin
+        dmi2dm_req_o   = tap_dr_ff[DMI_OP_HI  :DMI_OP_LO] != 2'b00;
+        dmi2dm_wr_o    = tap_dr_ff[DMI_OP_HI  :DMI_OP_LO] == 2'b10;
+        dmi2dm_addr_o  = tap_dr_ff[DMI_ADDR_HI:DMI_ADDR_LO];
+        dmi2dm_wdata_o = tap_dr_ff[DMI_DATA_HI:DMI_DATA_LO];
+    end
+end
+
+// DM read data register
+//------------------------------------------------------------------------------
+
+assign dm_rdata_upd = dmi2dm_req_o & dm2dmi_resp_i & ~dmi2dm_wr_o;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        dm_rdata_ff <= '0;
+    end else if (dm_rdata_upd) begin
+        dm_rdata_ff <= dm2dmi_rdata_i;
+    end
+end
+
+endmodule : scr1_dmi
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_scu.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_scu.sv
new file mode 100644
index 0000000..7f44ee6
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_scu.sv
@@ -0,0 +1,516 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file <scr1_scu.sv>
+/// @brief System Control Unit (SCU)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Generates System, Core, HDU and DM resets and their qualifier signals
+ // - Provides debugger with software System and Core resets generation functionality
+ // - Allows to set the behavior of DM and HDU resets
+ // - Shows resets Statuses and Sticky Statuses
+
+ // Structure:
+ // - TAPC scan-chain interface
+ // - SCU CSRs write/read interface
+ // - SCU CSRS:
+ //   - CONTROL register
+ //   - MODE register
+ //   - STATUS register
+ //   - STICKY_STATUS register
+ // - Reset logic
+ //   - System Reset
+ //   - Core Reset
+ //   - DM Reset
+ //   - HDU Reset
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+`include "scr1_scu.svh"
+
+`ifdef SCR1_DBG_EN
+
+module scr1_scu (
+    // Global signals
+    input  logic        pwrup_rst_n,                  // Power-Up Reset
+    input  logic        rst_n,                        // Regular Reset
+    input  logic        cpu_rst_n,                    // CPU Reset
+    input  logic        test_mode,                    // DFT Test Mode
+    input  logic        test_rst_n,                   // DFT Test Reset
+    input  logic        clk,                          // SCU clock
+
+    // TAPC scan-chains
+    input  logic        tapcsync2scu_ch_sel_i,        // TAPC Chain Select
+    input  logic        tapcsync2scu_ch_id_i,         // TAPC Chain ID
+    input  logic        tapcsync2scu_ch_capture_i,    // TAPC Chain Capture
+    input  logic        tapcsync2scu_ch_shift_i,      // TAPC Chain Shift
+    input  logic        tapcsync2scu_ch_update_i,     // TAPC Chain Update
+    input  logic        tapcsync2scu_ch_tdi_i,        // TAPC Chain TDI
+    output logic        scu2tapcsync_ch_tdo_o,        // TAPC Chain TDO
+
+    // Input sync resets:
+    input  logic        ndm_rst_n_i,                  // Non-DM Reset input from DM
+    input  logic        hart_rst_n_i,                 // HART Reset from DM
+
+    // Generated resets
+    output logic        sys_rst_n_o,                  // System/Cluster Reset
+    output logic        core_rst_n_o,                 // Core Reset
+    output logic        dm_rst_n_o,                   // Debug Module Reset
+    output logic        hdu_rst_n_o,                  // HART Debug Unit Reset
+
+    // Resets statuses
+    output logic        sys_rst_status_o,             // System Reset Status (sync'ed to POR reset domain)
+    output logic        core_rst_status_o,            // Core Reset Status (sync'ed to POR reset domain)
+
+    // Reset Domain Crossing (RDC) qualifiers
+    output logic        sys_rdc_qlfy_o,               // System/Cluster-to-ExternalSOC Reset Domain Crossing Qualifier
+    output logic        core_rdc_qlfy_o,              // Core-to-ExternalSOC Reset Domain Crossing Qualifier
+    output logic        core2hdu_rdc_qlfy_o,          // Core-to-HDU Reset Domain Crossing Qualifier
+    output logic        core2dm_rdc_qlfy_o,           // Core-to-DM Reset Domain Crossing Qualifier
+    output logic        hdu2dm_rdc_qlfy_o             // HDU-to-DM Reset Domain Crossing Qualifier
+);
+
+//------------------------------------------------------------------------------
+// Local Parameters
+//======================================================================================================================
+localparam int unsigned SCR1_SCU_RST_SYNC_STAGES_NUM        = 2;
+
+//------------------------------------------------------------------------------
+// Local Signals
+//------------------------------------------------------------------------------
+
+// SCU CSR write/read i/f
+//------------------------------------------------------------------------------
+
+// TAPC scan-chain control logic
+logic                                       scu_csr_req;
+logic                                       tapc_dr_cap_req;
+logic                                       tapc_dr_shft_req;
+logic                                       tapc_dr_upd_req;
+
+// TAPC shift register signals
+logic                                       tapc_shift_upd;
+type_scr1_scu_sysctrl_dr_s                  tapc_shift_ff;
+type_scr1_scu_sysctrl_dr_s                  tapc_shift_next;
+
+// TAPC shadow register signals
+type_scr1_scu_sysctrl_dr_s                  tapc_shadow_ff;
+
+// SCU CSR write/read i/f
+//------------------------------------------------------------------------------
+
+logic [SCR1_SCU_DR_SYSCTRL_DATA_WIDTH-1:0]  scu_csr_wdata;
+logic [SCR1_SCU_DR_SYSCTRL_DATA_WIDTH-1:0]  scu_csr_rdata;
+
+// SCU CSRs signals
+//------------------------------------------------------------------------------
+
+// Control register
+type_scr1_scu_sysctrl_control_reg_s         scu_control_ff;
+logic                                       scu_control_wr_req;
+
+// Mode register
+type_scr1_scu_sysctrl_mode_reg_s            scu_mode_ff;
+logic                                       scu_mode_wr_req;
+
+// Status register
+type_scr1_scu_sysctrl_status_reg_s          scu_status_ff;
+type_scr1_scu_sysctrl_status_reg_s          scu_status_ff_dly;
+type_scr1_scu_sysctrl_status_reg_s          scu_status_ff_posedge;
+
+// Sticky Status register
+type_scr1_scu_sysctrl_status_reg_s          scu_sticky_sts_ff;
+logic                                       scu_sticky_sts_wr_req;
+
+// Reset logic signals
+//------------------------------------------------------------------------------
+
+// Input resets synchronization signals
+logic                                       pwrup_rst_n_sync;
+logic                                       rst_n_sync;
+logic                                       cpu_rst_n_sync;
+
+// System Reset signals
+logic                                       sys_rst_n_in;
+logic                                       sys_rst_n_status;
+logic                                       sys_rst_n_status_sync;
+logic                                       sys_rst_n_qlfy;
+logic                                       sys_reset_n;
+
+// Core Reset signals
+logic                                       core_rst_n_in_sync;
+logic                                       core_rst_n_status;
+logic                                       core_rst_n_status_sync;
+logic                                       core_rst_n_qlfy;
+logic                                       core_reset_n;
+
+// HDU Reset signals
+logic                                       hdu_rst_n_in_sync;
+logic                                       hdu_rst_n_status;
+logic                                       hdu_rst_n_status_sync;
+logic                                       hdu_rst_n_qlfy;
+
+// DM Reset signals
+logic                                       dm_rst_n_in;
+logic                                       dm_rst_n_status;
+
+//------------------------------------------------------------------------------
+// TAPC scan-chain i/f
+//------------------------------------------------------------------------------
+//
+ // Consists of the following functional units:
+ // - TAPC scan-chain control logic
+ // - TAPC shift register
+ // - TAPC shadow register
+//
+
+// TAPC scan-chain control logic
+//------------------------------------------------------------------------------
+
+assign scu_csr_req      = tapcsync2scu_ch_sel_i & (tapcsync2scu_ch_id_i == '0);
+assign tapc_dr_cap_req  = scu_csr_req & tapcsync2scu_ch_capture_i;
+assign tapc_dr_shft_req = scu_csr_req & tapcsync2scu_ch_shift_i;
+assign tapc_dr_upd_req  = scu_csr_req & tapcsync2scu_ch_update_i;
+
+// TAPC shift register
+//------------------------------------------------------------------------------
+
+assign tapc_shift_upd = tapc_dr_cap_req | tapc_dr_shft_req;
+
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        tapc_shift_ff <= '0;
+    end else if (tapc_shift_upd) begin
+        tapc_shift_ff <= tapc_shift_next;
+    end
+end
+
+assign tapc_shift_next = tapc_dr_cap_req  ? tapc_shadow_ff
+                       : tapc_dr_shft_req ? {tapcsync2scu_ch_tdi_i, tapc_shift_ff[$bits(type_scr1_scu_sysctrl_dr_s)-1:1]}
+                                          : tapc_shift_ff;
+
+// TAPC shadow register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        tapc_shadow_ff      <= '0;
+    end else if (tapc_dr_upd_req) begin
+        tapc_shadow_ff.op   <= tapc_shift_ff.op;
+        tapc_shadow_ff.addr <= tapc_shift_ff.addr;
+        tapc_shadow_ff.data <= scu_csr_wdata;
+    end
+end
+
+assign scu2tapcsync_ch_tdo_o = tapc_shift_ff[0];
+
+//------------------------------------------------------------------------------
+// SCU CSRs write/read interface
+//------------------------------------------------------------------------------
+
+// Write interface
+//------------------------------------------------------------------------------
+
+// Register selection logic
+always_comb begin
+    scu_control_wr_req    = 1'b0;
+    scu_mode_wr_req       = 1'b0;
+    scu_sticky_sts_wr_req = 1'b0;
+
+    if (tapc_dr_upd_req && (tapc_shift_ff.op != SCR1_SCU_SYSCTRL_OP_READ)) begin
+        case (tapc_shift_ff.addr)
+            SCR1_SCU_SYSCTRL_ADDR_CONTROL: scu_control_wr_req    = 1'b1;
+            SCR1_SCU_SYSCTRL_ADDR_MODE   : scu_mode_wr_req       = 1'b1;
+            SCR1_SCU_SYSCTRL_ADDR_STICKY : scu_sticky_sts_wr_req = (tapc_shift_ff.op == SCR1_SCU_SYSCTRL_OP_CLRBITS);
+            default                      : begin end
+        endcase
+    end
+end
+
+// Write data construction
+always_comb begin
+    scu_csr_wdata = '0;
+
+    if (tapc_dr_upd_req) begin
+        case (tapc_shift_ff.op)
+            SCR1_SCU_SYSCTRL_OP_WRITE  : scu_csr_wdata = tapc_shift_ff.data;
+            SCR1_SCU_SYSCTRL_OP_READ   : scu_csr_wdata = scu_csr_rdata;
+            SCR1_SCU_SYSCTRL_OP_SETBITS: scu_csr_wdata = scu_csr_rdata |   tapc_shift_ff.data;
+            SCR1_SCU_SYSCTRL_OP_CLRBITS: scu_csr_wdata = scu_csr_rdata & (~tapc_shift_ff.data);
+            default                    : begin end
+        endcase
+    end
+end
+
+// Read interface
+//------------------------------------------------------------------------------
+
+// Read data multiplexer
+always_comb begin
+    scu_csr_rdata = '0;
+
+    if (tapc_dr_upd_req) begin
+        case (tapc_shift_ff.addr)
+            SCR1_SCU_SYSCTRL_ADDR_CONTROL: scu_csr_rdata = scu_control_ff;
+            SCR1_SCU_SYSCTRL_ADDR_MODE   : scu_csr_rdata = scu_mode_ff;
+            SCR1_SCU_SYSCTRL_ADDR_STATUS : scu_csr_rdata = scu_status_ff;
+            SCR1_SCU_SYSCTRL_ADDR_STICKY : scu_csr_rdata = scu_sticky_sts_ff;
+            default                      : scu_csr_rdata = 'x;
+        endcase
+    end
+end
+
+//------------------------------------------------------------------------------
+// SCU CSRs
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - CONTROL register
+ // - MODE register
+ // - STATUS register
+ // - STICKY_STATUS register
+//
+
+// CONTROL register
+//------------------------------------------------------------------------------
+// Allows debugger to generate System and Core resets
+
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        scu_control_ff <= '0;
+    end else if (scu_control_wr_req) begin
+        scu_control_ff <= scu_csr_wdata;
+    end
+end
+
+// MODE register
+//------------------------------------------------------------------------------
+// Sets reset behavior for DM Reset and HDU Reset signals
+
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        scu_mode_ff <= '0;
+    end else if (scu_mode_wr_req) begin
+        scu_mode_ff <= scu_csr_wdata;
+    end
+end
+
+// STATUS register
+//------------------------------------------------------------------------------
+// Holds the status of every output reset signal (System, Core, DM and HDU)
+
+assign scu_status_ff.sys_reset  = sys_rst_status_o ;
+assign scu_status_ff.core_reset = core_rst_status_o;
+assign scu_status_ff.dm_reset   = ~dm_rst_n_status;
+assign scu_status_ff.hdu_reset  = ~hdu_rst_n_status_sync;
+
+// Status Register positive edge detection logic
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        scu_status_ff_dly <= '0;
+    end else begin
+        scu_status_ff_dly <= scu_status_ff;
+    end
+end
+
+assign scu_status_ff_posedge = scu_status_ff & ~scu_status_ff_dly;
+
+// STICKY_STATUS register
+//------------------------------------------------------------------------------
+// For every output reset signal shows if it was asserted since the last bit clearing
+
+always_ff @(posedge clk, negedge pwrup_rst_n_sync) begin
+    if (~pwrup_rst_n_sync) begin
+        scu_sticky_sts_ff <= '0;
+    end else begin
+        for (int unsigned i = 0; i < $bits(type_scr1_scu_sysctrl_status_reg_s); ++i) begin
+            if (scu_status_ff_posedge[i]) begin
+                scu_sticky_sts_ff[i] <= 1'b1;
+            end else if (scu_sticky_sts_wr_req) begin
+                scu_sticky_sts_ff[i] <= scu_csr_wdata[i];
+            end
+        end
+    end
+end
+
+//------------------------------------------------------------------------------
+// Reset logic
+//------------------------------------------------------------------------------
+//
+ // Consists of the following functional units:
+ // - System Reset logic
+ // - Core Reset logic
+ // - Hart Debug Unit Reset logic
+ // - Debug Module Reset logic
+//
+
+// Reset inputs are assumed synchronous
+assign pwrup_rst_n_sync = pwrup_rst_n;
+assign rst_n_sync       = rst_n;
+assign cpu_rst_n_sync   = cpu_rst_n;
+
+// Intermediate resets:
+assign sys_reset_n  = ~scu_control_ff.sys_reset;
+assign core_reset_n = ~scu_control_ff.core_reset;
+
+// System/Cluster Reset: sys_rst_n_o
+//------------------------------------------------------------------------------
+
+scr1_reset_qlfy_adapter_cell_sync   i_sys_rstn_qlfy_adapter_cell_sync (
+    .rst_n                          (pwrup_rst_n_sync),
+    .clk                            (clk             ),
+    .test_rst_n                     (test_rst_n      ),
+    .test_mode                      (test_mode       ),
+    .reset_n_in_sync                (sys_rst_n_in    ),
+    .reset_n_out_qlfy               (sys_rst_n_qlfy  ),
+    .reset_n_out                    (sys_rst_n_o     ),
+    .reset_n_status                 (sys_rst_n_status)
+);
+
+assign sys_rst_n_in = sys_reset_n & ndm_rst_n_i & rst_n_sync;
+
+scr1_data_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_SCU_RST_SYNC_STAGES_NUM)
+) i_sys_rstn_status_sync (
+    .rst_n               (pwrup_rst_n_sync     ),
+    .clk                 (clk                  ),
+    .data_in             (sys_rst_n_status     ),
+    .data_out            (sys_rst_n_status_sync)
+);
+
+assign sys_rst_status_o = ~sys_rst_n_status_sync;
+
+// System/Cluster-to-ExternalSOC RDC qualifier
+assign sys_rdc_qlfy_o = sys_rst_n_qlfy;
+
+// Core Reset: core_rst_n_o
+//------------------------------------------------------------------------------
+
+scr1_reset_qlfy_adapter_cell_sync   i_core_rstn_qlfy_adapter_cell_sync (
+    .rst_n                          (pwrup_rst_n_sync  ),
+    .clk                            (clk               ),
+    .test_rst_n                     (test_rst_n        ),
+    .test_mode                      (test_mode         ),
+    .reset_n_in_sync                (core_rst_n_in_sync),
+    .reset_n_out_qlfy               (core_rst_n_qlfy   ),
+    .reset_n_out                    (core_rst_n_o      ),
+    .reset_n_status                 (core_rst_n_status )
+);
+
+assign core_rst_n_in_sync   = sys_rst_n_in & hart_rst_n_i & core_reset_n & cpu_rst_n_sync;
+
+scr1_data_sync_cell #(
+    .STAGES_AMOUNT        (SCR1_SCU_RST_SYNC_STAGES_NUM)
+) i_core_rstn_status_sync (
+    .rst_n                (pwrup_rst_n_sync      ),
+    .clk                  (clk                   ),
+    .data_in              (core_rst_n_status     ),
+    .data_out             (core_rst_n_status_sync)
+);
+
+assign core_rst_status_o = ~core_rst_n_status_sync;
+
+// Core Reset RDC Qualifiers:
+//  - Core-to-ExternalSOC RDC Qlfy
+assign core_rdc_qlfy_o = core_rst_n_qlfy;
+//  - Core-to-HDU RDC Qlfy
+assign core2hdu_rdc_qlfy_o = core_rst_n_qlfy;
+//  - Core-to-DebugModule RDC Qlfy
+assign core2dm_rdc_qlfy_o  = core_rst_n_qlfy;
+
+// Hart Debug Unit Reset: hdu_rst_n_o
+//------------------------------------------------------------------------------
+
+scr1_reset_qlfy_adapter_cell_sync   i_hdu_rstn_qlfy_adapter_cell_sync (
+    .rst_n                          (pwrup_rst_n_sync ),
+    .clk                            (clk              ),
+    .test_rst_n                     (test_rst_n       ),
+    .test_mode                      (test_mode        ),
+    .reset_n_in_sync                (hdu_rst_n_in_sync),
+    .reset_n_out_qlfy               (hdu_rst_n_qlfy   ),
+    .reset_n_out                    (hdu_rst_n_o      ),
+    .reset_n_status                 (hdu_rst_n_status )
+);
+
+assign hdu_rst_n_in_sync = scu_mode_ff.hdu_rst_bhv | core_rst_n_in_sync;
+
+scr1_data_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_SCU_RST_SYNC_STAGES_NUM)
+) i_hdu_rstn_status_sync (
+    .rst_n               (pwrup_rst_n_sync     ),
+    .clk                 (clk                  ),
+    .data_in             (hdu_rst_n_status     ),
+    .data_out            (hdu_rst_n_status_sync)
+);
+
+// Hart Debug Unit Reset RDC Qualifiers:
+//  - HDU-to-DebugModule RDC Qlfy
+assign hdu2dm_rdc_qlfy_o = hdu_rst_n_qlfy;
+
+// Debug Module Reset: dm_rst_n_o
+//------------------------------------------------------------------------------
+
+scr1_reset_buf_cell i_dm_rstn_buf_cell (
+    .rst_n              (pwrup_rst_n_sync),
+    .clk                (clk             ),
+    .test_mode          (test_mode       ),
+    .test_rst_n         (test_rst_n      ),
+    .reset_n_in         (dm_rst_n_in     ),
+    .reset_n_out        (dm_rst_n_o      ),
+    .reset_n_status     (dm_rst_n_status )
+);
+
+assign dm_rst_n_in  = ~scu_mode_ff.dm_rst_bhv | sys_reset_n;
+
+`ifdef SCR1_TRGT_SIMULATION
+//--------------------------------------------------------------------
+// Assertions
+//--------------------------------------------------------------------
+
+`ifndef VERILATOR
+// Preventing some assertions to be raised at 0 sim time or in the first cycle
+initial begin
+$assertoff(0, scr1_scu);
+repeat (2) @(posedge clk);
+$asserton(0, scr1_scu);
+end
+`endif // VERILATOR
+
+// X checks
+SCR1_SVA_SCU_RESETS_XCHECK : assert property (
+    @(negedge clk)
+    !$isunknown({pwrup_rst_n, rst_n, cpu_rst_n, ndm_rst_n_i, hart_rst_n_i})
+) else $error("SCU resets error: unknown values of input resets");
+
+// Qualifiers checks
+SCR1_SVA_SCU_SYS2SOC_QLFY_CHECK : assert property (
+    @(negedge clk) disable iff (~pwrup_rst_n)
+    $fell(sys_rst_n_o) |-> $fell($past(sys_rdc_qlfy_o))
+) else $error("SCU sys2soc qlfy error: qlfy wasn't raised prior to reset");
+
+SCR1_SVA_SCU_CORE2SOC_QLFY_CHECK : assert property (
+    @(negedge clk) disable iff (~pwrup_rst_n)
+    $fell(core_rst_n_o) |-> $fell($past(core_rdc_qlfy_o))
+) else $error("SCU core2soc qlfy error: qlfy wasn't raised prior to reset");
+
+SCR1_SVA_SCU_CORE2HDU_QLFY_CHECK : assert property (
+    @(negedge clk) disable iff (~pwrup_rst_n)
+    $fell(core_rst_n_o) |-> $fell($past(core2hdu_rdc_qlfy_o))
+) else $error("SCU core2hdu qlfy error: qlfy wasn't raised prior to reset");
+
+SCR1_SVA_SCU_CORE2DM_QLFY_CHECK : assert property (
+    @(negedge clk) disable iff (~pwrup_rst_n)
+    $fell(core_rst_n_o) |-> $fell($past(core2dm_rdc_qlfy_o))
+) else $error("SCU core2dm qlfy error: qlfy wasn't raised prior to reset");
+
+SCR1_SVA_SCU_HDU2DM_QLFY_CHECK : assert property (
+    @(negedge clk) disable iff (~pwrup_rst_n)
+    $fell(hdu_rst_n_o) |-> $fell($past(hdu2dm_rdc_qlfy_o))
+) else $error("SCU hdu2dm qlfy error: qlfy wasn't raised prior to reset");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_scu
+`endif // SCR1_DBG_EN
+
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_tapc.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc.sv
new file mode 100644
index 0000000..45687f4
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc.sv
@@ -0,0 +1,457 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_tapc.sv>
+/// @brief      TAP Controller (TAPC)
+///
+
+//------------------------------------------------------------------------------
+ //
+ // Functionality:
+ // - Controls TAP operation
+ // - Allows debugger to access TAP Data registers and DMI/SCU scan-chains via
+ //   command written in Instruction register
+ //
+ // Structure:
+ // - Synchronous reset generation
+ // - TAPC FSM
+ // - TAPC Instruction Registers
+ // - TAPC DRs/DMI/SCU scan-chains
+ // - TAPC TDO enable and output Registers
+ // - TAPC Data Registers
+ //   - BYPASS
+ //   - IDCODE
+ //   - BUILD ID
+ //
+//------------------------------------------------------------------------------
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_tapc.svh"
+`include "scr1_dm.svh"
+
+module scr1_tapc (
+    // JTAG signals
+    input   logic                                   tapc_trst_n,                    // Test Reset (TRSTn)
+    input   logic                                   tapc_tck,                       // Test Clock (TCK)
+    input   logic                                   tapc_tms,                       // Test Mode Select (TMS)
+    input   logic                                   tapc_tdi,                       // Test Data Input (TDI)
+    output  logic                                   tapc_tdo,                       // Test Data Output (TDO)
+    output  logic                                   tapc_tdo_en,                    // TDO Enable, signal for TDO buffer control
+
+    // Fuses:
+    input   logic [31:0]                            soc2tapc_fuse_idcode_i,         // IDCODE value from fuses
+
+    // DMI/SCU scan-chains
+    output  logic                                   tapc2tapcsync_scu_ch_sel_o,     // SCU Chain Select
+    output  logic                                   tapc2tapcsync_dmi_ch_sel_o,     // DMI Chain Select
+    output  logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]    tapc2tapcsync_ch_id_o,          // DMI/SCU Chain Identifier
+    output  logic                                   tapc2tapcsync_ch_capture_o,     // DMI/SCU Chain Capture
+    output  logic                                   tapc2tapcsync_ch_shift_o,       // DMI/SCU Chain Shift
+    output  logic                                   tapc2tapcsync_ch_update_o,      // DMI/SCU Chain Update
+    output  logic                                   tapc2tapcsync_ch_tdi_o,         // DMI/SCU Chain TDI
+    input   logic                                   tapcsync2tapc_ch_tdo_i          // DMI/SCU Chain TDO
+);
+
+//------------------------------------------------------------------------------
+// Local Signals
+//------------------------------------------------------------------------------
+
+logic                                       trst_n_int;       // Sync reset signal
+
+// TAPC FSM signals
+//------------------------------------------------------------------------------
+
+type_scr1_tap_state_e                       tap_fsm_ff;       // TAP's current state
+type_scr1_tap_state_e                       tap_fsm_next;     // TAP's next state
+
+// Control signals
+logic                                       tap_fsm_reset;
+logic                                       tap_fsm_ir_upd;
+logic                                       tap_fsm_ir_cap;
+logic                                       tap_fsm_ir_shft;
+
+// Registered control signals
+logic                                       tap_fsm_ir_shift_ff;
+logic                                       tap_fsm_ir_shift_next;
+logic                                       tap_fsm_dr_capture_ff;
+logic                                       tap_fsm_dr_capture_next;
+logic                                       tap_fsm_dr_shift_ff;
+logic                                       tap_fsm_dr_shift_next;
+logic                                       tap_fsm_dr_update_ff;
+logic                                       tap_fsm_dr_update_next;
+
+// TAPC Instruction Registers signals
+//------------------------------------------------------------------------------
+
+logic [SCR1_TAP_INSTRUCTION_WIDTH-1:0]      tap_ir_shift_ff;   // Instruction Shift Register
+logic [SCR1_TAP_INSTRUCTION_WIDTH-1:0]      tap_ir_shift_next; // Instruction Shift Register next value
+logic [SCR1_TAP_INSTRUCTION_WIDTH-1:0]      tap_ir_ff;         // Instruction Register
+logic [SCR1_TAP_INSTRUCTION_WIDTH-1:0]      tap_ir_next;       // Instruction Register next value
+
+// TAPC Data Registers signals
+//------------------------------------------------------------------------------
+
+// BYPASS register
+logic                                       dr_bypass_sel;
+logic                                       dr_bypass_tdo;
+
+// IDCODE register
+logic                                       dr_idcode_sel;
+logic                                       dr_idcode_tdo;
+
+// BUILD ID register
+logic                                       dr_bld_id_sel;
+logic                                       dr_bld_id_tdo;
+
+logic                                       dr_out;
+
+// TDO registers
+//------------------------------------------------------------------------------
+
+// TDO enable register
+logic                                       tdo_en_ff;
+logic                                       tdo_en_next;
+
+// TDO output register
+logic                                       tdo_out_ff;
+logic                                       tdo_out_next;
+
+//------------------------------------------------------------------------------
+// TAPC Synchronous Reset logic
+//------------------------------------------------------------------------------
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        trst_n_int <= 1'b0;
+    end else begin
+        trst_n_int <= ~tap_fsm_reset;
+    end
+end
+
+//------------------------------------------------------------------------------
+// TAP's FSM
+//------------------------------------------------------------------------------
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_fsm_ff <= SCR1_TAP_STATE_RESET;
+    end else begin
+        tap_fsm_ff <= tap_fsm_next;
+    end
+end
+
+always_comb begin
+    case (tap_fsm_ff)
+        SCR1_TAP_STATE_RESET      : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_RESET        : SCR1_TAP_STATE_IDLE;
+        SCR1_TAP_STATE_IDLE       : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_SEL_SCAN  : SCR1_TAP_STATE_IDLE;
+        SCR1_TAP_STATE_DR_SEL_SCAN: tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_SEL_SCAN  : SCR1_TAP_STATE_DR_CAPTURE;
+        SCR1_TAP_STATE_DR_CAPTURE : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_EXIT1     : SCR1_TAP_STATE_DR_SHIFT;
+        SCR1_TAP_STATE_DR_SHIFT   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_EXIT1     : SCR1_TAP_STATE_DR_SHIFT;
+        SCR1_TAP_STATE_DR_EXIT1   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_UPDATE    : SCR1_TAP_STATE_DR_PAUSE;
+        SCR1_TAP_STATE_DR_PAUSE   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_EXIT2     : SCR1_TAP_STATE_DR_PAUSE;
+        SCR1_TAP_STATE_DR_EXIT2   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_UPDATE    : SCR1_TAP_STATE_DR_SHIFT;
+        SCR1_TAP_STATE_DR_UPDATE  : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_SEL_SCAN  : SCR1_TAP_STATE_IDLE;
+        SCR1_TAP_STATE_IR_SEL_SCAN: tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_RESET        : SCR1_TAP_STATE_IR_CAPTURE;
+        SCR1_TAP_STATE_IR_CAPTURE : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_EXIT1     : SCR1_TAP_STATE_IR_SHIFT;
+        SCR1_TAP_STATE_IR_SHIFT   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_EXIT1     : SCR1_TAP_STATE_IR_SHIFT;
+        SCR1_TAP_STATE_IR_EXIT1   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_UPDATE    : SCR1_TAP_STATE_IR_PAUSE;
+        SCR1_TAP_STATE_IR_PAUSE   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_EXIT2     : SCR1_TAP_STATE_IR_PAUSE;
+        SCR1_TAP_STATE_IR_EXIT2   : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_IR_UPDATE    : SCR1_TAP_STATE_IR_SHIFT;
+        SCR1_TAP_STATE_IR_UPDATE  : tap_fsm_next = tapc_tms ? SCR1_TAP_STATE_DR_SEL_SCAN  : SCR1_TAP_STATE_IDLE;
+`ifdef SCR1_XPROP_EN
+        default                   : tap_fsm_next = SCR1_TAP_STATE_XXX;
+`else // SCR1_XPROP_EN
+        default                   : tap_fsm_next = tap_fsm_ff;
+`endif // SCR1_XPROP_EN
+    endcase
+end
+
+assign tap_fsm_reset   = (tap_fsm_ff == SCR1_TAP_STATE_RESET);
+assign tap_fsm_ir_upd  = (tap_fsm_ff == SCR1_TAP_STATE_IR_UPDATE);
+assign tap_fsm_ir_cap  = (tap_fsm_ff == SCR1_TAP_STATE_IR_CAPTURE);
+assign tap_fsm_ir_shft = (tap_fsm_ff == SCR1_TAP_STATE_IR_SHIFT);
+
+//------------------------------------------------------------------------------
+// TAPC Instruction Registers
+//------------------------------------------------------------------------------
+
+// TAPC Instruction Shift register
+//------------------------------------------------------------------------------
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_ir_shift_ff <= '0;
+    end else if (~trst_n_int) begin
+        tap_ir_shift_ff <= '0;
+    end else begin
+        tap_ir_shift_ff <= tap_ir_shift_next;
+    end
+end
+
+assign tap_ir_shift_next = tap_fsm_ir_cap  ? {{($bits(tap_ir_shift_ff)-1){1'b0}}, 1'b1}
+                         : tap_fsm_ir_shft ? {tapc_tdi, tap_ir_shift_ff[$left(tap_ir_shift_ff):1]}
+                                           : tap_ir_shift_ff;
+
+// TAPC Instruction register
+//------------------------------------------------------------------------------
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_ir_ff <= SCR1_TAP_INSTR_IDCODE;
+    end else if (~trst_n_int) begin
+        tap_ir_ff <= SCR1_TAP_INSTR_IDCODE;
+    end else begin
+        tap_ir_ff <= tap_ir_next;
+    end
+end
+
+assign tap_ir_next = tap_fsm_ir_upd ? tap_ir_shift_ff : tap_ir_ff;
+
+//------------------------------------------------------------------------------
+// Control signals
+//------------------------------------------------------------------------------
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_fsm_ir_shift_ff <= 1'b0;
+    end else if (~trst_n_int) begin
+        tap_fsm_ir_shift_ff <= 1'b0;
+    end else begin
+        tap_fsm_ir_shift_ff <= tap_fsm_ir_shift_next;
+    end
+end
+
+assign tap_fsm_ir_shift_next = (tap_fsm_next == SCR1_TAP_STATE_IR_SHIFT);
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_fsm_dr_capture_ff <= 1'b0;
+    end else if (~trst_n_int) begin
+        tap_fsm_dr_capture_ff <= 1'b0;
+    end else begin
+        tap_fsm_dr_capture_ff <= tap_fsm_dr_capture_next;
+    end
+end
+
+assign tap_fsm_dr_capture_next = (tap_fsm_next == SCR1_TAP_STATE_DR_CAPTURE);
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_fsm_dr_shift_ff <= 1'b0;
+    end else if (~trst_n_int) begin
+        tap_fsm_dr_shift_ff <= 1'b0;
+    end else begin
+        tap_fsm_dr_shift_ff <= tap_fsm_dr_shift_next;
+    end
+end
+
+assign tap_fsm_dr_shift_next = (tap_fsm_next == SCR1_TAP_STATE_DR_SHIFT);
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tap_fsm_dr_update_ff <= 1'b0;
+    end else if (~trst_n_int) begin
+        tap_fsm_dr_update_ff <= 1'b0;
+    end else begin
+        tap_fsm_dr_update_ff <= tap_fsm_dr_update_next;
+    end
+end
+
+assign tap_fsm_dr_update_next = (tap_fsm_next == SCR1_TAP_STATE_DR_UPDATE);
+
+//------------------------------------------------------------------------------
+// TAPC DRs/DMI/SCU scan-chains
+//------------------------------------------------------------------------------
+//
+ // Consists of the following functional units:
+ // - Data source/destination decoder
+ // - DMI channel ID decoder
+
+// - Read data multiplexer
+// Data source/destination decoder
+//------------------------------------------------------------------------------
+
+always_comb begin
+    dr_bypass_sel               = 1'b0;
+    dr_idcode_sel               = 1'b0;
+    dr_bld_id_sel               = 1'b0;
+    tapc2tapcsync_scu_ch_sel_o  = 1'b0;
+    tapc2tapcsync_dmi_ch_sel_o  = 1'b0;
+    case (tap_ir_ff)
+        SCR1_TAP_INSTR_DTMCS     : tapc2tapcsync_dmi_ch_sel_o = 1'b1;
+        SCR1_TAP_INSTR_DMI_ACCESS: tapc2tapcsync_dmi_ch_sel_o = 1'b1;
+        SCR1_TAP_INSTR_IDCODE    : dr_idcode_sel              = 1'b1;
+        SCR1_TAP_INSTR_BYPASS    : dr_bypass_sel              = 1'b1;
+        SCR1_TAP_INSTR_BLD_ID    : dr_bld_id_sel              = 1'b1;
+        SCR1_TAP_INSTR_SCU_ACCESS: tapc2tapcsync_scu_ch_sel_o = 1'b1;
+        default                  : dr_bypass_sel              = 1'b1;
+    endcase
+end
+
+// DMI channel ID decoder
+//------------------------------------------------------------------------------
+
+always_comb begin
+    tapc2tapcsync_ch_id_o = '0;
+    case (tap_ir_ff)
+        SCR1_TAP_INSTR_DTMCS     : tapc2tapcsync_ch_id_o = 'd1;
+        SCR1_TAP_INSTR_DMI_ACCESS: tapc2tapcsync_ch_id_o = 'd2;
+        default                  : tapc2tapcsync_ch_id_o = '0;
+    endcase
+end
+
+// Read data multiplexer
+//------------------------------------------------------------------------------
+
+always_comb begin
+    dr_out = 1'b0;
+    case (tap_ir_ff)
+        SCR1_TAP_INSTR_DTMCS     : dr_out = tapcsync2tapc_ch_tdo_i;
+        SCR1_TAP_INSTR_DMI_ACCESS: dr_out = tapcsync2tapc_ch_tdo_i;
+        SCR1_TAP_INSTR_IDCODE    : dr_out = dr_idcode_tdo;
+        SCR1_TAP_INSTR_BYPASS    : dr_out = dr_bypass_tdo;
+        SCR1_TAP_INSTR_BLD_ID    : dr_out = dr_bld_id_tdo;
+        SCR1_TAP_INSTR_SCU_ACCESS: dr_out = tapcsync2tapc_ch_tdo_i;
+        default                  : dr_out = dr_bypass_tdo;
+    endcase
+end
+
+//------------------------------------------------------------------------------
+// TDO enable and output registers
+//------------------------------------------------------------------------------
+
+// TDO enable register
+//------------------------------------------------------------------------------
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tdo_en_ff  <= 1'b0;
+    end else if (~trst_n_int) begin
+        tdo_en_ff  <= 1'b0;
+    end else begin
+        tdo_en_ff  <= tdo_en_next;
+    end
+end
+
+assign tdo_en_next = tap_fsm_dr_shift_ff | tap_fsm_ir_shift_ff;
+
+// TDO output register
+//------------------------------------------------------------------------------
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tdo_out_ff <= 1'b0;
+    end else if (~trst_n_int) begin
+        tdo_out_ff <= 1'b0;
+    end else begin
+        tdo_out_ff <= tdo_out_next;
+    end
+end
+
+assign tdo_out_next = tap_fsm_dr_shift_ff ? dr_out
+                    : tap_fsm_ir_shift_ff ? tap_ir_shift_ff[0]
+                                          : 1'b0;
+
+// TAPC TDO signals
+assign tapc_tdo_en = tdo_en_ff;
+assign tapc_tdo    = tdo_out_ff;
+
+//------------------------------------------------------------------------------
+// TAPC Data Registers
+//------------------------------------------------------------------------------
+//
+ // Registers:
+ // - BYPASS register
+ // - IDCODE register
+ // - BUILD ID register
+
+// BYPASS register
+//------------------------------------------------------------------------------
+// 1-bit mandatory IEEE 1149.1 compliant register
+
+scr1_tapc_shift_reg  #(
+    .SCR1_WIDTH       (SCR1_TAP_DR_BYPASS_WIDTH),
+    .SCR1_RESET_VALUE (SCR1_TAP_DR_BYPASS_WIDTH'(0))
+) i_bypass_reg        (
+    .clk              (tapc_tck             ),
+    .rst_n            (tapc_trst_n          ),
+    .rst_n_sync       (trst_n_int           ),
+    .fsm_dr_select    (dr_bypass_sel        ),
+    .fsm_dr_capture   (tap_fsm_dr_capture_ff),
+    .fsm_dr_shift     (tap_fsm_dr_shift_ff  ),
+    .din_serial       (tapc_tdi             ),
+    .din_parallel     (1'b0                 ),
+    .dout_serial      (dr_bypass_tdo        ),
+    .dout_parallel    (                     )
+);
+
+// IDCODE register
+//------------------------------------------------------------------------------
+// Holds the Device ID value (mandatory IEEE 1149.1 compliant register)
+
+scr1_tapc_shift_reg  #(
+    .SCR1_WIDTH       (SCR1_TAP_DR_IDCODE_WIDTH),
+    .SCR1_RESET_VALUE (SCR1_TAP_DR_IDCODE_WIDTH'(0))
+) i_tap_idcode_reg    (
+    .clk              (tapc_tck              ),
+    .rst_n            (tapc_trst_n           ),
+    .rst_n_sync       (trst_n_int            ),
+    .fsm_dr_select    (dr_idcode_sel         ),
+    .fsm_dr_capture   (tap_fsm_dr_capture_ff ),
+    .fsm_dr_shift     (tap_fsm_dr_shift_ff   ),
+    .din_serial       (tapc_tdi              ),
+    .din_parallel     (soc2tapc_fuse_idcode_i),
+    .dout_serial      (dr_idcode_tdo         ),
+    .dout_parallel    (                      )
+);
+
+// BUILD ID register
+//------------------------------------------------------------------------------
+// Holds the BUILD ID value
+
+scr1_tapc_shift_reg  #(
+    .SCR1_WIDTH       (SCR1_TAP_DR_BLD_ID_WIDTH),
+    .SCR1_RESET_VALUE (SCR1_TAP_DR_BLD_ID_WIDTH'(0))
+) i_tap_dr_bld_id_reg (
+    .clk              (tapc_tck             ),
+    .rst_n            (tapc_trst_n          ),
+    .rst_n_sync       (trst_n_int           ),
+    .fsm_dr_select    (dr_bld_id_sel        ),
+    .fsm_dr_capture   (tap_fsm_dr_capture_ff),
+    .fsm_dr_shift     (tap_fsm_dr_shift_ff  ),
+    .din_serial       (tapc_tdi             ),
+    .din_parallel     (SCR1_TAP_BLD_ID_VALUE),
+    .dout_serial      (dr_bld_id_tdo        ),
+    .dout_parallel    (                     )
+);
+
+//------------------------------------------------------------------------------
+// DMI/SCU scan-chains signals
+//------------------------------------------------------------------------------
+
+assign tapc2tapcsync_ch_tdi_o     = tapc_tdi;
+assign tapc2tapcsync_ch_capture_o = tap_fsm_dr_capture_ff;
+assign tapc2tapcsync_ch_shift_o   = tap_fsm_dr_shift_ff;
+assign tapc2tapcsync_ch_update_o  = tap_fsm_dr_update_ff;
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+// X checks
+SCR1_SVA_TAPC_XCHECK : assert property (
+    @(posedge tapc_tck) disable iff (~tapc_trst_n)
+    !$isunknown({tapc_tms, tapc_tdi})
+) else $error("TAPC error: unknown values");
+
+SCR1_SVA_TAPC_XCHECK_NEGCLK : assert property (
+    @(negedge tapc_tck) disable iff (tap_fsm_ff != SCR1_TAP_STATE_DR_SHIFT)
+    !$isunknown({tapcsync2tapc_ch_tdo_i})
+) else $error("TAPC @negedge error: unknown values");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_tapc
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_shift_reg.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_shift_reg.sv
new file mode 100644
index 0000000..a577bcc
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_shift_reg.sv
@@ -0,0 +1,112 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_tapc_shift_reg.sv>
+/// @brief      TAPC shift register. Parameterized implementation of JTAG TAPC's Shift Register.
+///
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+module scr1_tapc_shift_reg #(
+    parameter   int unsigned            SCR1_WIDTH       = 8,   // Register width, bits
+    parameter   logic [SCR1_WIDTH-1:0]  SCR1_RESET_VALUE = '0   // Register's value after reset
+) (
+    input  logic                    clk,            // Clock
+    input  logic                    rst_n,          // Async reset
+    input  logic                    rst_n_sync,     // Sync reset
+                                                    // TAP FSM's control signals:
+    input  logic                    fsm_dr_select,  //   - for this DR selection (operation enabling);
+    input  logic                    fsm_dr_capture, //   - to capture parallel input's data into shift register;
+    input  logic                    fsm_dr_shift,   //   - to enable data shifting;
+                                                    // Inputs:
+    input  logic                    din_serial,     //   - serial (shift_reg[msb/SCR1_WIDTH]);
+    input  logic [SCR1_WIDTH-1:0]   din_parallel,   //   - parallel (shift register's input).
+                                                    // Outputs:
+    output logic                    dout_serial,    //   - serial (shift_reg[0]);
+    output logic [SCR1_WIDTH-1:0]   dout_parallel   //   - parallel (shift register's output).
+);
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+logic [SCR1_WIDTH-1:0]   shift_reg;
+
+//-------------------------------------------------------------------------------
+// Shift register
+//-------------------------------------------------------------------------------
+generate
+    if (SCR1_WIDTH > 1)
+    begin : dr_shift_reg
+
+        always_ff @(posedge clk, negedge rst_n)
+        begin
+            if (~rst_n) begin
+                shift_reg <= SCR1_RESET_VALUE;
+            end
+            else if (~rst_n_sync) begin
+                shift_reg <= SCR1_RESET_VALUE;
+            end
+            else if (fsm_dr_select & fsm_dr_capture) begin
+                shift_reg <= din_parallel;
+            end
+            else if (fsm_dr_select & fsm_dr_shift) begin
+                shift_reg <= {din_serial, shift_reg[SCR1_WIDTH-1:1]};
+            end
+        end
+
+    end
+    else begin : dr_shift_reg
+
+        always_ff @(posedge clk, negedge rst_n)
+        begin
+            if (~rst_n) begin
+                shift_reg <= SCR1_RESET_VALUE;
+            end
+            else if (~rst_n_sync) begin
+                shift_reg <= SCR1_RESET_VALUE;
+            end
+            else if (fsm_dr_select & fsm_dr_capture) begin
+                shift_reg <= din_parallel;
+            end
+            else if (fsm_dr_select & fsm_dr_shift) begin
+                shift_reg <= din_serial;
+            end
+        end
+
+    end
+endgenerate
+
+//-------------------------------------------------------------------------------
+// Parallel output
+//-------------------------------------------------------------------------------
+assign dout_parallel = shift_reg;
+
+//-------------------------------------------------------------------------------
+// Serial output
+//-------------------------------------------------------------------------------
+assign dout_serial = shift_reg[0];
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+// X checks
+SCR1_SVA_TAPC_SHIFTREG_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown({
+        rst_n_sync,
+        fsm_dr_select,
+        fsm_dr_capture,
+        fsm_dr_shift,
+        din_serial,
+        din_parallel
+    })
+) else begin
+    $error("TAPC Shift Reg error: unknown values");
+end
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_tapc_shift_reg
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_synchronizer.sv b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_synchronizer.sv
new file mode 100644
index 0000000..0d94705
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/core/scr1_tapc_synchronizer.sv
@@ -0,0 +1,183 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_tapc_synchronizer.sv>
+/// @brief      TAPC clock domain crossing synchronizer
+///
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+`include "scr1_tapc.svh"
+`include "scr1_dm.svh"
+
+module scr1_tapc_synchronizer (
+    // System common signals
+    input   logic                                   pwrup_rst_n,                // Power-Up Reset
+    input   logic                                   dm_rst_n,                   // Debug Module Reset
+    input   logic                                   clk,                        // System Clock (SysCLK)
+
+    // JTAG common signals
+    input   logic                                   tapc_trst_n,                // JTAG Test Reset (TRSTn)
+    input   logic                                   tapc_tck,                   // JTAG Test Clock (TCK)
+
+
+    // DMI/SCU scan-chains
+    input  logic                                    tapc2tapcsync_scu_ch_sel_i, // SCU Chain Select input  (TCK domain)
+    output logic                                    tapcsync2scu_ch_sel_o,      // SCU Chain Select output (SysCLK domain)
+    input  logic                                    tapc2tapcsync_dmi_ch_sel_i, // DMI Chain Select input  (TCK domain)
+    output logic                                    tapcsync2dmi_ch_sel_o,      // DMI Chain Select output (SysCLK domain)
+
+    input  logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]     tapc2tapcsync_ch_id_i,      // DMI/SCU Chain Identifier input  (TCK domain)
+    output logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0]     tapcsync2core_ch_id_o,      // DMI/SCU Chain Identifier output (SysCLK domain)
+
+    input  logic                                    tapc2tapcsync_ch_capture_i, // DMI/SCU Chain Capture input  (TCK domain)
+    output logic                                    tapcsync2core_ch_capture_o, // DMI/SCU Chain Capture output (SysCLK domain)
+
+    input  logic                                    tapc2tapcsync_ch_shift_i,   // DMI/SCU Chain Shift input  (TCK domain)
+    output logic                                    tapcsync2core_ch_shift_o,   // DMI/SCU Chain Shift output (SysCLK domain)
+
+    input  logic                                    tapc2tapcsync_ch_update_i,  // DMI/SCU Chain Update input  (TCK domain)
+    output logic                                    tapcsync2core_ch_update_o,  // DMI/SCU Chain Update output (SysCLK domain)
+
+    input  logic                                    tapc2tapcsync_ch_tdi_i,     // DMI/SCU Chain TDI input  (TCK domain)
+    output logic                                    tapcsync2core_ch_tdi_o,     // DMI/SCU Chain TDI output (SysCLK domain)
+
+    output logic                                    tapc2tapcsync_ch_tdo_i,     // DMI/SCU Chain TDO output (TCK domain)
+    input  logic                                    tapcsync2core_ch_tdo_o      // DMI/SCU Chain TDO input  (SysCLK domain)
+);
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+
+logic           tck_divpos;
+logic           tck_divneg;
+logic           tck_rise_load;
+logic           tck_rise_reset;
+logic           tck_fall_load;
+logic           tck_fall_reset;
+logic [3:0]     tck_divpos_sync;
+logic [3:0]     tck_divneg_sync;
+logic [2:0]     dmi_ch_capture_sync;
+logic [2:0]     dmi_ch_shift_sync;
+logic [2:0]     dmi_ch_tdi_sync;
+
+//-------------------------------------------------------------------------------
+// Logic
+//-------------------------------------------------------------------------------
+
+always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tck_divpos      <= 1'b0;
+    end else begin
+        tck_divpos      <= ~tck_divpos;
+    end
+end
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        tck_divneg      <= 1'b0;
+    end else begin
+        tck_divneg      <= ~tck_divneg;
+    end
+end
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+        tck_divpos_sync <= 4'd0;
+        tck_divneg_sync <= 4'd0;
+    end else begin
+        tck_divpos_sync <= {tck_divpos_sync[2:0], tck_divpos};
+        tck_divneg_sync <= {tck_divneg_sync[2:0], tck_divneg};
+    end
+end
+
+assign tck_rise_load  = tck_divpos_sync[2] ^ tck_divpos_sync[1];
+assign tck_rise_reset = tck_divpos_sync[3] ^ tck_divpos_sync[2];
+assign tck_fall_load  = tck_divneg_sync[2] ^ tck_divneg_sync[1];
+assign tck_fall_reset = tck_divneg_sync[3] ^ tck_divneg_sync[2];
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+            tapcsync2core_ch_update_o   <= '0;
+    end else begin
+        if  (tck_fall_load) begin
+            tapcsync2core_ch_update_o   <= tapc2tapcsync_ch_update_i;
+        end else if (tck_fall_reset) begin
+            tapcsync2core_ch_update_o   <= '0;
+        end
+    end
+end
+
+always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin
+    if (~tapc_trst_n) begin
+        dmi_ch_capture_sync[0] <= '0;
+        dmi_ch_shift_sync[0]   <= '0;
+    end else begin
+        dmi_ch_capture_sync[0] <= tapc2tapcsync_ch_capture_i;
+        dmi_ch_shift_sync[0]   <= tapc2tapcsync_ch_shift_i;
+    end
+end
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+        dmi_ch_capture_sync[2:1] <= '0;
+        dmi_ch_shift_sync[2:1]   <= '0;
+    end else begin
+        dmi_ch_capture_sync[2:1] <= {dmi_ch_capture_sync[1], dmi_ch_capture_sync[0]};
+        dmi_ch_shift_sync[2:1]   <= {dmi_ch_shift_sync[1], dmi_ch_shift_sync[0]};
+    end
+end
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+        dmi_ch_tdi_sync     <= '0;
+    end else begin
+        dmi_ch_tdi_sync     <= {dmi_ch_tdi_sync[1:0], tapc2tapcsync_ch_tdi_i};
+    end
+end
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+            tapcsync2core_ch_capture_o <= '0;
+            tapcsync2core_ch_shift_o   <= '0;
+            tapcsync2core_ch_tdi_o     <= '0;
+    end else begin
+        if (tck_rise_load) begin
+            tapcsync2core_ch_capture_o <= dmi_ch_capture_sync[2];
+            tapcsync2core_ch_shift_o   <= dmi_ch_shift_sync[2];
+            tapcsync2core_ch_tdi_o     <= dmi_ch_tdi_sync[2];
+        end else if (tck_rise_reset) begin
+            tapcsync2core_ch_capture_o <= '0;
+            tapcsync2core_ch_shift_o   <= '0;
+            tapcsync2core_ch_tdi_o     <= '0;
+        end
+    end
+end
+
+always_ff @(posedge clk, negedge dm_rst_n) begin
+    if (~dm_rst_n) begin
+            tapcsync2dmi_ch_sel_o     <= '0;
+            tapcsync2core_ch_id_o      <= '0;
+    end else begin
+        if (tck_rise_load) begin
+            tapcsync2dmi_ch_sel_o     <= tapc2tapcsync_dmi_ch_sel_i;
+            tapcsync2core_ch_id_o      <= tapc2tapcsync_ch_id_i;
+        end
+    end
+end
+
+always_ff @(posedge clk, negedge pwrup_rst_n) begin
+    if (~pwrup_rst_n) begin
+            tapcsync2scu_ch_sel_o     <= '0;
+    end else begin
+        if (tck_rise_load) begin
+            tapcsync2scu_ch_sel_o     <= tapc2tapcsync_scu_ch_sel_i;
+        end
+    end
+end
+
+assign tapc2tapcsync_ch_tdo_i = tapcsync2core_ch_tdo_o;
+
+endmodule : scr1_tapc_synchronizer
+
+`endif // SCR1_DBG_EN
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_ahb.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_ahb.svh
new file mode 100644
index 0000000..54cd4e1
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_ahb.svh
@@ -0,0 +1,59 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_ahb.svh>
+/// @brief      AHB header file
+///
+
+`ifndef SCR1_AHB_SVH
+`define SCR1_AHB_SVH
+
+`include "scr1_arch_description.svh"
+
+parameter SCR1_AHB_WIDTH  = 32;
+
+// Encoding for HTRANS signal
+parameter logic [1:0] SCR1_HTRANS_IDLE   = 2'b00;
+parameter logic [1:0] SCR1_HTRANS_NONSEQ = 2'b10;
+`ifdef SCR1_XPROP_EN
+parameter logic [1:0] SCR1_HTRANS_ERR    = 'x;
+`else // SCR1_XPROP_EN
+parameter logic [1:0] SCR1_HTRANS_ERR    = '0;
+`endif // SCR1_XPROP_EN
+
+// Encoding for HBURST signal
+parameter logic [2:0] SCR1_HBURST_SINGLE = 3'b000;
+`ifdef SCR1_XPROP_EN
+parameter logic [2:0] SCR1_HBURST_ERR    = 'x;
+`else // SCR1_XPROP_EN
+parameter logic [1:0] SCR1_HBURST_ERR    = '0;
+`endif // SCR1_XPROP_EN
+
+// Encoding for HSIZE signal
+parameter logic [2:0] SCR1_HSIZE_8B    = 3'b000;
+parameter logic [2:0] SCR1_HSIZE_16B   = 3'b001;
+parameter logic [2:0] SCR1_HSIZE_32B   = 3'b010;
+`ifdef SCR1_XPROP_EN
+parameter logic [2:0] SCR1_HSIZE_ERR   = 'x;
+`else // SCR1_XPROP_EN
+parameter logic [1:0] SCR1_HSIZE_ERR   = '0;
+`endif // SCR1_XPROP_EN
+
+// Encoding HPROT signal
+// HPROT[0] : 0 - instr;      1 - data
+// HPROT[1] : 0 - user;       1 - privilege
+// HPROT[2] : 0 - not buffer; 1 - buffer
+// HPROT[3] : 0 - cacheable;  1 - cacheable
+parameter SCR1_HPROT_DATA  = 0;
+parameter SCR1_HPROT_PRV   = 1;
+parameter SCR1_HPROT_BUF   = 2;
+parameter SCR1_HPROT_CACHE = 3;
+
+// Encoding HRESP signal
+parameter logic SCR1_HRESP_OKAY  = 1'b0;
+parameter logic SCR1_HRESP_ERROR = 1'b1;
+`ifdef SCR1_XPROP_EN
+parameter logic SCR1_HRESP_ERR   = 1'bx;
+`else // SCR1_XPROP_EN
+parameter logic SCR1_HRESP_ERR   = 1'b0;
+`endif // SCR1_XPROP_EN
+
+`endif // SCR1_AHB_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_description.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_description.svh
new file mode 100644
index 0000000..7c8b532
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_description.svh
@@ -0,0 +1,215 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_arch_description.svh>
+/// @brief      Architecture description file
+///
+
+`ifndef SCR1_ARCH_DESCRIPTION_SVH
+`define SCR1_ARCH_DESCRIPTION_SVH
+
+
+//------------------------------------------------------------------------------
+// CORE FUNDAMENTAL PARAMETERS
+//------------------------------------------------------------------------------
+
+// SCR1 core identifiers
+`define SCR1_MIMPID             32'h21051400
+`define SCR1_MVENDORID          32'h00000000
+
+// Width of main registers and buses
+`define SCR1_XLEN               32
+`define SCR1_IMEM_AWIDTH        `SCR1_XLEN
+`define SCR1_IMEM_DWIDTH        `SCR1_XLEN
+`define SCR1_DMEM_AWIDTH        `SCR1_XLEN
+`define SCR1_DMEM_DWIDTH        `SCR1_XLEN
+
+// TAP IDCODE
+`define SCR1_TAP_IDCODE         'hDEB11001
+
+
+`ifdef SCR1_ARCH_CUSTOM
+//------------------------------------------------------------------------------
+// INCLUDE SCR1_ARCH_CUSTOM.SVH
+//------------------------------------------------------------------------------
+
+// The external file scr1_arch_custom.svh is used for the open SCR1-SDK project,
+// and can also be used for any custom projects.
+
+// The file sets:
+// - target platform (FPGA/ASIC), which affects the choice of logical constructs;
+// - device build ID;
+// - address constants;
+// - could enables configuration parameters.
+
+// Possible targets:
+// `define SCR1_TRGT_FPGA_INTEL         // target platform is Intel FPGAs
+// `define SCR1_TRGT_FPGA_INTEL_MAX10   // target platform is Intel MAX 10 FPGAs (used in the SCR1-SDK project)
+// `define SCR1_TRGT_FPGA_INTEL_ARRIAV  // target platform is Intel Arria V FPGAs (used in the SCR1-SDK project)
+// `define SCR1_TRGT_FPGA_XILINX        // target platform is Xilinx FPGAs (used in the SCR1-SDK project)
+// `define SCR1_TRGT_ASIC               // target platform is ASIC
+// `define SCR1_TRGT_SIMULATION         // target is simulation (enable simulation code)
+
+ `include "scr1_arch_custom.svh"
+
+`endif // SCR1_ARCH_CUSTOM
+
+
+//------------------------------------------------------------------------------
+// RECOMMENDED CORE ARCHITECTURE CONFIGURATIONS
+//------------------------------------------------------------------------------
+
+// Uncomment one of these defines to set the recommended configuration:
+
+//`define SCR1_CFG_RV32IMC_MAX
+//`define SCR1_CFG_RV32IC_BASE
+//`define SCR1_CFG_RV32EC_MIN
+
+// If all defines are commented, custom configuration will be used (see below)
+
+//------------------------------------------------------------------------------
+// READ-ONLY: settings for recommended configurations
+`ifdef  SCR1_CFG_RV32IMC_MAX
+  `define SCR1_RVI_EXT
+  `define SCR1_RVM_EXT
+  `define SCR1_RVC_EXT
+  parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 26;
+  `define SCR1_MTVEC_MODE_EN
+  `define SCR1_FAST_MUL
+  `define SCR1_MPRF_RST_EN
+  `define SCR1_MCOUNTEN_EN
+  `define SCR1_DBG_EN
+  `define SCR1_TDU_EN
+  parameter int unsigned SCR1_TDU_TRIG_NUM = 4;
+  `define SCR1_TDU_ICOUNT_EN
+  `define SCR1_IPIC_EN
+  `define SCR1_IPIC_SYNC_EN
+  `define SCR1_TCM_EN
+`elsif  SCR1_CFG_RV32IC_BASE
+  `define SCR1_RVI_EXT
+  `define SCR1_RVC_EXT
+  parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 16;
+  `define SCR1_MTVEC_MODE_EN
+  `define SCR1_NO_DEC_STAGE
+  `define SCR1_MPRF_RST_EN
+  `define SCR1_MCOUNTEN_EN
+  `define SCR1_DBG_EN
+  `define SCR1_TDU_EN
+  parameter int unsigned SCR1_TDU_TRIG_NUM = 2;
+  `define SCR1_TDU_ICOUNT_EN
+  `define SCR1_IPIC_EN
+  `define SCR1_IPIC_SYNC_EN
+  `define SCR1_TCM_EN
+`elsif  SCR1_CFG_RV32EC_MIN
+  `define SCR1_RVE_EXT
+  `define SCR1_RVC_EXT
+  parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 0;
+  `define SCR1_NO_DEC_STAGE
+  `define SCR1_NO_EXE_STAGE
+  `define SCR1_TCM_EN
+
+`else // begin custom configuration section
+
+
+//------------------------------------------------------------------------------
+// CUSTOM CORE ARCHITECTURE CONFIGURATION
+//------------------------------------------------------------------------------
+
+// To fine-tune custom configuration, you can change the values in this section.
+// Make sure that the defines of the recommended configurations are commented,
+// otherwise this section will be inactive.
+
+// RISC-V ISA options
+//`define SCR1_RVE_EXT                // enable RV32E base integer instruction set, otherwise RV32I will be used
+`define SCR1_RVM_EXT                // enable standard extension "M" for integer hardware multiplier and divider
+`define SCR1_RVC_EXT                // enable standard extension "C" for compressed instructions
+parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 26;    // number of writable high-order bits in MTVEC.base field
+                                                            // legal values are 0 to 26
+                                                            // read-only bits are hardwired to reset value
+`define SCR1_MTVEC_MODE_EN          // enable writable MTVEC.mode field to allow vectored irq mode, otherwise only direct mode is possible
+
+`ifndef SCR1_RVE_EXT
+  `define SCR1_RVI_EXT // RV32E base integer instruction set if SCR1_RVE_EXT is not enabled
+`endif // ~SCR1_RVE_EXT
+
+// Core pipeline options (power-performance-area optimization)
+`define SCR1_NO_DEC_STAGE           // disable register between IFU and IDU
+`define SCR1_NO_EXE_STAGE           // disable register between IDU and EXU
+`define SCR1_NEW_PC_REG             // enable register in IFU for New_PC value
+`define SCR1_FAST_MUL               // enable fast one-cycle multiplication, otherwise multiplication takes 32 cycles
+`define SCR1_CLKCTRL_EN             // enable global clock gating
+`define SCR1_MPRF_RST_EN            // enable reset for MPRF
+`define SCR1_MCOUNTEN_EN            // enable custom MCOUNTEN CSR for counter control
+
+// Uncore options
+`define SCR1_DBG_EN                 // enable Debug Subsystem (TAPC, DM, SCU, HDU)
+`define SCR1_TDU_EN                 // enable Trigger Debug Unit (hardware breakpoints)
+parameter int unsigned SCR1_TDU_TRIG_NUM = 2;   // number of hardware triggers
+`define SCR1_TDU_ICOUNT_EN          // enable hardware triggers on instruction counter
+`define SCR1_IPIC_EN                // enable Integrated Programmable Interrupt Controller
+`define SCR1_IPIC_SYNC_EN           // enable IPIC synchronizer
+`define SCR1_TCM_EN                 // enable Tightly-Coupled Memory
+
+`endif // end custom configuration section
+
+
+//------------------------------------------------------------------------------
+// CORE INTEGRATION OPTIONS
+//------------------------------------------------------------------------------
+
+// Bypasses on AXI/AHB bridge I/O
+`define SCR1_IMEM_AHB_IN_BP         // bypass instruction memory AHB bridge input register
+`define SCR1_IMEM_AHB_OUT_BP        // bypass instruction memory AHB bridge output register
+`define SCR1_DMEM_AHB_IN_BP         // bypass data memory AHB bridge input register
+`define SCR1_DMEM_AHB_OUT_BP        // bypass data memory AHB bridge output register
+`define SCR1_IMEM_AXI_REQ_BP        // bypass instruction memory AXI bridge request register
+`define SCR1_IMEM_AXI_RESP_BP       // bypass instruction memory AXI bridge response register
+`define SCR1_DMEM_AXI_REQ_BP        // bypass data memory AXI bridge request register
+`define SCR1_DMEM_AXI_RESP_BP       // bypass data memory AXI bridge response register
+
+`ifndef SCR1_ARCH_CUSTOM
+// Default address constants (if scr1_arch_custom.svh is not used)
+parameter bit [`SCR1_XLEN-1:0]          SCR1_ARCH_RST_VECTOR        = 'h200;            // Reset vector value (start address after reset)
+parameter bit [`SCR1_XLEN-1:0]          SCR1_ARCH_MTVEC_BASE        = 'h1C0;            // MTVEC.base field reset value, or constant value for MTVEC.base bits that are hardwired
+
+parameter bit [`SCR1_DMEM_AWIDTH-1:0]   SCR1_TCM_ADDR_MASK          = 'hFFFF0000;       // TCM mask and size; size in bytes is two's complement of the mask value
+parameter bit [`SCR1_DMEM_AWIDTH-1:0]   SCR1_TCM_ADDR_PATTERN       = 'h00480000;       // TCM address match pattern
+
+parameter bit [`SCR1_DMEM_AWIDTH-1:0]   SCR1_TIMER_ADDR_MASK        = 'hFFFFFFE0;       // Timer mask
+parameter bit [`SCR1_DMEM_AWIDTH-1:0]   SCR1_TIMER_ADDR_PATTERN     = 'h00490000;       // Timer address match pattern
+
+// Device build ID
+ `define SCR1_ARCH_BUILD_ID             `SCR1_MIMPID
+
+`endif // SCR1_ARCH_CUSTOM
+
+
+//------------------------------------------------------------------------------
+// TARGET-SPECIFIC OPTIONS
+//------------------------------------------------------------------------------
+
+// RAM-based MPRF can be used for Intel FPGAs only
+`ifdef SCR1_TRGT_FPGA_INTEL
+  `define SCR1_MPRF_RAM           // implements MPRF with dedicated RAM blocks
+`endif
+
+// EXU_STAGE_BYPASS and MPRF_RST_EN must be disabled for RAM-based MPRF
+`ifdef SCR1_MPRF_RAM
+  `undef  SCR1_NO_EXE_STAGE
+  `undef  SCR1_MPRF_RST_EN
+`endif
+
+
+//------------------------------------------------------------------------------
+// SIMULATION OPTIONS
+//------------------------------------------------------------------------------
+
+//`define SCR1_TRGT_SIMULATION            // enable simulation code (automatically defined by root makefile)
+//`define SCR1_TRACE_LOG_EN               // enable tracelog
+//`define SCR1_XPROP_EN                   // enable X-propagation
+
+// Addresses used in testbench
+localparam [`SCR1_XLEN-1:0]      SCR1_SIM_EXIT_ADDR      = 32'h0000_00F8;
+localparam [`SCR1_XLEN-1:0]      SCR1_SIM_PRINT_ADDR     = 32'hF000_0000;
+localparam [`SCR1_XLEN-1:0]      SCR1_SIM_EXT_IRQ_ADDR   = 32'hF000_0100;
+localparam [`SCR1_XLEN-1:0]      SCR1_SIM_SOFT_IRQ_ADDR  = 32'hF000_0200;
+
+`endif // SCR1_ARCH_DESCRIPTION_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_types.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_types.svh
new file mode 100644
index 0000000..62f1037
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_arch_types.svh
@@ -0,0 +1,72 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_arch_types.svh>
+/// @brief      Pipeline types description file
+///
+
+`ifndef SCR1_ARCH_TYPES_SVH
+`define SCR1_ARCH_TYPES_SVH
+
+`include "scr1_arch_description.svh"
+
+//-------------------------------------------------------------------------------
+// MPRF and CSR parameters
+//-------------------------------------------------------------------------------
+
+`ifdef SCR1_RVE_EXT
+  `define SCR1_MPRF_AWIDTH    4
+  `define SCR1_MPRF_SIZE      16
+`else // SCR1_RVE_EXT
+  `define SCR1_MPRF_AWIDTH    5
+  `define SCR1_MPRF_SIZE      32
+`endif // SCR1_RVE_EXT
+
+typedef logic [`SCR1_XLEN-1:0]  type_scr1_mprf_v;
+typedef logic [`SCR1_XLEN-1:0]  type_scr1_pc_v;
+
+parameter int unsigned  SCR1_CSR_ADDR_WIDTH             = 12;
+parameter int unsigned  SCR1_CSR_MTVEC_BASE_ZERO_BITS   = 6;
+parameter int unsigned  SCR1_CSR_MTVEC_BASE_VAL_BITS    = `SCR1_XLEN-SCR1_CSR_MTVEC_BASE_ZERO_BITS;
+parameter bit [`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS]  SCR1_CSR_MTVEC_BASE_WR_RST_VAL    =
+                                      SCR1_CSR_MTVEC_BASE_VAL_BITS'(SCR1_ARCH_MTVEC_BASE >> SCR1_CSR_MTVEC_BASE_ZERO_BITS);
+parameter int unsigned  SCR1_CSR_MTVEC_BASE_RO_BITS = (`SCR1_XLEN-(SCR1_CSR_MTVEC_BASE_ZERO_BITS+SCR1_MTVEC_BASE_WR_BITS));
+
+`define SCR1_MTVAL_ILLEGAL_INSTR_EN
+
+//-------------------------------------------------------------------------------
+// Exception and IRQ codes
+//-------------------------------------------------------------------------------
+parameter int unsigned SCR1_EXC_CODE_WIDTH_E    = 4;
+
+// Exceptions
+typedef enum logic [SCR1_EXC_CODE_WIDTH_E-1:0] {
+    SCR1_EXC_CODE_INSTR_MISALIGN        = 4'd0,     // from EXU
+    SCR1_EXC_CODE_INSTR_ACCESS_FAULT    = 4'd1,     // from IFU
+    SCR1_EXC_CODE_ILLEGAL_INSTR         = 4'd2,     // from IDU or CSR
+    SCR1_EXC_CODE_BREAKPOINT            = 4'd3,     // from IDU or BRKM
+    SCR1_EXC_CODE_LD_ADDR_MISALIGN      = 4'd4,     // from LSU
+    SCR1_EXC_CODE_LD_ACCESS_FAULT       = 4'd5,     // from LSU
+    SCR1_EXC_CODE_ST_ADDR_MISALIGN      = 4'd6,     // from LSU
+    SCR1_EXC_CODE_ST_ACCESS_FAULT       = 4'd7,     // from LSU
+    SCR1_EXC_CODE_ECALL_M               = 4'd11     // from IDU
+} type_scr1_exc_code_e;
+
+// IRQs, reset
+parameter bit [SCR1_EXC_CODE_WIDTH_E-1:0] SCR1_EXC_CODE_IRQ_M_SOFTWARE      = 4'd3;
+parameter bit [SCR1_EXC_CODE_WIDTH_E-1:0] SCR1_EXC_CODE_IRQ_M_TIMER         = 4'd7;
+parameter bit [SCR1_EXC_CODE_WIDTH_E-1:0] SCR1_EXC_CODE_IRQ_M_EXTERNAL      = 4'd11;
+parameter bit [SCR1_EXC_CODE_WIDTH_E-1:0] SCR1_EXC_CODE_RESET               = 4'd0;
+
+//-------------------------------------------------------------------------------
+// Operand width for BRKM
+//-------------------------------------------------------------------------------
+typedef enum logic [1:0] {
+    SCR1_OP_WIDTH_BYTE  = 2'b00,
+    SCR1_OP_WIDTH_HALF  = 2'b01,
+    SCR1_OP_WIDTH_WORD  = 2'b10
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_OP_WIDTH_ERROR = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_op_width_e;
+
+`endif //SCR1_ARCH_TYPES_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_csr.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_csr.svh
new file mode 100644
index 0000000..18dcafb
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_csr.svh
@@ -0,0 +1,196 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_csr.svh>
+/// @brief      CSR mapping/description file
+///
+
+`ifndef SCR1_CSR_SVH
+`define SCR1_CSR_SVH
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+`include "scr1_ipic.svh"
+
+`ifdef SCR1_RVE_EXT
+`define SCR1_CSR_REDUCED_CNT
+`endif // SCR1_RVE_EXT
+
+`ifdef SCR1_CSR_REDUCED_CNT
+`undef SCR1_MCOUNTEN_EN
+`endif // SCR1_CSR_REDUCED_CNT
+
+//-------------------------------------------------------------------------------
+// CSR addresses (standard)
+//-------------------------------------------------------------------------------
+
+// Machine Information Registers (read-only)
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MVENDORID     = 'hF11;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MARCHID       = 'hF12;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MIMPID        = 'hF13;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MHARTID       = 'hF14;
+
+// Machine Trap Setup (read-write)
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MSTATUS       = 'h300;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MISA          = 'h301;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MIE           = 'h304;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MTVEC         = 'h305;
+
+// Machine Trap Handling (read-write)
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MSCRATCH      = 'h340;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MEPC          = 'h341;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MCAUSE        = 'h342;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MTVAL         = 'h343;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MIP           = 'h344;
+
+// Machine Counters/Timers (read-write)
+`ifndef SCR1_CSR_REDUCED_CNT
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MCYCLE        = 'hB00;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MINSTRET      = 'hB02;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MCYCLEH       = 'hB80;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MINSTRETH     = 'hB82;
+`endif // SCR1_CSR_REDUCED_CNT
+
+// Shadow Counters/Timers (read-only)
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TIME          = 'hC01;
+`ifndef SCR1_CSR_REDUCED_CNT
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_CYCLE         = 'hC00;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_INSTRET       = 'hC02;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TIMEH         = 'hC81;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_CYCLEH        = 'hC80;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_INSTRETH      = 'hC82;
+`endif // SCR1_CSR_REDUCED_CNT
+
+`ifdef SCR1_DBG_EN
+//parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_DBGC_SCRATCH  = 'h7C8;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_HDU_MBASE    = 'h7B0;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_HDU_MSPAN    = 'h004;    // must be power of 2
+`endif // SCR1_DBG_EN
+
+//-------------------------------------------------------------------------------
+// CSR addresses (non-standard)
+//-------------------------------------------------------------------------------
+`ifdef SCR1_MCOUNTEN_EN
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_MCOUNTEN      = 'h7E0;
+`endif // SCR1_MCOUNTEN_EN
+
+`ifdef SCR1_TDU_EN
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_MBASE    = 'h7A0;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_MSPAN    = 'h008;    // must be power of 2
+`endif // SCR1_TDU_EN
+
+`ifdef SCR1_IPIC_EN
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_BASE     = 'hBF0;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_CISV     = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_CISV );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_CICSR    = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_CICSR);
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_IPR      = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_IPR  );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_ISVR     = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_ISVR );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_EOI      = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_EOI  );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_SOI      = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_SOI  );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_IDX      = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_IDX  );
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_IPIC_ICSR     = (SCR1_CSR_ADDR_IPIC_BASE + SCR1_IPIC_ICSR );
+`endif // SCR1_IPIC_EN
+
+
+//-------------------------------------------------------------------------------
+// CSR definitions
+//-------------------------------------------------------------------------------
+
+// General
+parameter bit [`SCR1_XLEN-1:0] SCR1_RST_VECTOR      = SCR1_ARCH_RST_VECTOR;
+
+// Reset values TBD
+parameter bit SCR1_CSR_MIE_MSIE_RST_VAL             = 1'b0;
+parameter bit SCR1_CSR_MIE_MTIE_RST_VAL             = 1'b0;
+parameter bit SCR1_CSR_MIE_MEIE_RST_VAL             = 1'b0;
+
+parameter bit SCR1_CSR_MIP_MSIP_RST_VAL             = 1'b0;
+parameter bit SCR1_CSR_MIP_MTIP_RST_VAL             = 1'b0;
+parameter bit SCR1_CSR_MIP_MEIP_RST_VAL             = 1'b0;
+
+parameter bit SCR1_CSR_MSTATUS_MIE_RST_VAL          = 1'b0;
+parameter bit SCR1_CSR_MSTATUS_MPIE_RST_VAL         = 1'b1;
+
+// MISA
+`define SCR1_RVC_ENC                                `SCR1_XLEN'h0004
+`define SCR1_RVE_ENC                                `SCR1_XLEN'h0010
+`define SCR1_RVI_ENC                                `SCR1_XLEN'h0100
+`define SCR1_RVM_ENC                                `SCR1_XLEN'h1000
+parameter bit [1:0]             SCR1_MISA_MXL_32    = 2'd1;
+parameter bit [`SCR1_XLEN-1:0]  SCR1_CSR_MISA       = (SCR1_MISA_MXL_32 << (`SCR1_XLEN-2))
+`ifndef SCR1_RVE_EXT
+                                                    | `SCR1_RVI_ENC
+`else // SCR1_RVE_EXT
+                                                    | `SCR1_RVE_ENC
+`endif // SCR1_RVE_EXT
+`ifdef SCR1_RVC_EXT
+                                                    | `SCR1_RVC_ENC
+`endif // SCR1_RVC_EXT
+`ifdef SCR1_RVM_EXT
+                                                    | `SCR1_RVM_ENC
+`endif // SCR1_RVM_EXT
+                                                    ;
+
+// MVENDORID
+parameter bit [`SCR1_XLEN-1:0] SCR1_CSR_MVENDORID   = `SCR1_MVENDORID;
+
+// MARCHID
+parameter bit [`SCR1_XLEN-1:0] SCR1_CSR_MARCHID     = `SCR1_XLEN'd8;
+
+// MIMPID
+parameter bit [`SCR1_XLEN-1:0] SCR1_CSR_MIMPID      = `SCR1_MIMPID;
+
+// MSTATUS
+parameter bit [1:0] SCR1_CSR_MSTATUS_MPP            = 2'b11;
+parameter int unsigned SCR1_CSR_MSTATUS_MIE_OFFSET  = 3;
+parameter int unsigned SCR1_CSR_MSTATUS_MPIE_OFFSET = 7;
+parameter int unsigned SCR1_CSR_MSTATUS_MPP_OFFSET  = 11;
+
+// MTVEC
+// bits [5:0] are always zero
+parameter bit [`SCR1_XLEN-1:SCR1_CSR_MTVEC_BASE_ZERO_BITS] SCR1_CSR_MTVEC_BASE_RST_VAL  = SCR1_CSR_MTVEC_BASE_WR_RST_VAL;
+
+parameter bit SCR1_CSR_MTVEC_MODE_DIRECT            = 1'b0;
+`ifdef SCR1_MTVEC_MODE_EN
+parameter bit SCR1_CSR_MTVEC_MODE_VECTORED          = 1'b1;
+`endif // SCR1_MTVEC_MODE_EN
+
+// MIE, MIP
+parameter int unsigned SCR1_CSR_MIE_MSIE_OFFSET     = 3;
+parameter int unsigned SCR1_CSR_MIE_MTIE_OFFSET     = 7;
+parameter int unsigned SCR1_CSR_MIE_MEIE_OFFSET     = 11;
+
+`ifdef SCR1_MCOUNTEN_EN
+// MCOUNTEN
+parameter int unsigned SCR1_CSR_MCOUNTEN_CY_OFFSET  = 0;
+parameter int unsigned SCR1_CSR_MCOUNTEN_IR_OFFSET  = 2;
+`endif // SCR1_MCOUNTEN_EN
+
+// MCAUSE
+typedef logic [`SCR1_XLEN-2:0]      type_scr1_csr_mcause_ec_v;
+
+// MCYCLE, MINSTRET
+`ifdef SCR1_CSR_REDUCED_CNT
+parameter int unsigned SCR1_CSR_COUNTERS_WIDTH      = 32;
+`else // ~SCR1_CSR_REDUCED_CNT
+parameter int unsigned SCR1_CSR_COUNTERS_WIDTH      = 64;
+`endif // ~SCR1_CSR_REDUCED_CNT
+
+// HPM
+parameter bit [6:0] SCR1_CSR_ADDR_HPMCOUNTER_MASK   = 7'b1100000;
+parameter bit [6:0] SCR1_CSR_ADDR_HPMCOUNTERH_MASK  = 7'b1100100;
+parameter bit [6:0] SCR1_CSR_ADDR_MHPMCOUNTER_MASK  = 7'b1011000;
+parameter bit [6:0] SCR1_CSR_ADDR_MHPMCOUNTERH_MASK = 7'b1011100;
+parameter bit [6:0] SCR1_CSR_ADDR_MHPMEVENT_MASK    = 7'b0011001;
+
+//-------------------------------------------------------------------------------
+// Types declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_CSR_RESP_OK,
+    SCR1_CSR_RESP_ER
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_CSR_RESP_ERROR = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_csr_resp_e;
+
+`endif // SCR1_CSR_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_dm.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_dm.svh
new file mode 100644
index 0000000..0d4b0d9
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_dm.svh
@@ -0,0 +1,141 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_dm.svh>
+/// @brief      Debug Module header file
+///
+
+`ifndef SCR1_INCLUDE_DM_DEFS
+`define SCR1_INCLUDE_DM_DEFS
+
+`include "scr1_arch_description.svh"
+`include "scr1_hdu.svh"
+`include "scr1_csr.svh"
+
+parameter SCR1_DBG_DMI_ADDR_WIDTH                  = 6'd7;
+parameter SCR1_DBG_DMI_DATA_WIDTH                  = 6'd32;
+parameter SCR1_DBG_DMI_OP_WIDTH                    = 2'd2;
+
+parameter SCR1_DBG_DMI_CH_ID_WIDTH                 = 2'd2;
+parameter SCR1_DBG_DMI_DR_DTMCS_WIDTH              = 6'd32;
+parameter SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH         = SCR1_DBG_DMI_OP_WIDTH +
+                                                     SCR1_DBG_DMI_DATA_WIDTH +
+                                                     SCR1_DBG_DMI_ADDR_WIDTH;
+
+// Debug Module addresses
+parameter SCR1_DBG_DATA0                           = 7'h4;
+parameter SCR1_DBG_DATA1                           = 7'h5;
+parameter SCR1_DBG_DMCONTROL                       = 7'h10;
+parameter SCR1_DBG_DMSTATUS                        = 7'h11;
+parameter SCR1_DBG_HARTINFO                        = 7'h12;
+parameter SCR1_DBG_ABSTRACTCS                      = 7'h16;
+parameter SCR1_DBG_COMMAND                         = 7'h17;
+parameter SCR1_DBG_ABSTRACTAUTO                    = 7'h18;
+parameter SCR1_DBG_PROGBUF0                        = 7'h20;
+parameter SCR1_DBG_PROGBUF1                        = 7'h21;
+parameter SCR1_DBG_PROGBUF2                        = 7'h22;
+parameter SCR1_DBG_PROGBUF3                        = 7'h23;
+parameter SCR1_DBG_PROGBUF4                        = 7'h24;
+parameter SCR1_DBG_PROGBUF5                        = 7'h25;
+parameter SCR1_DBG_HALTSUM0                        = 7'h40;
+
+// DMCONTROL
+parameter SCR1_DBG_DMCONTROL_HALTREQ               = 5'd31;
+parameter SCR1_DBG_DMCONTROL_RESUMEREQ             = 5'd30;
+parameter SCR1_DBG_DMCONTROL_HARTRESET             = 5'd29;
+parameter SCR1_DBG_DMCONTROL_ACKHAVERESET          = 5'd28;
+parameter SCR1_DBG_DMCONTROL_RESERVEDB             = 5'd27;
+parameter SCR1_DBG_DMCONTROL_HASEL                 = 5'd26;
+parameter SCR1_DBG_DMCONTROL_HARTSELLO_HI          = 5'd25;
+parameter SCR1_DBG_DMCONTROL_HARTSELLO_LO          = 5'd16;
+parameter SCR1_DBG_DMCONTROL_HARTSELHI_HI          = 5'd15;
+parameter SCR1_DBG_DMCONTROL_HARTSELHI_LO          = 5'd6;
+parameter SCR1_DBG_DMCONTROL_RESERVEDA_HI          = 5'd5;
+parameter SCR1_DBG_DMCONTROL_RESERVEDA_LO          = 5'd2;
+parameter SCR1_DBG_DMCONTROL_NDMRESET              = 5'd1;
+parameter SCR1_DBG_DMCONTROL_DMACTIVE              = 5'd0;
+
+// DMSTATUS
+parameter SCR1_DBG_DMSTATUS_RESERVEDC_HI           = 5'd31;
+parameter SCR1_DBG_DMSTATUS_RESERVEDC_LO           = 5'd23;
+parameter SCR1_DBG_DMSTATUS_IMPEBREAK              = 5'd22;
+parameter SCR1_DBG_DMSTATUS_RESERVEDB_HI           = 5'd21;
+parameter SCR1_DBG_DMSTATUS_RESERVEDB_LO           = 5'd20;
+parameter SCR1_DBG_DMSTATUS_ALLHAVERESET           = 5'd19;
+parameter SCR1_DBG_DMSTATUS_ANYHAVERESET           = 5'd18;
+parameter SCR1_DBG_DMSTATUS_ALLRESUMEACK           = 5'd17;
+parameter SCR1_DBG_DMSTATUS_ANYRESUMEACK           = 5'd16;
+parameter SCR1_DBG_DMSTATUS_ALLNONEXISTENT         = 5'd15;
+parameter SCR1_DBG_DMSTATUS_ANYNONEXISTENT         = 5'd14;
+parameter SCR1_DBG_DMSTATUS_ALLUNAVAIL             = 5'd13;
+parameter SCR1_DBG_DMSTATUS_ANYUNAVAIL             = 5'd12;
+parameter SCR1_DBG_DMSTATUS_ALLRUNNING             = 5'd11;
+parameter SCR1_DBG_DMSTATUS_ANYRUNNING             = 5'd10;
+parameter SCR1_DBG_DMSTATUS_ALLHALTED              = 5'd9;
+parameter SCR1_DBG_DMSTATUS_ANYHALTED              = 5'd8;
+parameter SCR1_DBG_DMSTATUS_AUTHENTICATED          = 5'd7;
+parameter SCR1_DBG_DMSTATUS_AUTHBUSY               = 5'd6;
+parameter SCR1_DBG_DMSTATUS_RESERVEDA              = 5'd5;
+parameter SCR1_DBG_DMSTATUS_DEVTREEVALID           = 5'd4;
+parameter SCR1_DBG_DMSTATUS_VERSION_HI             = 5'd3;
+parameter SCR1_DBG_DMSTATUS_VERSION_LO             = 5'd0;
+
+// COMMANDS
+parameter SCR1_DBG_COMMAND_TYPE_HI                 = 5'd31;
+parameter SCR1_DBG_COMMAND_TYPE_LO                 = 5'd24;
+parameter SCR1_DBG_COMMAND_TYPE_WDTH               = SCR1_DBG_COMMAND_TYPE_HI
+                                                   - SCR1_DBG_COMMAND_TYPE_LO;
+
+parameter SCR1_DBG_COMMAND_ACCESSREG_RESERVEDB     = 5'd23;
+parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_HI       = 5'd22;
+parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_LO       = 5'd20;
+parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_WDTH     = SCR1_DBG_COMMAND_ACCESSREG_SIZE_HI
+                                                   - SCR1_DBG_COMMAND_ACCESSREG_SIZE_LO;
+parameter SCR1_DBG_COMMAND_ACCESSREG_RESERVEDA     = 5'd19;
+parameter SCR1_DBG_COMMAND_ACCESSREG_POSTEXEC      = 5'd18;
+parameter SCR1_DBG_COMMAND_ACCESSREG_TRANSFER      = 5'd17;
+parameter SCR1_DBG_COMMAND_ACCESSREG_WRITE         = 5'd16;
+parameter SCR1_DBG_COMMAND_ACCESSREG_REGNO_HI      = 5'd15;
+parameter SCR1_DBG_COMMAND_ACCESSREG_REGNO_LO      = 5'd0;
+
+parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMVIRTUAL    = 5'd23;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_HI    = 5'd22;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_LO    = 5'd20;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMPOSTINC    = 5'd19;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_HI  = 5'd18;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_LO  = 5'd17;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_WRITE         = 5'd16;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_HI  = 5'd13;
+parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_LO  = 5'd0;
+
+// ABSTRACTCS
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDD_HI         = 5'd31;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDD_LO         = 5'd29;
+parameter SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_HI       = 5'd28;
+parameter SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_LO       = 5'd24;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDC_HI         = 5'd23;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDC_LO         = 5'd13;
+parameter SCR1_DBG_ABSTRACTCS_BUSY                 = 5'd12;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDB            = 5'd11;
+parameter SCR1_DBG_ABSTRACTCS_CMDERR_HI            = 5'd10;
+parameter SCR1_DBG_ABSTRACTCS_CMDERR_LO            = 5'd8;
+parameter SCR1_DBG_ABSTRACTCS_CMDERR_WDTH          = SCR1_DBG_ABSTRACTCS_CMDERR_HI
+                                                   - SCR1_DBG_ABSTRACTCS_CMDERR_LO;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDA_HI         = 5'd7;
+parameter SCR1_DBG_ABSTRACTCS_RESERVEDA_LO         = 5'd4;
+parameter SCR1_DBG_ABSTRACTCS_DATACOUNT_HI         = 5'd3;
+parameter SCR1_DBG_ABSTRACTCS_DATACOUNT_LO         = 5'd0;
+
+// HARTINFO
+parameter SCR1_DBG_HARTINFO_RESERVEDB_HI           = 5'd31;
+parameter SCR1_DBG_HARTINFO_RESERVEDB_LO           = 5'd24;
+parameter SCR1_DBG_HARTINFO_NSCRATCH_HI            = 5'd23;
+parameter SCR1_DBG_HARTINFO_NSCRATCH_LO            = 5'd20;
+parameter SCR1_DBG_HARTINFO_RESERVEDA_HI           = 5'd19;
+parameter SCR1_DBG_HARTINFO_RESERVEDA_LO           = 5'd17;
+parameter SCR1_DBG_HARTINFO_DATAACCESS             = 5'd16;
+parameter SCR1_DBG_HARTINFO_DATASIZE_HI            = 5'd15;
+parameter SCR1_DBG_HARTINFO_DATASIZE_LO            = 5'd12;
+parameter SCR1_DBG_HARTINFO_DATAADDR_HI            = 5'd11;
+parameter SCR1_DBG_HARTINFO_DATAADDR_LO            = 5'd0;
+
+
+`endif // SCR1_INCLUDE_DM_DEFS
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_hdu.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_hdu.svh
new file mode 100644
index 0000000..c3a503f
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_hdu.svh
@@ -0,0 +1,163 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_pipe_hdu.svh>
+/// @brief      HART Debug Unit definitions file
+///
+
+`ifndef SCR1_INCLUDE_HDU_DEFS
+`define SCR1_INCLUDE_HDU_DEFS
+
+`include "scr1_arch_description.svh"
+`include "scr1_csr.svh"
+
+`ifdef SCR1_MMU_EN
+ `define SCR1_HDU_FEATURE_MPRVEN
+`endif // SCR1_MMU_EN
+
+//==============================================================================
+// Parameters
+//==============================================================================
+//localparam int unsigned SCR1_HDU_DEBUGCSR_BASE_ADDR      = 12'h7B0;
+localparam int unsigned SCR1_HDU_DEBUGCSR_ADDR_SPAN      = SCR1_CSR_ADDR_HDU_MSPAN;
+localparam int unsigned SCR1_HDU_DEBUGCSR_ADDR_WIDTH     = $clog2(SCR1_HDU_DEBUGCSR_ADDR_SPAN);
+localparam bit [3:0]    SCR1_HDU_DEBUGCSR_DCSR_XDEBUGVER = 4'h4;
+localparam int unsigned SCR1_HDU_PBUF_ADDR_SPAN          = 8;
+localparam int unsigned SCR1_HDU_PBUF_ADDR_WIDTH         = $clog2(SCR1_HDU_PBUF_ADDR_SPAN);
+localparam int unsigned SCR1_HDU_DATA_REG_WIDTH          = 32;
+localparam int unsigned SCR1_HDU_CORE_INSTR_WIDTH        = 32;
+
+
+//==============================================================================
+// Types
+//==============================================================================
+
+// HART Debug States:
+typedef enum logic [1:0] {
+    SCR1_HDU_DBGSTATE_RESET         = 2'b00,
+    SCR1_HDU_DBGSTATE_RUN           = 2'b01,
+    SCR1_HDU_DBGSTATE_DHALTED       = 2'b10,
+    SCR1_HDU_DBGSTATE_DRUN          = 2'b11
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_HDU_DBGSTATE_XXX           = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_hdu_dbgstates_e;
+
+typedef enum logic [1:0] {
+    SCR1_HDU_PBUFSTATE_IDLE          = 2'b00,
+    SCR1_HDU_PBUFSTATE_FETCH         = 2'b01,
+    SCR1_HDU_PBUFSTATE_EXCINJECT     = 2'b10,
+    SCR1_HDU_PBUFSTATE_WAIT4END      = 2'b11
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_HDU_PBUFSTATE_XXX           = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_hdu_pbufstates_e;
+
+typedef enum logic {
+    SCR1_HDU_HARTCMD_RESUME         = 1'b0,
+    SCR1_HDU_HARTCMD_HALT           = 1'b1
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_HDU_HARTCMD_XXX            = 1'bX
+`endif // SCR1_XPROP_EN
+} type_scr1_hdu_hart_command_e;
+
+typedef enum logic {
+    SCR1_HDU_FETCH_SRC_NORMAL       = 1'b0,
+    SCR1_HDU_FETCH_SRC_PBUF         = 1'b1
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_HDU_FETCH_SRC_XXX          = 1'bX
+`endif // SCR1_XPROP_EN
+} type_scr1_hdu_fetch_src_e;
+
+typedef struct packed {
+    //logic                               reset_n;
+    logic                               except;
+    logic                               ebreak;
+    type_scr1_hdu_dbgstates_e           dbg_state;
+} type_scr1_hdu_hartstatus_s;
+
+// Debug Mode Redirection control:
+typedef struct packed {
+    logic                               sstep;          // Single Step
+    logic                               ebreak;         // Redirection after EBREAK execution
+} type_scr1_hdu_redirect_s;
+
+typedef struct packed {
+    logic                               irq_dsbl;
+    type_scr1_hdu_fetch_src_e           fetch_src;
+    logic                               pc_advmt_dsbl;
+    logic                               hwbrkpt_dsbl;
+    type_scr1_hdu_redirect_s            redirect;
+} type_scr1_hdu_runctrl_s;
+
+// HART Halt Status:
+typedef enum logic [2:0] {
+    SCR1_HDU_HALTCAUSE_NONE         = 3'b000,
+    SCR1_HDU_HALTCAUSE_EBREAK       = 3'b001,
+    SCR1_HDU_HALTCAUSE_TMREQ        = 3'b010,
+    SCR1_HDU_HALTCAUSE_DMREQ        = 3'b011,
+    SCR1_HDU_HALTCAUSE_SSTEP        = 3'b100,
+    SCR1_HDU_HALTCAUSE_RSTEXIT      = 3'b101
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_HDU_HALTCAUSE_XXX          = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_hdu_haltcause_e;
+
+typedef struct packed {
+    logic                               except;
+    type_scr1_hdu_haltcause_e           cause;
+} type_scr1_hdu_haltstatus_s;
+
+
+// Debug CSR map
+localparam SCR1_HDU_DBGCSR_OFFS_DCSR       = SCR1_HDU_DEBUGCSR_ADDR_WIDTH'( 'd0 );
+localparam SCR1_HDU_DBGCSR_OFFS_DPC        = SCR1_HDU_DEBUGCSR_ADDR_WIDTH'( 'd1 );
+localparam SCR1_HDU_DBGCSR_OFFS_DSCRATCH0  = SCR1_HDU_DEBUGCSR_ADDR_WIDTH'( 'd2 );
+localparam SCR1_HDU_DBGCSR_OFFS_DSCRATCH1  = SCR1_HDU_DEBUGCSR_ADDR_WIDTH'( 'd3 );
+
+localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DCSR      = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DCSR;
+localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DPC       = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DPC;
+localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DSCRATCH0 = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DSCRATCH0;
+localparam bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_HDU_DBGCSR_ADDR_DSCRATCH1 = SCR1_CSR_ADDR_HDU_MBASE + SCR1_HDU_DBGCSR_OFFS_DSCRATCH1;
+
+// Debug CSRs :: DCSR
+typedef enum int {
+    SCR1_HDU_DCSR_PRV_BIT_R         = 0,
+    SCR1_HDU_DCSR_PRV_BIT_L         = 1,
+    SCR1_HDU_DCSR_STEP_BIT          = 2,
+    SCR1_HDU_DCSR_RSRV0_BIT_R       = 3,
+    SCR1_HDU_DCSR_RSRV0_BIT_L       = 5,
+    SCR1_HDU_DCSR_CAUSE_BIT_R       = 6,
+    SCR1_HDU_DCSR_CAUSE_BIT_L       = 8,
+    SCR1_HDU_DCSR_RSRV1_BIT_R       = 9,
+    SCR1_HDU_DCSR_RSRV1_BIT_L       = 10,
+    SCR1_HDU_DCSR_STEPIE_BIT        = 11,
+    SCR1_HDU_DCSR_RSRV2_BIT_R       = 12,
+    SCR1_HDU_DCSR_RSRV2_BIT_L       = 14,
+    SCR1_HDU_DCSR_EBREAKM_BIT       = 15,
+    SCR1_HDU_DCSR_RSRV3_BIT_R       = 16,
+    SCR1_HDU_DCSR_RSRV3_BIT_L       = 27,
+    SCR1_HDU_DCSR_XDEBUGVER_BIT_R   = 28,
+    SCR1_HDU_DCSR_XDEBUGVER_BIT_L   = 31
+} type_scr1_hdu_dcsr_bits_e;
+
+//localparam int unsigned SCR1_HDU_DEBUGCSR_DCSR_PRV_WIDTH = SCR1_HDU_DCSR_PRV_BIT_L-SCR1_HDU_DCSR_PRV_BIT_R+1;
+
+typedef struct packed {
+    logic [SCR1_HDU_DCSR_XDEBUGVER_BIT_L-SCR1_HDU_DCSR_XDEBUGVER_BIT_R:0]   xdebugver;
+    logic [SCR1_HDU_DCSR_RSRV3_BIT_L-SCR1_HDU_DCSR_RSRV3_BIT_R:0]           rsrv3;
+    logic                                                                   ebreakm;
+    logic [SCR1_HDU_DCSR_RSRV2_BIT_L-SCR1_HDU_DCSR_RSRV2_BIT_R:0]           rsrv2;
+    logic                                                                   stepie;
+    logic [SCR1_HDU_DCSR_RSRV1_BIT_L-SCR1_HDU_DCSR_RSRV1_BIT_R:0]           rsrv1;
+    logic [SCR1_HDU_DCSR_CAUSE_BIT_L-SCR1_HDU_DCSR_CAUSE_BIT_R:0]           cause;
+    logic [SCR1_HDU_DCSR_RSRV0_BIT_L-SCR1_HDU_DCSR_RSRV0_BIT_R:0]           rsrv0;
+    logic                                                                   step;
+    logic [SCR1_HDU_DCSR_PRV_BIT_L-SCR1_HDU_DCSR_PRV_BIT_R:0]               prv;
+} type_scr1_hdu_dcsr_s;
+
+
+`endif // SCR1_INCLUDE_HDU_DEFS
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_ipic.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_ipic.svh
new file mode 100644
index 0000000..4a42dc3
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_ipic.svh
@@ -0,0 +1,58 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_ipic.svh>
+/// @brief      IPIC header file
+///
+
+`ifndef SCR1_IPIC_SVH
+`define SCR1_IPIC_SVH
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_IPIC_EN
+//-------------------------------------------------------------------------------
+// Parameters declaration
+//-------------------------------------------------------------------------------
+parameter                                   SCR1_IRQ_VECT_NUM       = 16;   // must be power of 2 in the current implementation
+parameter                                   SCR1_IRQ_VECT_WIDTH     = $clog2(SCR1_IRQ_VECT_NUM+1);
+parameter                                   SCR1_IRQ_LINES_NUM      = SCR1_IRQ_VECT_NUM;
+parameter                                   SCR1_IRQ_LINES_WIDTH    = $clog2(SCR1_IRQ_LINES_NUM);
+parameter   logic [SCR1_IRQ_VECT_WIDTH-1:0] SCR1_IRQ_VOID_VECT_NUM  = SCR1_IRQ_VECT_WIDTH'(SCR1_IRQ_VECT_NUM);
+parameter                                   SCR1_IRQ_IDX_WIDTH      = $clog2(SCR1_IRQ_VECT_NUM);
+
+// Address decoding parameters
+parameter   logic [2:0]                     SCR1_IPIC_CISV          = 3'h0;    // RO
+parameter   logic [2:0]                     SCR1_IPIC_CICSR         = 3'h1;    // {IP, IE}
+parameter   logic [2:0]                     SCR1_IPIC_IPR           = 3'h2;    // RW1C
+parameter   logic [2:0]                     SCR1_IPIC_ISVR          = 3'h3;    // RO
+parameter   logic [2:0]                     SCR1_IPIC_EOI           = 3'h4;    // RZW
+parameter   logic [2:0]                     SCR1_IPIC_SOI           = 3'h5;    // RZW
+parameter   logic [2:0]                     SCR1_IPIC_IDX           = 3'h6;    // RW
+parameter   logic [2:0]                     SCR1_IPIC_ICSR          = 3'h7;    // RW
+
+parameter                                   SCR1_IPIC_ICSR_IP       = 0;
+parameter                                   SCR1_IPIC_ICSR_IE       = 1;
+parameter                                   SCR1_IPIC_ICSR_IM       = 2;
+parameter                                   SCR1_IPIC_ICSR_INV      = 3;
+parameter                                   SCR1_IPIC_ICSR_IS       = 4;
+parameter                                   SCR1_IPIC_ICSR_PRV_LSB  = 8;
+parameter                                   SCR1_IPIC_ICSR_PRV_MSB  = 9;
+parameter                                   SCR1_IPIC_ICSR_LN_LSB   = 12;
+parameter                                   SCR1_IPIC_ICSR_LN_MSB   = SCR1_IPIC_ICSR_LN_LSB
+                                                                    + SCR1_IRQ_LINES_WIDTH;
+
+parameter   logic [1:0]                     SCR1_IPIC_PRV_M         = 2'b11;
+
+//-------------------------------------------------------------------------------
+// Types declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_CSR2IPIC_RD,
+    SCR1_CSR2IPIC_WR
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_CSR2IPIC_ERROR = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_csr2ipic_wr_e;
+
+`endif // SCR1_IPIC_EN
+`endif // SCR1_IPIC_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_memif.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_memif.svh
new file mode 100644
index 0000000..7235d1d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_memif.svh
@@ -0,0 +1,49 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_memif.svh>
+/// @brief      Memory interface definitions file
+///
+
+`ifndef SCR1_MEMIF_SVH
+`define SCR1_MEMIF_SVH
+
+`include "scr1_arch_description.svh"
+
+//-------------------------------------------------------------------------------
+// Memory command enum
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_MEM_CMD_RD     = 1'b0,
+    SCR1_MEM_CMD_WR     = 1'b1
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_MEM_CMD_ERROR  = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_mem_cmd_e;
+
+//-------------------------------------------------------------------------------
+// Memory data width enum
+//-------------------------------------------------------------------------------
+typedef enum logic[1:0] {
+    SCR1_MEM_WIDTH_BYTE     = 2'b00,
+    SCR1_MEM_WIDTH_HWORD    = 2'b01,
+    SCR1_MEM_WIDTH_WORD     = 2'b10
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_MEM_WIDTH_ERROR    = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_mem_width_e;
+
+//-------------------------------------------------------------------------------
+// Memory response enum
+//-------------------------------------------------------------------------------
+typedef enum logic[1:0] {
+    SCR1_MEM_RESP_NOTRDY    = 2'b00,
+    SCR1_MEM_RESP_RDY_OK    = 2'b01,
+    SCR1_MEM_RESP_RDY_ER    = 2'b10
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_MEM_RESP_ERROR     = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_mem_resp_e;
+
+`endif // SCR1_MEMIF_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_riscv_isa_decoding.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_riscv_isa_decoding.svh
new file mode 100644
index 0000000..e143d89
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_riscv_isa_decoding.svh
@@ -0,0 +1,185 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_riscv_isa_decoding.svh>
+/// @brief      RISC-V ISA definitions file
+///
+
+`ifndef SCR1_RISCV_ISA_DECODING_SVH
+`define SCR1_RISCV_ISA_DECODING_SVH
+
+`include "scr1_arch_description.svh"
+`include "scr1_arch_types.svh"
+
+//-------------------------------------------------------------------------------
+// Instruction types
+//-------------------------------------------------------------------------------
+typedef enum logic [1:0] {
+    SCR1_INSTR_RVC0     = 2'b00,
+    SCR1_INSTR_RVC1     = 2'b01,
+    SCR1_INSTR_RVC2     = 2'b10,
+    SCR1_INSTR_RVI      = 2'b11
+} type_scr1_instr_type_e;
+
+//-------------------------------------------------------------------------------
+// RV32I opcodes (bits 6:2)
+//-------------------------------------------------------------------------------
+typedef enum logic [6:2] {
+    SCR1_OPCODE_LOAD        = 5'b00000,
+    SCR1_OPCODE_MISC_MEM    = 5'b00011,
+    SCR1_OPCODE_OP_IMM      = 5'b00100,
+    SCR1_OPCODE_AUIPC       = 5'b00101,
+    SCR1_OPCODE_STORE       = 5'b01000,
+    SCR1_OPCODE_OP          = 5'b01100,
+    SCR1_OPCODE_LUI         = 5'b01101,
+    SCR1_OPCODE_BRANCH      = 5'b11000,
+    SCR1_OPCODE_JALR        = 5'b11001,
+    SCR1_OPCODE_JAL         = 5'b11011,
+    SCR1_OPCODE_SYSTEM      = 5'b11100
+} type_scr1_rvi_opcode_e;
+
+
+//-------------------------------------------------------------------------------
+// IALU main operands
+//-------------------------------------------------------------------------------
+localparam SCR1_IALU_OP_ALL_NUM_E = 2;
+localparam SCR1_IALU_OP_WIDTH_E   = $clog2(SCR1_IALU_OP_ALL_NUM_E);
+typedef enum logic [SCR1_IALU_OP_WIDTH_E-1:0] {
+    SCR1_IALU_OP_REG_IMM,          // op1 = rs1; op2 = imm
+    SCR1_IALU_OP_REG_REG           // op1 = rs1; op2 = rs2
+} type_scr1_ialu_op_sel_e;
+
+//-------------------------------------------------------------------------------
+// IALU main commands
+//-------------------------------------------------------------------------------
+`ifdef SCR1_RVM_EXT
+localparam SCR1_IALU_CMD_ALL_NUM_E    = 23;
+`else // ~SCR1_RVM_EXT
+localparam SCR1_IALU_CMD_ALL_NUM_E    = 15;
+`endif // ~SCR1_RVM_EXT
+localparam SCR1_IALU_CMD_WIDTH_E      = $clog2(SCR1_IALU_CMD_ALL_NUM_E);
+typedef enum logic [SCR1_IALU_CMD_WIDTH_E-1:0] {
+    SCR1_IALU_CMD_NONE  = '0,   // IALU disable
+    SCR1_IALU_CMD_AND,          // op1 & op2
+    SCR1_IALU_CMD_OR,           // op1 | op2
+    SCR1_IALU_CMD_XOR,          // op1 ^ op2
+    SCR1_IALU_CMD_ADD,          // op1 + op2
+    SCR1_IALU_CMD_SUB,          // op1 - op2
+    SCR1_IALU_CMD_SUB_LT,       // op1 < op2
+    SCR1_IALU_CMD_SUB_LTU,      // op1 u< op2
+    SCR1_IALU_CMD_SUB_EQ,       // op1 = op2
+    SCR1_IALU_CMD_SUB_NE,       // op1 != op2
+    SCR1_IALU_CMD_SUB_GE,       // op1 >= op2
+    SCR1_IALU_CMD_SUB_GEU,      // op1 u>= op2
+    SCR1_IALU_CMD_SLL,          // op1 << op2
+    SCR1_IALU_CMD_SRL,          // op1 >> op2
+    SCR1_IALU_CMD_SRA           // op1 >>> op2
+`ifdef SCR1_RVM_EXT
+    ,
+    SCR1_IALU_CMD_MUL,          // low(unsig(op1) * unsig(op2))
+    SCR1_IALU_CMD_MULHU,        // high(unsig(op1) * unsig(op2))
+    SCR1_IALU_CMD_MULHSU,       // high(op1 * unsig(op2))
+    SCR1_IALU_CMD_MULH,         // high(op1 * op2)
+    SCR1_IALU_CMD_DIV,          // op1 / op2
+    SCR1_IALU_CMD_DIVU,         // op1 u/ op2
+    SCR1_IALU_CMD_REM,          // op1 % op2
+    SCR1_IALU_CMD_REMU          // op1 u% op2
+`endif  // SCR1_RVM_EXT
+} type_scr1_ialu_cmd_sel_e;
+
+//-------------------------------------------------------------------------------
+// IALU SUM2 operands (result is JUMP/BRANCH target, LOAD/STORE address)
+//-------------------------------------------------------------------------------
+localparam SCR1_SUM2_OP_ALL_NUM_E    = 2;
+localparam SCR1_SUM2_OP_WIDTH_E      = $clog2(SCR1_SUM2_OP_ALL_NUM_E);
+typedef enum logic [SCR1_SUM2_OP_WIDTH_E-1:0] {
+    SCR1_SUM2_OP_PC_IMM,        // op1 = curr_pc; op2 = imm (AUIPC, target new_pc for JAL and branches)
+    SCR1_SUM2_OP_REG_IMM        // op1 = rs1; op2 = imm (target new_pc for JALR, LOAD/STORE address)
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_SUM2_OP_ERROR = 'x
+`endif // SCR1_XPROP_EN
+} type_scr1_ialu_sum2_op_sel_e;
+
+//-------------------------------------------------------------------------------
+// LSU commands
+//-------------------------------------------------------------------------------
+localparam SCR1_LSU_CMD_ALL_NUM_E   = 9;
+localparam SCR1_LSU_CMD_WIDTH_E     = $clog2(SCR1_LSU_CMD_ALL_NUM_E);
+typedef enum logic [SCR1_LSU_CMD_WIDTH_E-1:0] {
+    SCR1_LSU_CMD_NONE = '0,
+    SCR1_LSU_CMD_LB,
+    SCR1_LSU_CMD_LH,
+    SCR1_LSU_CMD_LW,
+    SCR1_LSU_CMD_LBU,
+    SCR1_LSU_CMD_LHU,
+    SCR1_LSU_CMD_SB,
+    SCR1_LSU_CMD_SH,
+    SCR1_LSU_CMD_SW
+} type_scr1_lsu_cmd_sel_e;
+
+//-------------------------------------------------------------------------------
+// CSR operands
+//-------------------------------------------------------------------------------
+localparam SCR1_CSR_OP_ALL_NUM_E   = 2;
+localparam SCR1_CSR_OP_WIDTH_E     = $clog2(SCR1_CSR_OP_ALL_NUM_E);
+typedef enum logic [SCR1_CSR_OP_WIDTH_E-1:0] {
+    SCR1_CSR_OP_IMM,
+    SCR1_CSR_OP_REG
+} type_scr1_csr_op_sel_e;
+
+//-------------------------------------------------------------------------------
+// CSR commands
+//-------------------------------------------------------------------------------
+localparam SCR1_CSR_CMD_ALL_NUM_E   = 4;
+localparam SCR1_CSR_CMD_WIDTH_E     = $clog2(SCR1_CSR_CMD_ALL_NUM_E);
+typedef enum logic [SCR1_CSR_CMD_WIDTH_E-1:0] {
+    SCR1_CSR_CMD_NONE = '0,
+    SCR1_CSR_CMD_WRITE,
+    SCR1_CSR_CMD_SET,
+    SCR1_CSR_CMD_CLEAR
+} type_scr1_csr_cmd_sel_e;
+
+//-------------------------------------------------------------------------------
+// MPRF rd writeback source
+//-------------------------------------------------------------------------------
+localparam SCR1_RD_WB_ALL_NUM_E = 7;
+localparam SCR1_RD_WB_WIDTH_E   = $clog2(SCR1_RD_WB_ALL_NUM_E);
+typedef enum logic [SCR1_RD_WB_WIDTH_E-1:0] {
+    SCR1_RD_WB_NONE = '0,
+    SCR1_RD_WB_IALU,            // IALU main result
+    SCR1_RD_WB_SUM2,            // IALU SUM2 result (AUIPC)
+    SCR1_RD_WB_IMM,             // LUI
+    SCR1_RD_WB_INC_PC,          // JAL(R)
+    SCR1_RD_WB_LSU,             // Load from DMEM
+    SCR1_RD_WB_CSR              // Read CSR
+} type_scr1_rd_wb_sel_e;
+
+//-------------------------------------------------------------------------------
+// IDU to EXU full command structure
+//-------------------------------------------------------------------------------
+localparam SCR1_GPR_FIELD_WIDTH = 5;
+
+typedef struct packed {
+    logic                               instr_rvc;      // used with a different meaning for IFU access fault exception
+    type_scr1_ialu_op_sel_e             ialu_op;
+    type_scr1_ialu_cmd_sel_e            ialu_cmd;
+    type_scr1_ialu_sum2_op_sel_e        sum2_op;
+    type_scr1_lsu_cmd_sel_e             lsu_cmd;
+    type_scr1_csr_op_sel_e              csr_op;
+    type_scr1_csr_cmd_sel_e             csr_cmd;
+    type_scr1_rd_wb_sel_e               rd_wb_sel;
+    logic                               jump_req;
+    logic                               branch_req;
+    logic                               mret_req;
+    logic                               fencei_req;
+    logic                               wfi_req;
+    logic [SCR1_GPR_FIELD_WIDTH-1:0]    rs1_addr;       // also used as zimm for CSRRxI instructions
+    logic [SCR1_GPR_FIELD_WIDTH-1:0]    rs2_addr;
+    logic [SCR1_GPR_FIELD_WIDTH-1:0]    rd_addr;
+    logic [`SCR1_XLEN-1:0]              imm;            // used as {funct3, CSR address} for CSR instructions
+                                                        // used as instruction field for illegal instruction exception
+    logic                               exc_req;
+    type_scr1_exc_code_e                exc_code;
+} type_scr1_exu_cmd_s;
+
+`endif // SCR1_RISCV_ISA_DECODING_SVH
+
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_scu.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_scu.svh
new file mode 100644
index 0000000..ab19386
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_scu.svh
@@ -0,0 +1,84 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_scu.svh>
+/// @brief      SCU header file
+///
+
+`ifndef SCR1_INCLUDE_SCU_DEFS
+`define SCR1_INCLUDE_SCU_DEFS
+
+//`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+
+//==============================================================================
+// Parameters
+//==============================================================================
+localparam int unsigned         SCR1_SCU_DR_SYSCTRL_OP_WIDTH        = 2;
+localparam int unsigned         SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH      = 2;
+localparam int unsigned         SCR1_SCU_DR_SYSCTRL_DATA_WIDTH      = 4;
+
+//==============================================================================
+// Types
+//==============================================================================
+typedef enum logic [SCR1_SCU_DR_SYSCTRL_OP_WIDTH-1:0] {
+    SCR1_SCU_SYSCTRL_OP_WRITE       = 2'h0,
+    SCR1_SCU_SYSCTRL_OP_READ        = 2'h1,
+    SCR1_SCU_SYSCTRL_OP_SETBITS     = 2'h2,
+    SCR1_SCU_SYSCTRL_OP_CLRBITS     = 2'h3
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_SCU_SYSCTRL_OP_XXX         = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_scu_sysctrl_op_e;
+
+typedef enum logic [SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH-1:0] {
+    SCR1_SCU_SYSCTRL_ADDR_CONTROL   = 2'h0,
+    SCR1_SCU_SYSCTRL_ADDR_MODE      = 2'h1,
+    SCR1_SCU_SYSCTRL_ADDR_STATUS    = 2'h2,
+    SCR1_SCU_SYSCTRL_ADDR_STICKY    = 2'h3
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_SCU_SYSCTRL_ADDR_XXX       = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_scu_sysctrl_addr_e;
+
+typedef struct packed {
+    logic [SCR1_SCU_DR_SYSCTRL_DATA_WIDTH-1:0]  data;
+    logic [SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH-1:0]  addr;
+    logic [SCR1_SCU_DR_SYSCTRL_OP_WIDTH-1:0]    op;
+} type_scr1_scu_sysctrl_dr_s;
+
+typedef enum int unsigned {
+    SCR1_SCU_DR_SYSCTRL_OP_BIT_R                  = 'h0,
+    SCR1_SCU_DR_SYSCTRL_OP_BIT_L                  = SCR1_SCU_DR_SYSCTRL_OP_WIDTH-1,
+    SCR1_SCU_DR_SYSCTRL_ADDR_BIT_R                = SCR1_SCU_DR_SYSCTRL_OP_WIDTH,
+    SCR1_SCU_DR_SYSCTRL_ADDR_BIT_L                = SCR1_SCU_DR_SYSCTRL_OP_WIDTH +
+                                                    SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH - 1,
+    SCR1_SCU_DR_SYSCTRL_DATA_BIT_R                = SCR1_SCU_DR_SYSCTRL_OP_WIDTH +
+                                                    SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH,
+    SCR1_SCU_DR_SYSCTRL_DATA_BIT_L                = SCR1_SCU_DR_SYSCTRL_OP_WIDTH +
+                                                    SCR1_SCU_DR_SYSCTRL_ADDR_WIDTH +
+                                                    SCR1_SCU_DR_SYSCTRL_DATA_WIDTH - 1
+} type_scr1_scu_sysctrl_dr_bits_e;
+
+typedef struct packed {
+    logic [1:0]                                     rsrv;
+    logic                                           core_reset;
+    logic                                           sys_reset;
+} type_scr1_scu_sysctrl_control_reg_s;
+
+typedef struct packed {
+    logic [1:0]                                     rsrv;
+    logic                                           hdu_rst_bhv;
+    logic                                           dm_rst_bhv;
+} type_scr1_scu_sysctrl_mode_reg_s;
+
+typedef struct packed {
+    logic                                           hdu_reset;
+    logic                                           dm_reset;
+    logic                                           core_reset;
+    logic                                           sys_reset;
+} type_scr1_scu_sysctrl_status_reg_s;
+
+`endif // SCR1_DBG_EN
+`endif // SCR1_INCLUDE_SCU_DEFS
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_search_ms1.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_search_ms1.svh
new file mode 100644
index 0000000..fc516ba
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_search_ms1.svh
@@ -0,0 +1,94 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_search_ms1.svh>
+/// @brief      Most significant one search function
+///
+
+`ifndef SCR1_SEARCH_MS1_SVH
+`define SCR1_SEARCH_MS1_SVH
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef struct {
+    logic       vd;
+    logic       idx;
+} type_scr1_search_one_2_s;
+
+typedef struct {
+    logic           vd;
+    logic [4:0]     idx;
+} type_scr1_search_one_32_s;
+
+//-------------------------------------------------------------------------------
+// Leading Zeros Count Function
+//-------------------------------------------------------------------------------
+function automatic type_scr1_search_one_2_s scr1_lead_zeros_cnt_2(
+    input   logic [1:0]     din
+);
+    type_scr1_search_one_2_s tmp;
+begin
+    tmp.vd  = |din;
+    tmp.idx = ~din[1];
+    return  tmp;
+end
+endfunction : scr1_lead_zeros_cnt_2
+
+function automatic logic [4:0] scr1_lead_zeros_cnt_32(
+    input   logic [31:0]    din
+);
+begin
+    logic [15:0]    stage1_vd;
+    logic [7:0]     stage2_vd;
+    logic [3:0]     stage3_vd;
+    logic [1:0]     stage4_vd;
+
+    logic           stage1_idx [15:0];
+    logic [1:0]     stage2_idx [7:0];
+    logic [2:0]     stage3_idx [3:0];
+    logic [3:0]     stage4_idx [1:0];
+    type_scr1_search_one_32_s tmp;
+    logic [4:0]     res;
+
+    // Stage 1
+    for (int unsigned i=0; i<16; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_lead_zeros_cnt_2(din[(i+1)*2-1-:2]);
+        stage1_vd[i]  = tmp.vd;
+        stage1_idx[i] = tmp.idx;
+    end
+
+    // Stage 2
+    for (int unsigned i=0; i<8; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_lead_zeros_cnt_2(stage1_vd[(i+1)*2-1-:2]);
+        stage2_vd[i]  = tmp.vd;
+        stage2_idx[i] = (tmp.idx) ? {tmp.idx, stage1_idx[2*i]} : {tmp.idx, stage1_idx[2*i+1]};
+    end
+
+    // Stage 3
+    for (int unsigned i=0; i<4; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_lead_zeros_cnt_2(stage2_vd[(i+1)*2-1-:2]);
+        stage3_vd[i]  = tmp.vd;
+        stage3_idx[i] = (tmp.idx) ? {tmp.idx, stage2_idx[2*i]} : {tmp.idx, stage2_idx[2*i+1]};
+    end
+
+    // Stage 4
+    for (int unsigned i=0; i<2; ++i) begin
+        type_scr1_search_one_2_s tmp;
+        tmp = scr1_lead_zeros_cnt_2(stage3_vd[(i+1)*2-1-:2]);
+        stage4_vd[i]  = tmp.vd;
+        stage4_idx[i] = (tmp.idx) ? {tmp.idx, stage3_idx[2*i]} : {tmp.idx, stage3_idx[2*i+1]};
+    end
+
+    // Stage 5
+    tmp.vd = |stage4_vd;
+    tmp.idx = (stage4_vd[1]) ? {1'b0, stage4_idx[1]} : {1'b1, stage4_idx[0]};
+
+    res = tmp.idx;
+
+    return res;
+end
+endfunction : scr1_lead_zeros_cnt_32
+
+`endif // SCR1_SEARCH_MS1_SVH
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_tapc.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_tapc.svh
new file mode 100644
index 0000000..e96ea44
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_tapc.svh
@@ -0,0 +1,66 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_tapc.svh>
+/// @brief      TAPC header file
+///
+
+`ifndef SCR1_INCLUDE_TAPC_DEFS
+`define SCR1_INCLUDE_TAPC_DEFS
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_DBG_EN
+
+//==============================================================================
+// Parameters
+//==============================================================================
+localparam int unsigned                         SCR1_TAP_STATE_WIDTH            = 4;
+localparam int unsigned                         SCR1_TAP_INSTRUCTION_WIDTH      = 5;
+localparam int unsigned                         SCR1_TAP_DR_IDCODE_WIDTH        = 32;
+localparam int unsigned                         SCR1_TAP_DR_BLD_ID_WIDTH        = 32;
+localparam int unsigned                         SCR1_TAP_DR_BYPASS_WIDTH        = 1;
+//localparam bit [SCR1_TAP_DR_IDCODE_WIDTH-1:0]   SCR1_TAP_IDCODE_RISCV_SC        = `SCR1_TAP_IDCODE;
+localparam bit [SCR1_TAP_DR_BLD_ID_WIDTH-1:0]   SCR1_TAP_BLD_ID_VALUE           = `SCR1_MIMPID;
+
+//==============================================================================
+// Types
+//==============================================================================
+typedef enum logic [SCR1_TAP_STATE_WIDTH-1:0] {
+    SCR1_TAP_STATE_RESET,
+    SCR1_TAP_STATE_IDLE,
+    SCR1_TAP_STATE_DR_SEL_SCAN,
+    SCR1_TAP_STATE_DR_CAPTURE,
+    SCR1_TAP_STATE_DR_SHIFT,
+    SCR1_TAP_STATE_DR_EXIT1,
+    SCR1_TAP_STATE_DR_PAUSE,
+    SCR1_TAP_STATE_DR_EXIT2,
+    SCR1_TAP_STATE_DR_UPDATE,
+    SCR1_TAP_STATE_IR_SEL_SCAN,
+    SCR1_TAP_STATE_IR_CAPTURE,
+    SCR1_TAP_STATE_IR_SHIFT,
+    SCR1_TAP_STATE_IR_EXIT1,
+    SCR1_TAP_STATE_IR_PAUSE,
+    SCR1_TAP_STATE_IR_EXIT2,
+    SCR1_TAP_STATE_IR_UPDATE
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_TAP_STATE_XXX       = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_tap_state_e;
+
+typedef enum logic [SCR1_TAP_INSTRUCTION_WIDTH - 1:0] {
+    SCR1_TAP_INSTR_IDCODE            = 5'h01,
+    SCR1_TAP_INSTR_BLD_ID            = 5'h04,
+    SCR1_TAP_INSTR_SCU_ACCESS        = 5'h09,
+
+    SCR1_TAP_INSTR_DTMCS             = 5'h10,
+    SCR1_TAP_INSTR_DMI_ACCESS        = 5'h11,
+
+    SCR1_TAP_INSTR_BYPASS            = 5'h1F
+`ifdef SCR1_XPROP_EN
+    ,
+    SCR1_TAP_INSTR_XXX               = 'X
+`endif // SCR1_XPROP_EN
+} type_scr1_tap_instr_e;
+
+`endif // SCR1_DBG_EN
+`endif // SCR1_INCLUDE_TAPC_DEFS
diff --git a/verilog/rtl/syntacore_scr1/src/includes/scr1_tdu.svh b/verilog/rtl/syntacore_scr1/src/includes/scr1_tdu.svh
new file mode 100644
index 0000000..79382cf
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/includes/scr1_tdu.svh
@@ -0,0 +1,121 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_tdu.svh>
+/// @brief      Trigger Debug Module header
+///
+
+`ifndef SCR1_INCLUDE_TDU_DEFS
+`define SCR1_INCLUDE_TDU_DEFS
+
+//`include "scr1_arch_description.svh"
+
+`ifdef SCR1_TDU_EN
+//`include "scr1_csr.svh"
+
+`include "scr1_arch_description.svh"
+//`include "scr1_arch_types.svh"
+`include "scr1_csr.svh"
+
+parameter int unsigned  SCR1_TDU_MTRIG_NUM             = SCR1_TDU_TRIG_NUM;
+`ifdef SCR1_TDU_ICOUNT_EN
+parameter int unsigned  SCR1_TDU_ALLTRIG_NUM           = SCR1_TDU_MTRIG_NUM + 1'b1;
+`else
+parameter int unsigned  SCR1_TDU_ALLTRIG_NUM           = SCR1_TDU_MTRIG_NUM;
+`endif
+
+parameter int unsigned  SCR1_TDU_ADDR_W                = `SCR1_XLEN;
+parameter int unsigned  SCR1_TDU_DATA_W                = `SCR1_XLEN;
+
+// Register map
+parameter                                     SCR1_CSR_ADDR_TDU_OFFS_W        = 3;
+parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]  SCR1_CSR_ADDR_TDU_OFFS_TSELECT  = 'h0;
+parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]  SCR1_CSR_ADDR_TDU_OFFS_TDATA1   = 'h1;
+parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]  SCR1_CSR_ADDR_TDU_OFFS_TDATA2   = 'h2;
+parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0]  SCR1_CSR_ADDR_TDU_OFFS_TINFO    = 'h4;
+
+
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TSELECT       = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TSELECT;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA1        = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA1;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA2        = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA2;
+parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TINFO         = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TINFO;
+
+// TDATA1
+parameter int unsigned  SCR1_TDU_TDATA1_TYPE_HI        = `SCR1_XLEN-1;
+parameter int unsigned  SCR1_TDU_TDATA1_TYPE_LO        = `SCR1_XLEN-4;
+parameter int unsigned  SCR1_TDU_TDATA1_DMODE          = `SCR1_XLEN-5;
+
+// TDATA1: constant bits values
+parameter bit           SCR1_TDU_TDATA1_DMODE_VAL      = 1'b0;
+
+// MCONTROL: bits number
+parameter int unsigned  SCR1_TDU_MCONTROL_MASKMAX_HI   = `SCR1_XLEN-6;
+parameter int unsigned  SCR1_TDU_MCONTROL_MASKMAX_LO   = `SCR1_XLEN-11;
+parameter int unsigned  SCR1_TDU_MCONTROL_RESERVEDB_HI = `SCR1_XLEN-12;
+parameter int unsigned  SCR1_TDU_MCONTROL_RESERVEDB_LO = 21;
+parameter int unsigned  SCR1_TDU_MCONTROL_HIT          = 20;
+parameter int unsigned  SCR1_TDU_MCONTROL_SELECT       = 19;
+parameter int unsigned  SCR1_TDU_MCONTROL_TIMING       = 18;
+parameter int unsigned  SCR1_TDU_MCONTROL_ACTION_HI    = 17;
+parameter int unsigned  SCR1_TDU_MCONTROL_ACTION_LO    = 12;
+parameter int unsigned  SCR1_TDU_MCONTROL_CHAIN        = 11;
+parameter int unsigned  SCR1_TDU_MCONTROL_MATCH_HI     = 10;
+parameter int unsigned  SCR1_TDU_MCONTROL_MATCH_LO     = 7;
+parameter int unsigned  SCR1_TDU_MCONTROL_M            = 6;
+parameter int unsigned  SCR1_TDU_MCONTROL_RESERVEDA    = 5;
+parameter int unsigned  SCR1_TDU_MCONTROL_S            = 4;
+parameter int unsigned  SCR1_TDU_MCONTROL_U            = 3;
+parameter int unsigned  SCR1_TDU_MCONTROL_EXECUTE      = 2;
+parameter int unsigned  SCR1_TDU_MCONTROL_STORE        = 1;
+parameter int unsigned  SCR1_TDU_MCONTROL_LOAD         = 0;
+
+// MCONTROL: constant bits values
+parameter bit [SCR1_TDU_TDATA1_TYPE_HI-SCR1_TDU_TDATA1_TYPE_LO:0]
+                        SCR1_TDU_MCONTROL_TYPE_VAL           = 2'd2;
+
+parameter bit           SCR1_TDU_MCONTROL_SELECT_VAL         = 1'b0;
+parameter bit           SCR1_TDU_MCONTROL_TIMING_VAL         = 1'b0;
+
+parameter bit [SCR1_TDU_MCONTROL_MASKMAX_HI-SCR1_TDU_MCONTROL_MASKMAX_LO:0]
+                        SCR1_TDU_MCONTROL_MASKMAX_VAL        = 1'b0;
+
+parameter bit           SCR1_TDU_MCONTROL_RESERVEDA_VAL      = 1'b0;
+
+// ICOUNT: bits number
+parameter int unsigned  SCR1_TDU_ICOUNT_DMODE          = `SCR1_XLEN-5;
+parameter int unsigned  SCR1_TDU_ICOUNT_RESERVEDB_HI   = `SCR1_XLEN-6;
+parameter int unsigned  SCR1_TDU_ICOUNT_RESERVEDB_LO   = 25;
+parameter int unsigned  SCR1_TDU_ICOUNT_HIT            = 24;
+parameter int unsigned  SCR1_TDU_ICOUNT_COUNT_HI       = 23;
+parameter int unsigned  SCR1_TDU_ICOUNT_COUNT_LO       = 10;
+parameter int unsigned  SCR1_TDU_ICOUNT_M              = 9;
+parameter int unsigned  SCR1_TDU_ICOUNT_RESERVEDA      = 8;
+parameter int unsigned  SCR1_TDU_ICOUNT_S              = 7;
+parameter int unsigned  SCR1_TDU_ICOUNT_U              = 6;
+parameter int unsigned  SCR1_TDU_ICOUNT_ACTION_HI      = 5;
+parameter int unsigned  SCR1_TDU_ICOUNT_ACTION_LO      = 0;
+
+// ICOUNT: constant bits values
+parameter bit [SCR1_TDU_TDATA1_TYPE_HI-SCR1_TDU_TDATA1_TYPE_LO:0]
+                        SCR1_TDU_ICOUNT_TYPE_VAL             = 2'd3;
+
+parameter bit [SCR1_TDU_ICOUNT_RESERVEDB_HI-SCR1_TDU_ICOUNT_RESERVEDB_LO:0]
+                        SCR1_TDU_ICOUNT_RESERVEDB_VAL        = 1'b0;
+
+parameter bit           SCR1_TDU_ICOUNT_RESERVEDA_VAL        = 1'b0;
+
+// CPU pipeline monitors
+typedef struct packed {
+    logic                                           vd;
+    logic                                           req;
+    logic [`SCR1_XLEN-1:0]                          addr;
+} type_scr1_brkm_instr_mon_s;
+
+typedef struct packed {
+    logic                                           vd;
+    logic                                           load;
+    logic                                           store;
+    logic [`SCR1_XLEN-1:0]                          addr;
+} type_scr1_brkm_lsu_mon_s;
+
+`endif // SCR1_TDU_EN
+
+`endif // SCR1_INCLUDE_TDU_DEFS
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_ahb.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_ahb.sv
new file mode 100644
index 0000000..1a413d5
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_ahb.sv
@@ -0,0 +1,466 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_dmem_ahb.sv>
+/// @brief      Data memory AHB bridge
+///
+
+`include "scr1_ahb.svh"
+`include "scr1_memif.svh"
+
+module scr1_dmem_ahb (
+    // Control Signals
+    input   logic                           rst_n,
+    input   logic                           clk,
+
+    // Core Interface
+    output  logic                           dmem_req_ack,
+    input   logic                           dmem_req,
+    input   type_scr1_mem_cmd_e             dmem_cmd,
+    input   type_scr1_mem_width_e           dmem_width,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    dmem_addr,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    dmem_wdata,
+    output  logic   [SCR1_AHB_WIDTH-1:0]    dmem_rdata,
+    output  type_scr1_mem_resp_e            dmem_resp,
+
+    // AHB Interface
+    output  logic   [3:0]                   hprot,
+    output  logic   [2:0]                   hburst,
+    output  logic   [2:0]                   hsize,
+    output  logic   [1:0]                   htrans,
+    output  logic                           hmastlock,
+    output  logic   [SCR1_AHB_WIDTH-1:0]    haddr,
+    output  logic                           hwrite,
+    output  logic   [SCR1_AHB_WIDTH-1:0]    hwdata,
+    input   logic                           hready,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    hrdata,
+    input   logic                           hresp
+
+);
+
+//-------------------------------------------------------------------------------
+// Local Parameters
+//-------------------------------------------------------------------------------
+`ifndef SCR1_DMEM_AHB_OUT_BP
+localparam  SCR1_FIFO_WIDTH = 2;
+localparam  SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
+`endif // SCR1_DMEM_AHB_OUT_BP
+
+//-------------------------------------------------------------------------------
+// Local type declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_FSM_ADDR = 1'b0,
+    SCR1_FSM_DATA = 1'b1,
+    SCR1_FSM_ERR  = 1'bx
+} type_scr1_fsm_e;
+
+typedef struct packed {
+    logic                           hwrite;
+    logic   [2:0]                   hwidth;
+    logic   [SCR1_AHB_WIDTH-1:0]    haddr;
+    logic   [SCR1_AHB_WIDTH-1:0]    hwdata;
+} type_scr1_req_fifo_s;
+
+typedef struct packed {
+    logic                           hwrite;
+    logic   [2:0]                   hwidth;
+    logic   [1:0]                   haddr;
+    logic   [SCR1_AHB_WIDTH-1:0]    hwdata;
+} type_scr1_data_fifo_s;
+
+typedef struct packed {
+    logic                           hresp;
+    logic   [2:0]                   hwidth;
+    logic   [1:0]                   haddr;
+    logic   [SCR1_AHB_WIDTH-1:0]    hrdata;
+} type_scr1_resp_fifo_s;
+
+//-------------------------------------------------------------------------------
+// Local functions
+//-------------------------------------------------------------------------------
+function automatic logic   [2:0] scr1_conv_mem2ahb_width (
+    input   type_scr1_mem_width_e    dmem_width
+);
+    logic   [2:0]   tmp;
+begin
+    case (dmem_width)
+        SCR1_MEM_WIDTH_BYTE : begin
+            tmp = SCR1_HSIZE_8B;
+        end
+        SCR1_MEM_WIDTH_HWORD : begin
+            tmp = SCR1_HSIZE_16B;
+        end
+        SCR1_MEM_WIDTH_WORD : begin
+            tmp = SCR1_HSIZE_32B;
+        end
+        default : begin
+            tmp = SCR1_HSIZE_ERR;
+        end
+    endcase
+    return tmp;
+end
+endfunction : scr1_conv_mem2ahb_width
+
+function automatic logic[SCR1_AHB_WIDTH-1:0] scr1_conv_mem2ahb_wdata (
+    input   logic   [1:0]                   dmem_addr,
+    input   type_scr1_mem_width_e           dmem_width,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    dmem_wdata
+);
+    logic   [SCR1_AHB_WIDTH-1:0]  tmp;
+begin
+    tmp = 'x;
+    case (dmem_width)
+        SCR1_MEM_WIDTH_BYTE : begin
+            case (dmem_addr)
+                2'b00 : begin
+                    tmp[7:0]   = dmem_wdata[7:0];
+                end
+                2'b01 : begin
+                    tmp[15:8]  = dmem_wdata[7:0];
+                end
+                2'b10 : begin
+                    tmp[23:16] = dmem_wdata[7:0];
+                end
+                2'b11 : begin
+                    tmp[31:24] = dmem_wdata[7:0];
+                end
+                default : begin
+                end
+            endcase
+        end
+        SCR1_MEM_WIDTH_HWORD : begin
+            case (dmem_addr[1])
+                1'b0 : begin
+                    tmp[15:0]  = dmem_wdata[15:0];
+                end
+                1'b1 : begin
+                    tmp[31:16] = dmem_wdata[15:0];
+                end
+                default : begin
+                end
+            endcase
+        end
+        SCR1_MEM_WIDTH_WORD : begin
+            tmp = dmem_wdata;
+        end
+        default : begin
+        end
+    endcase
+    return tmp;
+end
+endfunction : scr1_conv_mem2ahb_wdata
+
+function automatic logic[SCR1_AHB_WIDTH-1:0] scr1_conv_ahb2mem_rdata (
+    input   logic [2:0]                 hwidth,
+    input   logic [1:0]                 haddr,
+    input   logic [SCR1_AHB_WIDTH-1:0]  hrdata
+);
+    logic   [SCR1_AHB_WIDTH-1:0]  tmp;
+begin
+    tmp = 'x;
+    case (hwidth)
+        SCR1_HSIZE_8B : begin
+            case (haddr)
+                2'b00 : tmp[7:0] = hrdata[7:0];
+                2'b01 : tmp[7:0] = hrdata[15:8];
+                2'b10 : tmp[7:0] = hrdata[23:16];
+                2'b11 : tmp[7:0] = hrdata[31:24];
+                default : begin
+                end
+            endcase
+        end
+        SCR1_HSIZE_16B : begin
+            case (haddr[1])
+                1'b0 : tmp[15:0] = hrdata[15:0];
+                1'b1 : tmp[15:0] = hrdata[31:16];
+                default : begin
+                end
+            endcase
+        end
+        SCR1_HSIZE_32B : begin
+            tmp = hrdata;
+        end
+        default : begin
+        end
+    endcase
+    return tmp;
+end
+endfunction : scr1_conv_ahb2mem_rdata
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+type_scr1_fsm_e                             fsm;
+logic                                       req_fifo_rd;
+logic                                       req_fifo_wr;
+logic                                       req_fifo_up;
+`ifdef SCR1_DMEM_AHB_OUT_BP
+type_scr1_req_fifo_s                        req_fifo_new;
+type_scr1_req_fifo_s                        req_fifo_r;
+type_scr1_req_fifo_s [0:0]                  req_fifo;
+`else // SCR1_DMEM_AHB_OUT_BP
+type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo;
+type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo_new;
+logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt;
+logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt_new;
+`endif // SCR1_DMEM_AHB_OUT_BP
+logic                                       req_fifo_empty;
+logic                                       req_fifo_full;
+
+type_scr1_data_fifo_s                       data_fifo;
+type_scr1_resp_fifo_s                       resp_fifo;
+logic                                       resp_fifo_hready;
+
+//-------------------------------------------------------------------------------
+// Interface to Core
+//-------------------------------------------------------------------------------
+assign dmem_req_ack = ~req_fifo_full;
+assign req_fifo_wr  = ~req_fifo_full & dmem_req;
+
+assign dmem_rdata = scr1_conv_ahb2mem_rdata(resp_fifo.hwidth, resp_fifo.haddr, resp_fifo.hrdata);
+
+assign dmem_resp = (resp_fifo_hready)
+                    ? (resp_fifo.hresp == SCR1_HRESP_OKAY)
+                        ? SCR1_MEM_RESP_RDY_OK
+                        : SCR1_MEM_RESP_RDY_ER
+                    : SCR1_MEM_RESP_NOTRDY ;
+
+//-------------------------------------------------------------------------------
+// REQ_FIFO
+//-------------------------------------------------------------------------------
+`ifdef SCR1_DMEM_AHB_OUT_BP
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_fifo_full <= 1'b0;
+    end else begin
+        if (~req_fifo_full) begin
+            req_fifo_full <= dmem_req & ~req_fifo_rd;
+        end else begin
+            req_fifo_full <= ~req_fifo_rd;
+        end
+    end
+end
+assign req_fifo_empty = ~(req_fifo_full | dmem_req);
+
+assign req_fifo_up = ~req_fifo_rd & req_fifo_wr;
+always_ff @(posedge clk) begin
+    if (req_fifo_up) begin
+        req_fifo_r <= req_fifo_new;
+    end
+end
+
+assign req_fifo_new.hwrite = dmem_req ? (dmem_cmd == SCR1_MEM_CMD_WR)       : 1'b0;
+assign req_fifo_new.hwidth = dmem_req ? scr1_conv_mem2ahb_width(dmem_width) : '0;
+assign req_fifo_new.haddr  = dmem_req ? dmem_addr                           : '0;
+assign req_fifo_new.hwdata = (dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR))
+                                ? scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata)
+                                : '0;
+assign req_fifo[0] = (req_fifo_full) ? req_fifo_r: req_fifo_new;
+
+`else // SCR1_DMEM_AHB_OUT_BP
+always_comb begin
+    req_fifo_up      = 1'b0;
+    req_fifo_cnt_new = req_fifo_cnt;
+    req_fifo_new     = req_fifo;
+    case ({req_fifo_rd, req_fifo_wr})
+        2'b00 : begin
+            // nothing todo
+        end
+        2'b01: begin
+            // FIFO write
+            req_fifo_up = 1'b1;
+            req_fifo_new[req_fifo_cnt].hwrite = (dmem_cmd == SCR1_MEM_CMD_WR);
+            req_fifo_new[req_fifo_cnt].hwidth = scr1_conv_mem2ahb_width(dmem_width);
+            req_fifo_new[req_fifo_cnt].haddr  = dmem_addr;
+            req_fifo_new[req_fifo_cnt].hwdata = scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata);
+            req_fifo_cnt_new = req_fifo_cnt + 1'b1;
+        end
+        2'b10 : begin
+            // FIFO read
+            req_fifo_up = 1'b1;
+            req_fifo_new[0] = req_fifo_new[1];
+            req_fifo_new[1].hwrite = 1'b0;
+            req_fifo_new[1].hwidth = SCR1_HSIZE_32B;
+            req_fifo_new[1].haddr  = 'x;
+            req_fifo_new[1].hwdata = 'x;
+            req_fifo_cnt_new = req_fifo_cnt - 1'b1;
+        end
+        2'b11 : begin
+            // Read and Write FIFO. It is possible only when fifo_cnt = 1
+            req_fifo_up = 1'b1;
+            req_fifo_new[0].hwrite = (dmem_cmd == SCR1_MEM_CMD_WR);
+            req_fifo_new[0].hwidth = scr1_conv_mem2ahb_width(dmem_width);
+            req_fifo_new[0].haddr  = dmem_addr;
+            req_fifo_new[0].hwdata = scr1_conv_mem2ahb_wdata(dmem_addr[1:0], dmem_width, dmem_wdata);
+        end
+        default : begin
+            req_fifo_up      = 'x;
+            req_fifo_cnt_new = 'x;
+            req_fifo_new     = 'x;
+        end
+    endcase
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_fifo_cnt <= '0;
+    end else begin
+        if (req_fifo_up) begin
+            req_fifo_cnt <= req_fifo_cnt_new;
+        end
+    end
+end
+assign req_fifo_full  = (req_fifo_cnt == SCR1_FIFO_WIDTH);
+assign req_fifo_empty = ~(|req_fifo_cnt);
+
+always_ff @(posedge clk) begin
+    if (req_fifo_up) begin
+        req_fifo <= req_fifo_new;
+    end
+end
+`endif // SCR1_DMEM_AHB_OUT_BP
+//-------------------------------------------------------------------------------
+// FSM
+//-------------------------------------------------------------------------------
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        fsm <= SCR1_FSM_ADDR;
+    end else begin
+        case (fsm)
+            SCR1_FSM_ADDR : begin
+                if (hready) begin
+                    fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
+                end
+            end
+            SCR1_FSM_DATA : begin
+                if (hready) begin
+                    if (hresp == SCR1_HRESP_OKAY) begin
+                        fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
+                    end else begin
+                        fsm <= SCR1_FSM_ADDR;
+                    end
+                end
+            end
+            default : begin
+                fsm <= SCR1_FSM_ERR;
+            end
+        endcase
+    end
+end
+
+always_comb begin
+    req_fifo_rd = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            if (hready) begin
+                req_fifo_rd = ~req_fifo_empty;
+            end
+        end
+        SCR1_FSM_DATA : begin
+            if (hready) begin
+                req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
+            end
+        end
+        default : begin
+            req_fifo_rd = 1'bx;
+        end
+    endcase
+end
+
+//-------------------------------------------------------------------------------
+// FIFO data
+//-------------------------------------------------------------------------------
+always_ff @(posedge clk) begin
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            if (~req_fifo_empty) begin
+                data_fifo.hwrite <= req_fifo[0].hwrite;
+                data_fifo.hwidth <= req_fifo[0].hwidth;
+                data_fifo.haddr  <= req_fifo[0].haddr[1:0];
+                data_fifo.hwdata <= req_fifo[0].hwdata;
+            end
+        end
+        SCR1_FSM_DATA : begin
+            if (hready) begin
+                if (hresp == SCR1_HRESP_OKAY) begin
+                    if (~req_fifo_empty) begin
+                        data_fifo.hwrite <= req_fifo[0].hwrite;
+                        data_fifo.hwidth <= req_fifo[0].hwidth;
+                        data_fifo.haddr  <= req_fifo[0].haddr[1:0];
+                        data_fifo.hwdata <= req_fifo[0].hwdata;
+                    end
+                end
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+//-------------------------------------------------------------------------------
+// FIFO response
+//-------------------------------------------------------------------------------
+`ifdef SCR1_DMEM_AHB_IN_BP
+assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
+assign resp_fifo.hresp  = hresp;
+assign resp_fifo.hwidth = data_fifo.hwidth;
+assign resp_fifo.haddr  = data_fifo.haddr;
+assign resp_fifo.hrdata = hrdata;
+`else // SCR1_DMEM_AHB_IN_BP
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        resp_fifo_hready <= 1'b0;
+    end else begin
+        resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
+    end
+end
+
+always_ff @(posedge clk) begin
+    if (hready & (fsm == SCR1_FSM_DATA)) begin
+        resp_fifo.hresp  <= hresp;
+        resp_fifo.hwidth <= data_fifo.hwidth;
+        resp_fifo.haddr  <= data_fifo.haddr;
+        resp_fifo.hrdata <= hrdata;
+    end
+end
+`endif // SCR1_DMEM_AHB_IN_BP
+
+//-------------------------------------------------------------------------------
+// Interface to AHB
+//-------------------------------------------------------------------------------
+assign hprot[SCR1_HPROT_DATA]  = 1'b1;
+assign hprot[SCR1_HPROT_PRV]   = 1'b0;
+assign hprot[SCR1_HPROT_BUF]   = 1'b0;
+assign hprot[SCR1_HPROT_CACHE] = 1'b0;
+
+assign hburst       = SCR1_HBURST_SINGLE;
+assign hsize        = req_fifo[0].hwidth;
+assign hmastlock    = 1'b0;
+
+always_comb begin
+    htrans = SCR1_HTRANS_IDLE;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            if (~req_fifo_empty) begin
+                htrans = SCR1_HTRANS_NONSEQ;
+            end
+        end
+        SCR1_FSM_DATA : begin
+            if (hready) begin
+                if (hresp == SCR1_HRESP_OKAY) begin
+                    if (~req_fifo_empty) begin
+                        htrans = SCR1_HTRANS_NONSEQ;
+                    end
+                end
+            end
+        end
+        default : begin
+            htrans = SCR1_HTRANS_ERR;
+        end
+    endcase
+end
+
+assign haddr  = req_fifo[0].haddr;
+assign hwrite = req_fifo[0].hwrite;
+assign hwdata = data_fifo.hwdata;
+
+endmodule : scr1_dmem_ahb
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_router.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_router.sv
new file mode 100644
index 0000000..afef729
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_dmem_router.sv
@@ -0,0 +1,278 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_dmem_router.sv>
+/// @brief      Data memory router
+///
+`include "scr1_memif.svh"
+`include "scr1_arch_description.svh"
+
+module scr1_dmem_router
+#(
+    parameter SCR1_PORT1_ADDR_MASK      = `SCR1_DMEM_AWIDTH'hFFFF0000,
+    parameter SCR1_PORT1_ADDR_PATTERN   = `SCR1_DMEM_AWIDTH'h00010000,
+    parameter SCR1_PORT2_ADDR_MASK      = `SCR1_DMEM_AWIDTH'hFFFF0000,
+    parameter SCR1_PORT2_ADDR_PATTERN   = `SCR1_DMEM_AWIDTH'h00020000
+)
+(
+    // Control signals
+    input   logic                           rst_n,
+    input   logic                           clk,
+
+    // Core interface
+    output  logic                           dmem_req_ack,
+    input   logic                           dmem_req,
+    input   type_scr1_mem_cmd_e             dmem_cmd,
+    input   type_scr1_mem_width_e           dmem_width,
+    input   logic [`SCR1_DMEM_AWIDTH-1:0]   dmem_addr,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_wdata,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_rdata,
+    output  type_scr1_mem_resp_e            dmem_resp,
+
+    // PORT0 interface
+    input   logic                           port0_req_ack,
+    output  logic                           port0_req,
+    output  type_scr1_mem_cmd_e             port0_cmd,
+    output  type_scr1_mem_width_e           port0_width,
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port0_addr,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port0_wdata,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port0_rdata,
+    input   type_scr1_mem_resp_e            port0_resp,
+
+    // PORT1 interface
+    input   logic                           port1_req_ack,
+    output  logic                           port1_req,
+    output  type_scr1_mem_cmd_e             port1_cmd,
+    output  type_scr1_mem_width_e           port1_width,
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port1_addr,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port1_wdata,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port1_rdata,
+    input   type_scr1_mem_resp_e            port1_resp,
+
+    // PORT2 interface
+    input   logic                           port2_req_ack,
+    output  logic                           port2_req,
+    output  type_scr1_mem_cmd_e             port2_cmd,
+    output  type_scr1_mem_width_e           port2_width,
+    output  logic [`SCR1_DMEM_AWIDTH-1:0]   port2_addr,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]   port2_wdata,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]   port2_rdata,
+    input   type_scr1_mem_resp_e            port2_resp
+);
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_FSM_ADDR,
+    SCR1_FSM_DATA
+} type_scr1_fsm_e;
+
+typedef enum logic [1:0] {
+    SCR1_SEL_PORT0,
+    SCR1_SEL_PORT1,
+    SCR1_SEL_PORT2
+} type_scr1_sel_e;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+type_scr1_fsm_e                 fsm;
+type_scr1_sel_e                 port_sel;
+type_scr1_sel_e                 port_sel_r;
+logic [`SCR1_DMEM_DWIDTH-1:0]   sel_rdata;
+type_scr1_mem_resp_e            sel_resp;
+logic                           sel_req_ack;
+
+//-------------------------------------------------------------------------------
+// FSM
+//-------------------------------------------------------------------------------
+always_comb begin
+    port_sel    = SCR1_SEL_PORT0;
+    if ((dmem_addr & SCR1_PORT1_ADDR_MASK) == SCR1_PORT1_ADDR_PATTERN) begin
+        port_sel    = SCR1_SEL_PORT1;
+    end else if ((dmem_addr & SCR1_PORT2_ADDR_MASK) == SCR1_PORT2_ADDR_PATTERN) begin
+        port_sel    = SCR1_SEL_PORT2;
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        fsm         <= SCR1_FSM_ADDR;
+        port_sel_r  <= SCR1_SEL_PORT0;
+    end else begin
+        case (fsm)
+            SCR1_FSM_ADDR : begin
+                if (dmem_req & sel_req_ack) begin
+                    fsm         <= SCR1_FSM_DATA;
+                    port_sel_r  <= port_sel;
+                end
+            end
+            SCR1_FSM_DATA : begin
+                case (sel_resp)
+                    SCR1_MEM_RESP_RDY_OK : begin
+                        if (dmem_req & sel_req_ack) begin
+                            fsm         <= SCR1_FSM_DATA;
+                            port_sel_r  <= port_sel;
+                        end else begin
+                            fsm <= SCR1_FSM_ADDR;
+                        end
+                    end
+                    SCR1_MEM_RESP_RDY_ER : begin
+                        fsm <= SCR1_FSM_ADDR;
+                    end
+                    default : begin
+                    end
+                endcase
+            end
+            default : begin
+            end
+        endcase
+    end
+end
+
+always_comb begin
+    if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin
+        case (port_sel)
+            SCR1_SEL_PORT0  : sel_req_ack   = port0_req_ack;
+            SCR1_SEL_PORT1  : sel_req_ack   = port1_req_ack;
+            SCR1_SEL_PORT2  : sel_req_ack   = port2_req_ack;
+            default         : sel_req_ack   = 1'b0;
+        endcase
+    end else begin
+        sel_req_ack = 1'b0;
+    end
+end
+
+always_comb begin
+    case (port_sel_r)
+        SCR1_SEL_PORT0  : begin
+            sel_rdata   = port0_rdata;
+            sel_resp    = port0_resp;
+        end
+        SCR1_SEL_PORT1  : begin
+            sel_rdata   = port1_rdata;
+            sel_resp    = port1_resp;
+        end
+        SCR1_SEL_PORT2  : begin
+            sel_rdata   = port2_rdata;
+            sel_resp    = port2_resp;
+        end
+        default         : begin
+            sel_rdata   = '0;
+            sel_resp    = SCR1_MEM_RESP_RDY_ER;
+        end
+    endcase
+end
+
+//-------------------------------------------------------------------------------
+// Interface to core
+//-------------------------------------------------------------------------------
+assign dmem_req_ack = sel_req_ack;
+assign dmem_rdata   = sel_rdata;
+assign dmem_resp    = sel_resp;
+
+//-------------------------------------------------------------------------------
+// Interface to PORT0
+//-------------------------------------------------------------------------------
+always_comb begin
+    port0_req = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
+        end
+        SCR1_FSM_DATA : begin
+            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
+                port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0);
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+`ifdef SCR1_XPROP_EN
+assign port0_cmd    = (port_sel == SCR1_SEL_PORT0) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
+assign port0_width  = (port_sel == SCR1_SEL_PORT0) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
+assign port0_addr   = (port_sel == SCR1_SEL_PORT0) ? dmem_addr  : 'x;
+assign port0_wdata  = (port_sel == SCR1_SEL_PORT0) ? dmem_wdata : 'x;
+`else // SCR1_XPROP_EN
+assign port0_cmd    = dmem_cmd  ;
+assign port0_width  = dmem_width;
+assign port0_addr   = dmem_addr ;
+assign port0_wdata  = dmem_wdata;
+`endif // SCR1_XPROP_EN
+
+//-------------------------------------------------------------------------------
+// Interface to PORT1
+//-------------------------------------------------------------------------------
+always_comb begin
+    port1_req = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
+        end
+        SCR1_FSM_DATA : begin
+            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
+                port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1);
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+`ifdef SCR1_XPROP_EN
+assign port1_cmd    = (port_sel == SCR1_SEL_PORT1) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
+assign port1_width  = (port_sel == SCR1_SEL_PORT1) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
+assign port1_addr   = (port_sel == SCR1_SEL_PORT1) ? dmem_addr  : 'x;
+assign port1_wdata  = (port_sel == SCR1_SEL_PORT1) ? dmem_wdata : 'x;
+`else // SCR1_XPROP_EN
+assign port1_cmd    = dmem_cmd  ;
+assign port1_width  = dmem_width;
+assign port1_addr   = dmem_addr ;
+assign port1_wdata  = dmem_wdata;
+`endif // SCR1_XPROP_EN
+
+//-------------------------------------------------------------------------------
+// Interface to PORT2
+//-------------------------------------------------------------------------------
+always_comb begin
+    port2_req = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
+        end
+        SCR1_FSM_DATA : begin
+            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
+                port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2);
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+`ifdef SCR1_XPROP_EN
+assign port2_cmd    = (port_sel == SCR1_SEL_PORT2) ? dmem_cmd   : SCR1_MEM_CMD_ERROR;
+assign port2_width  = (port_sel == SCR1_SEL_PORT2) ? dmem_width : SCR1_MEM_WIDTH_ERROR;
+assign port2_addr   = (port_sel == SCR1_SEL_PORT2) ? dmem_addr  : 'x;
+assign port2_wdata  = (port_sel == SCR1_SEL_PORT2) ? dmem_wdata : 'x;
+`else // SCR1_XPROP_EN
+assign port2_cmd    = dmem_cmd  ;
+assign port2_width  = dmem_width;
+assign port2_addr   = dmem_addr ;
+assign port2_wdata  = dmem_wdata;
+`endif // SCR1_XPROP_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+SCR1_SVA_DMEM_RT_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    dmem_req |-> !$isunknown({port_sel, dmem_cmd, dmem_width})
+    ) else $error("DMEM router Error: unknown values");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_dmem_router
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_dp_memory.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_dp_memory.sv
new file mode 100644
index 0000000..971591d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_dp_memory.sv
@@ -0,0 +1,111 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_dp_memory.sv>
+/// @brief      Dual-port synchronous memory with byte enable inputs
+///
+
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_TCM_EN
+module scr1_dp_memory
+#(
+    parameter SCR1_WIDTH    = 32,
+    parameter SCR1_SIZE     = `SCR1_IMEM_AWIDTH'h00010000,
+    parameter SCR1_NBYTES   = SCR1_WIDTH / 8
+)
+(
+    input   logic                           clk,
+    // Port A
+    input   logic                           rena,
+    input   logic [$clog2(SCR1_SIZE)-1:2]   addra,
+    output  logic [SCR1_WIDTH-1:0]          qa,
+    // Port B
+    input   logic                           renb,
+    input   logic                           wenb,
+    input   logic [SCR1_NBYTES-1:0]         webb,
+    input   logic [$clog2(SCR1_SIZE)-1:2]   addrb,
+    input   logic [SCR1_WIDTH-1:0]          datab,
+    output  logic [SCR1_WIDTH-1:0]          qb
+);
+
+`ifdef SCR1_TRGT_FPGA_INTEL
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+ `ifdef SCR1_TRGT_FPGA_INTEL_MAX10
+(* ramstyle = "M9K" *)    logic [SCR1_NBYTES-1:0][7:0]  memory_array  [0:(SCR1_SIZE/SCR1_NBYTES)-1];
+ `elsif SCR1_TRGT_FPGA_INTEL_ARRIAV
+(* ramstyle = "M10K" *)   logic [SCR1_NBYTES-1:0][7:0]  memory_array  [0:(SCR1_SIZE/SCR1_NBYTES)-1];
+ `endif
+logic [3:0] wenbb;
+//-------------------------------------------------------------------------------
+// Port B memory behavioral description
+//-------------------------------------------------------------------------------
+assign wenbb = {4{wenb}} & webb;
+always_ff @(posedge clk) begin
+    if (wenb) begin
+        if (wenbb[0]) begin
+            memory_array[addrb][0] <= datab[0+:8];
+        end
+        if (wenbb[1]) begin
+            memory_array[addrb][1] <= datab[8+:8];
+        end
+        if (wenbb[2]) begin
+            memory_array[addrb][2] <= datab[16+:8];
+        end
+        if (wenbb[3]) begin
+            memory_array[addrb][3] <= datab[24+:8];
+        end
+    end
+    qb <= memory_array[addrb];
+end
+//-------------------------------------------------------------------------------
+// Port A memory behavioral description
+//-------------------------------------------------------------------------------
+always_ff @(posedge clk) begin
+    qa <= memory_array[addra];
+end
+
+`else // SCR1_TRGT_FPGA_INTEL
+
+// CASE: OTHERS - SCR1_TRGT_FPGA_XILINX, SIMULATION, ASIC etc
+
+localparam int unsigned RAM_SIZE_WORDS = SCR1_SIZE/SCR1_NBYTES;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+ `ifdef SCR1_TRGT_FPGA_XILINX
+(* ram_style = "block" *)  logic  [SCR1_WIDTH-1:0]  ram_block  [RAM_SIZE_WORDS-1:0];
+ `else  // ASIC or SIMULATION
+logic  [SCR1_WIDTH-1:0]  ram_block  [RAM_SIZE_WORDS-1:0];
+ `endif
+//-------------------------------------------------------------------------------
+// Port A memory behavioral description
+//-------------------------------------------------------------------------------
+always_ff @(posedge clk) begin
+    if (rena) begin
+        qa <= ram_block[addra];
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Port B memory behavioral description
+//-------------------------------------------------------------------------------
+always_ff @(posedge clk) begin
+    if (wenb) begin
+        for (int i=0; i<SCR1_NBYTES; i++) begin
+            if (webb[i]) begin
+                ram_block[addrb][i*8 +: 8] <= datab[i*8 +: 8];
+            end
+        end
+    end
+    if (renb) begin
+        qb <= ram_block[addrb];
+    end
+end
+
+`endif // SCR1_TRGT_FPGA_INTEL
+
+endmodule : scr1_dp_memory
+
+`endif // SCR1_TCM_EN
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_imem_ahb.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_imem_ahb.sv
new file mode 100644
index 0000000..e749f9d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_imem_ahb.sv
@@ -0,0 +1,319 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_imem_ahb.sv>
+/// @brief      Instruction memory AHB bridge
+///
+
+`include "scr1_ahb.svh"
+`include "scr1_memif.svh"
+
+module scr1_imem_ahb (
+    // Control Signals
+    input   logic                           rst_n,
+    input   logic                           clk,
+
+    // Core Interface
+    output  logic                           imem_req_ack,
+    input   logic                           imem_req,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    imem_addr,
+    output  logic   [SCR1_AHB_WIDTH-1:0]    imem_rdata,
+    output  type_scr1_mem_resp_e            imem_resp,
+
+    // AHB Interface
+    output  logic   [3:0]                   hprot,
+    output  logic   [2:0]                   hburst,
+    output  logic   [2:0]                   hsize,
+    output  logic   [1:0]                   htrans,
+    output  logic                           hmastlock,
+    output  logic   [SCR1_AHB_WIDTH-1:0]    haddr,
+    input   logic                           hready,
+    input   logic   [SCR1_AHB_WIDTH-1:0]    hrdata,
+    input   logic                           hresp
+
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters declaration
+//-------------------------------------------------------------------------------
+`ifndef SCR1_IMEM_AHB_OUT_BP
+localparam  SCR1_FIFO_WIDTH = 2;
+localparam  SCR1_FIFO_CNT_WIDTH = $clog2(SCR1_FIFO_WIDTH+1);
+`endif // SCR1_IMEM_AHB_OUT_BP
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_FSM_ADDR = 1'b0,
+    SCR1_FSM_DATA = 1'b1,
+    SCR1_FSM_ERR  = 1'bx
+} type_scr1_fsm_e;
+
+typedef struct packed {
+    logic   [SCR1_AHB_WIDTH-1:0]    haddr;
+} type_scr1_req_fifo_s;
+
+typedef struct packed {
+    logic                           hresp;
+    logic   [SCR1_AHB_WIDTH-1:0]    hrdata;
+} type_scr1_resp_fifo_s;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+type_scr1_fsm_e                             fsm;
+logic                                       req_fifo_rd;
+logic                                       req_fifo_wr;
+logic                                       req_fifo_up;
+`ifdef SCR1_IMEM_AHB_OUT_BP
+type_scr1_req_fifo_s                        req_fifo_r;
+type_scr1_req_fifo_s [0:0]                  req_fifo;
+`else // SCR1_IMEM_AHB_OUT_BP
+type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo;
+type_scr1_req_fifo_s [0:SCR1_FIFO_WIDTH-1]  req_fifo_new;
+logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt;
+logic       [SCR1_FIFO_CNT_WIDTH-1:0]       req_fifo_cnt_new;
+`endif // SCR1_IMEM_AHB_OUT_BP
+logic                                       req_fifo_empty;
+logic                                       req_fifo_full;
+
+type_scr1_resp_fifo_s                       resp_fifo;
+logic                                       resp_fifo_hready;
+
+//-------------------------------------------------------------------------------
+// Interface to Core
+//-------------------------------------------------------------------------------
+assign imem_req_ack = ~req_fifo_full;
+assign req_fifo_wr  = ~req_fifo_full & imem_req;
+
+assign imem_rdata = resp_fifo.hrdata;
+
+assign imem_resp = (resp_fifo_hready)
+                    ? (resp_fifo.hresp == SCR1_HRESP_OKAY)
+                        ? SCR1_MEM_RESP_RDY_OK
+                        : SCR1_MEM_RESP_RDY_ER
+                    : SCR1_MEM_RESP_NOTRDY;
+
+//-------------------------------------------------------------------------------
+// REQ_FIFO
+//-------------------------------------------------------------------------------
+`ifdef SCR1_IMEM_AHB_OUT_BP
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_fifo_full <= 1'b0;
+    end else begin
+        if (~req_fifo_full) begin
+            req_fifo_full <= imem_req & ~req_fifo_rd;
+        end else begin
+            req_fifo_full <= ~req_fifo_rd;
+        end
+    end
+end
+assign req_fifo_empty = ~(req_fifo_full | imem_req);
+
+assign req_fifo_up    = ~req_fifo_rd & req_fifo_wr;
+always_ff @(posedge clk) begin
+    if (req_fifo_up) begin
+        req_fifo_r.haddr <= imem_addr;
+    end
+end
+
+assign req_fifo[0] = (req_fifo_full) ? req_fifo_r : imem_addr;
+
+`else // SCR1_IMEM_AHB_OUT_BP
+always_comb begin
+    req_fifo_up      = 1'b0;
+    req_fifo_cnt_new = req_fifo_cnt;
+    req_fifo_new     = req_fifo;
+    case ({req_fifo_rd, req_fifo_wr})
+        2'b00 : begin
+            // nothing todo
+        end
+        2'b01: begin
+            // FIFO write
+            req_fifo_up = 1'b1;
+            req_fifo_new[req_fifo_cnt].haddr  = imem_addr;
+            req_fifo_cnt_new = req_fifo_cnt + 1'b1;
+        end
+        2'b10 : begin
+            // FIFO read
+            req_fifo_up     = 1'b1;
+            req_fifo_new[0] = req_fifo_new[1];
+            req_fifo_new[1].haddr  = 'x;
+            req_fifo_cnt_new = req_fifo_cnt - 1'b1;
+        end
+        2'b11 : begin
+            // Read and Write FIFO. It is possible only when fifo_cnt = 1
+            req_fifo_up           = 1'b1;
+            req_fifo_new[0].haddr = imem_addr;
+        end
+        default : begin
+            req_fifo_up      = 'x;
+            req_fifo_cnt_new = 'x;
+            req_fifo_new     = 'x;
+        end
+    endcase
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_fifo_cnt <= '0;
+    end else begin
+        if (req_fifo_up) begin
+            req_fifo_cnt <= req_fifo_cnt_new;
+        end
+    end
+end
+assign req_fifo_full  = (req_fifo_cnt == SCR1_FIFO_WIDTH);
+assign req_fifo_empty = ~(|req_fifo_cnt);
+
+always_ff @(posedge clk) begin
+    if (req_fifo_up) begin
+        req_fifo <= req_fifo_new;
+    end
+end
+`endif // SCR1_IMEM_AHB_OUT_BP
+
+//-------------------------------------------------------------------------------
+// FSM
+//-------------------------------------------------------------------------------
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        fsm <= SCR1_FSM_ADDR;
+    end else begin
+        case (fsm)
+            SCR1_FSM_ADDR : begin
+                if (hready) begin
+                    fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
+                end
+            end
+            SCR1_FSM_DATA : begin
+                if (hready) begin
+                    if (hresp == SCR1_HRESP_OKAY) begin
+                        fsm <= (req_fifo_empty) ? SCR1_FSM_ADDR : SCR1_FSM_DATA;
+                    end else begin
+                        fsm <= SCR1_FSM_ADDR;
+                    end
+                end
+            end
+            default : begin
+                fsm <= SCR1_FSM_ERR;
+            end
+        endcase
+    end
+end
+
+always_comb begin
+    req_fifo_rd = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            if (hready) begin
+                req_fifo_rd = ~req_fifo_empty;
+            end
+        end
+        SCR1_FSM_DATA : begin
+            if (hready) begin
+                req_fifo_rd = ~req_fifo_empty & (hresp == SCR1_HRESP_OKAY);
+            end
+        end
+        default : begin
+            req_fifo_rd = 1'bx;
+        end
+    endcase
+end
+
+//-------------------------------------------------------------------------------
+// FIFO response
+//-------------------------------------------------------------------------------
+`ifdef SCR1_IMEM_AHB_IN_BP
+assign resp_fifo_hready = (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
+assign resp_fifo.hresp  = hresp;
+assign resp_fifo.hrdata = hrdata;
+`else // SCR1_IMEM_AHB_IN_BP
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        resp_fifo_hready <= 1'b0;
+    end else begin
+        resp_fifo_hready <= (fsm == SCR1_FSM_DATA) ? hready : 1'b0;
+    end
+end
+
+always_ff @(posedge clk) begin
+    if (hready & (fsm == SCR1_FSM_DATA)) begin
+        resp_fifo.hresp  <= hresp;
+        resp_fifo.hrdata <= hrdata;
+    end
+end
+`endif // SCR1_IMEM_AHB_IN_BP
+
+//-------------------------------------------------------------------------------
+// Interface to AHB
+//-------------------------------------------------------------------------------
+assign hprot[SCR1_HPROT_DATA]  = 1'b0;
+assign hprot[SCR1_HPROT_PRV]   = 1'b0;
+assign hprot[SCR1_HPROT_BUF]   = 1'b0;
+assign hprot[SCR1_HPROT_CACHE] = 1'b0;
+
+assign hburst       = SCR1_HBURST_SINGLE;
+assign hsize        = SCR1_HSIZE_32B;
+assign hmastlock    = 1'b0;
+
+always_comb begin
+    htrans = SCR1_HTRANS_IDLE;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            if (~req_fifo_empty) begin
+                htrans = SCR1_HTRANS_NONSEQ;
+            end
+        end
+        SCR1_FSM_DATA : begin
+            if (hready) begin
+                if (hresp == SCR1_HRESP_OKAY) begin
+                    if (~req_fifo_empty) begin
+                        htrans = SCR1_HTRANS_NONSEQ;
+                    end
+                end
+            end
+        end
+        default : begin
+            htrans = SCR1_HTRANS_ERR;
+        end
+    endcase
+end
+
+assign haddr  = req_fifo[0].haddr;
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+// Check Core interface
+SCR1_SVA_IMEM_AHB_BRIDGE_REQ_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(imem_req)
+    ) else $error("IMEM AHB bridge Error: imem_req has unknown values");
+
+SCR1_IMEM_AHB_BRIDGE_ADDR_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    imem_req |-> !$isunknown(imem_addr)
+    ) else $error("IMEM AHB bridge Error: imem_addr has unknown values");
+
+SCR1_IMEM_AHB_BRIDGE_ADDR_ALLIGN : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    imem_req |-> (imem_addr[1:0] == '0)
+    ) else $error("IMEM AHB bridge Error: imem_addr has unalign values");
+
+// Check AHB interface
+SCR1_IMEM_AHB_BRIDGE_HREADY_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(hready)
+    ) else $error("IMEM AHB bridge Error: hready has unknown values");
+
+SCR1_IMEM_AHB_BRIDGE_HRESP_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    !$isunknown(hresp)
+    ) else $error("IMEM AHB bridge Error: hresp has unknown values");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_imem_ahb
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_imem_router.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_imem_router.sv
new file mode 100644
index 0000000..dd76f25
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_imem_router.sv
@@ -0,0 +1,185 @@
+/// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details
+/// @file       <scr1_imem_router.sv>
+/// @brief      Instruction memory router
+///
+`include "scr1_memif.svh"
+`include "scr1_arch_description.svh"
+
+module scr1_imem_router
+#(
+    parameter SCR1_ADDR_MASK    = `SCR1_IMEM_AWIDTH'hFFFF0000,
+    parameter SCR1_ADDR_PATTERN = `SCR1_IMEM_AWIDTH'h00010000
+)
+(
+    // Control signals
+    input   logic                           rst_n,
+    input   logic                           clk,
+
+    // Core interface
+    output  logic                           imem_req_ack,
+    input   logic                           imem_req,
+    input   type_scr1_mem_cmd_e             imem_cmd,
+    input   logic [`SCR1_IMEM_AWIDTH-1:0]   imem_addr,
+    output  logic [`SCR1_IMEM_DWIDTH-1:0]   imem_rdata,
+    output  type_scr1_mem_resp_e            imem_resp,
+
+    // PORT0 interface
+    input   logic                           port0_req_ack,
+    output  logic                           port0_req,
+    output  type_scr1_mem_cmd_e             port0_cmd,
+    output  logic [`SCR1_IMEM_AWIDTH-1:0]   port0_addr,
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]   port0_rdata,
+    input   type_scr1_mem_resp_e            port0_resp,
+
+    // PORT1 interface
+    input   logic                           port1_req_ack,
+    output  logic                           port1_req,
+    output  type_scr1_mem_cmd_e             port1_cmd,
+    output  logic [`SCR1_IMEM_AWIDTH-1:0]   port1_addr,
+    input   logic [`SCR1_IMEM_DWIDTH-1:0]   port1_rdata,
+    input   type_scr1_mem_resp_e            port1_resp
+);
+
+//-------------------------------------------------------------------------------
+// Local types declaration
+//-------------------------------------------------------------------------------
+typedef enum logic {
+    SCR1_FSM_ADDR,
+    SCR1_FSM_DATA
+} type_scr1_fsm_e;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+type_scr1_fsm_e                 fsm;
+logic                           port_sel;
+logic                           port_sel_r;
+logic [`SCR1_IMEM_DWIDTH-1:0]   sel_rdata;
+type_scr1_mem_resp_e            sel_resp;
+logic                           sel_req_ack;
+
+//-------------------------------------------------------------------------------
+// FSM
+//-------------------------------------------------------------------------------
+assign port_sel = ((imem_addr & SCR1_ADDR_MASK) == SCR1_ADDR_PATTERN);
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        fsm        <= SCR1_FSM_ADDR;
+        port_sel_r <= 1'b0;
+    end else begin
+        case (fsm)
+            SCR1_FSM_ADDR : begin
+                if (imem_req & sel_req_ack) begin
+                    fsm <= SCR1_FSM_DATA;
+                    port_sel_r <= port_sel;
+                end
+            end
+            SCR1_FSM_DATA : begin
+                case (sel_resp)
+                    SCR1_MEM_RESP_RDY_OK : begin
+                        if (imem_req & sel_req_ack) begin
+                            fsm <= SCR1_FSM_DATA;
+                            port_sel_r <= port_sel;
+                        end else begin
+                            fsm <= SCR1_FSM_ADDR;
+                        end
+                    end
+                    SCR1_MEM_RESP_RDY_ER : begin
+                        fsm <= SCR1_FSM_ADDR;
+                    end
+                    default : begin
+                    end
+                endcase
+            end
+            default : begin
+            end
+        endcase
+    end
+end
+
+always_comb begin
+    if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin
+        sel_req_ack = (port_sel) ? port1_req_ack : port0_req_ack;
+    end else begin
+        sel_req_ack = 1'b0;
+    end
+end
+
+assign sel_rdata = (port_sel_r) ? port1_rdata : port0_rdata;
+assign sel_resp  = (port_sel_r) ? port1_resp  : port0_resp;
+
+//-------------------------------------------------------------------------------
+// Interface to core
+//-------------------------------------------------------------------------------
+assign imem_req_ack = sel_req_ack;
+assign imem_rdata   = sel_rdata;
+assign imem_resp    = sel_resp;
+
+//-------------------------------------------------------------------------------
+// Interface to PORT0
+//-------------------------------------------------------------------------------
+always_comb begin
+    port0_req = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            port0_req = imem_req & ~port_sel;
+        end
+        SCR1_FSM_DATA : begin
+            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
+                port0_req = imem_req & ~port_sel;
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+`ifdef SCR1_XPROP_EN
+assign port0_cmd   = (~port_sel) ? imem_cmd  : SCR1_MEM_CMD_ERROR;
+assign port0_addr  = (~port_sel) ? imem_addr : 'x;
+`else // SCR1_XPROP_EN
+assign port0_cmd   = imem_cmd ;
+assign port0_addr  = imem_addr;
+`endif // SCR1_XPROP_EN
+
+//-------------------------------------------------------------------------------
+// Interface to PORT1
+//-------------------------------------------------------------------------------
+always_comb begin
+    port1_req = 1'b0;
+    case (fsm)
+        SCR1_FSM_ADDR : begin
+            port1_req = imem_req & port_sel;
+        end
+        SCR1_FSM_DATA : begin
+            if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin
+                port1_req = imem_req & port_sel;
+            end
+        end
+        default : begin
+        end
+    endcase
+end
+
+`ifdef SCR1_XPROP_EN
+assign port1_cmd   = (port_sel) ? imem_cmd  : SCR1_MEM_CMD_ERROR;
+assign port1_addr  = (port_sel) ? imem_addr : 'x;
+`else // SCR1_XPROP_EN
+assign port1_cmd   = imem_cmd ;
+assign port1_addr  = imem_addr;
+`endif // SCR1_XPROP_EN
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+SCR1_SVA_IMEM_RT_XCHECK : assert property (
+    @(negedge clk) disable iff (~rst_n)
+    imem_req |-> !$isunknown({port_sel, imem_cmd})
+    ) else $error("IMEM router Error: unknown values");
+
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_imem_router
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_mem_axi.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_mem_axi.sv
new file mode 100644
index 0000000..406494d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_mem_axi.sv
@@ -0,0 +1,363 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_mem_axi.sv>
+/// @brief      Memory AXI bridge
+///
+
+`include "scr1_memif.svh"
+`include "scr1_arch_description.svh"
+
+module scr1_mem_axi
+#(
+    parameter SCR1_REQ_BUF_SIZE     = 2,                    // Power of 2 value
+    parameter SCR1_AXI_IDWIDTH      = 4,
+    parameter SCR1_ADDR_WIDTH       = 32,
+    parameter SCR1_AXI_REQ_BP       = 1,
+    parameter SCR1_AXI_RESP_BP      = 1
+)
+(
+    // Clock and Reset
+    input   logic                           clk,
+    input   logic                           rst_n,
+    input   logic                           axi_reinit,
+    // Core Interface
+    output  logic                           core_idle,
+    output  logic                           core_req_ack,
+    input   logic                           core_req,
+    input   type_scr1_mem_cmd_e             core_cmd,
+    input   type_scr1_mem_width_e           core_width,
+    input   logic [SCR1_ADDR_WIDTH-1:0]     core_addr,
+    input   logic [31:0]                    core_wdata,
+    output  logic [31:0]                    core_rdata,
+    output  type_scr1_mem_resp_e            core_resp,
+
+    // AXI
+    output  logic [SCR1_AXI_IDWIDTH-1:0]    awid,
+    output  logic [SCR1_ADDR_WIDTH-1:0]     awaddr,
+    output  logic [ 7:0]                    awlen,
+    output  logic [ 2:0]                    awsize,
+    output  logic [ 1:0]                    awburst,
+    output  logic                           awlock,
+    output  logic [ 3:0]                    awcache,
+    output  logic [ 2:0]                    awprot,
+    output  logic [ 3:0]                    awregion,
+    output  logic [ 3:0]                    awuser,
+    output  logic [ 3:0]                    awqos,
+    output  logic                           awvalid,
+    input   logic                           awready,
+    output  logic [31:0]                    wdata,
+    output  logic [3:0]                     wstrb,
+    output  logic                           wlast,
+    output  logic [3:0]                     wuser,
+    output  logic                           wvalid,
+    input   logic                           wready,
+    input   logic [SCR1_AXI_IDWIDTH-1:0]    bid,
+    input   logic [ 1:0]                    bresp,
+    input   logic                           bvalid,
+    input   logic [ 3:0]                    buser,
+    output  logic                           bready,
+    output  logic [SCR1_AXI_IDWIDTH-1:0]    arid,
+    output  logic [SCR1_ADDR_WIDTH-1:0]     araddr,
+    output  logic [ 7:0]                    arlen,
+    output  logic [ 2:0]                    arsize,
+    output  logic [ 1:0]                    arburst,
+    output  logic                           arlock,
+    output  logic [ 3:0]                    arcache,
+    output  logic [ 2:0]                    arprot,
+    output  logic [ 3:0]                    arregion,
+    output  logic [ 3:0]                    aruser,
+    output  logic [ 3:0]                    arqos,
+    output  logic                           arvalid,
+    input   logic                           arready,
+    input   logic [SCR1_AXI_IDWIDTH-1:0]    rid,
+    input   logic [31:0]                    rdata,
+    input   logic [ 1:0]                    rresp,
+    input   logic                           rlast,
+    input   logic [ 3:0]                    ruser,
+    input   logic                           rvalid,
+    output  logic                           rready
+);
+
+
+// Local functions
+function automatic logic [2:0] width2axsize (
+    input   type_scr1_mem_width_e    width );
+    logic [2:0] axsize;
+begin
+    case (width)
+        SCR1_MEM_WIDTH_BYTE :  axsize = 3'b000;
+        SCR1_MEM_WIDTH_HWORD:  axsize = 3'b001;
+        SCR1_MEM_WIDTH_WORD :  axsize = 3'b010;
+                     default:  axsize = 'x;
+    endcase
+
+    return axsize;
+end
+endfunction: width2axsize
+
+typedef struct packed {
+    type_scr1_mem_width_e                               axi_width;
+    logic                    [SCR1_ADDR_WIDTH-1:0]      axi_addr;
+    logic                                   [31:0]      axi_wdata;
+} type_scr1_request_s;
+
+typedef struct packed {
+    logic                                               req_write;
+    logic                                               req_addr;
+    logic                                               req_data;
+    logic                                               req_resp;
+} type_scr1_req_status_s;
+
+
+type_scr1_request_s         [SCR1_REQ_BUF_SIZE-1:0]     req_fifo;
+type_scr1_req_status_s      [SCR1_REQ_BUF_SIZE-1:0]     req_status;
+type_scr1_req_status_s      [SCR1_REQ_BUF_SIZE-1:0]     req_status_new;
+logic                       [SCR1_REQ_BUF_SIZE-1:0]     req_status_en;
+logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_aval_ptr;
+logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_proc_ptr;
+logic               [$clog2(SCR1_REQ_BUF_SIZE)-1:0]     req_done_ptr;
+logic                                                   rresp_err;
+logic                                       [31:0]      rcvd_rdata;
+type_scr1_mem_resp_e                                    rcvd_resp;
+logic                                                   force_read;
+logic                                                   force_write;
+
+
+
+assign core_req_ack =   ~axi_reinit                        &
+                        ~req_status[req_aval_ptr].req_resp &
+                         core_resp!=SCR1_MEM_RESP_RDY_ER;
+
+
+assign rready      = ~req_status[req_done_ptr].req_write;
+assign bready      =  req_status[req_done_ptr].req_write;
+
+
+assign force_read  = bit'(SCR1_AXI_REQ_BP) & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_RD;
+assign force_write = bit'(SCR1_AXI_REQ_BP) & core_req & core_req_ack & req_aval_ptr==req_proc_ptr & core_cmd==SCR1_MEM_CMD_WR;
+
+
+always_comb begin: idle_status
+    core_idle = 1'b1;
+    for (int unsigned i=0; i<SCR1_REQ_BUF_SIZE; ++i) begin
+        core_idle &= req_status[i].req_resp==1'b0;
+    end
+end
+
+always_ff @(posedge clk) begin
+    if (core_req & core_req_ack) begin
+        req_fifo[req_aval_ptr].axi_width <= core_width;
+        req_fifo[req_aval_ptr].axi_addr  <= core_addr;
+        req_fifo[req_aval_ptr].axi_wdata <= core_wdata;
+    end
+end
+
+// Request Status Queue
+// It is used for holding control info of processing requests
+
+// Combinational logic of Request Status Queue
+always_comb begin
+    // Default
+    req_status_en  = '0; // No update
+    req_status_new = req_status; // Hold request info
+
+    // Update status on new core request
+    if( core_req & core_req_ack ) begin
+        req_status_en[req_aval_ptr]            = 1'd1;
+
+        req_status_new[req_aval_ptr].req_resp  = 1'd1;
+        req_status_new[req_aval_ptr].req_write = core_cmd == SCR1_MEM_CMD_WR;
+
+        req_status_new[req_aval_ptr].req_addr  = ~( (force_read & arready) |
+                                                    (force_write & awready) );
+
+        req_status_new[req_aval_ptr].req_data  = ~( (force_write & wready & awlen == 8'd0) |
+                                                    (~force_write & core_cmd == SCR1_MEM_CMD_RD) );
+    end
+
+    // Update status on AXI address phase
+    if ( (awvalid & awready) | (arvalid & arready) ) begin
+        req_status_en[req_proc_ptr]           = 1'd1;
+        req_status_new[req_proc_ptr].req_addr = 1'd0;
+    end
+
+    // Update status on AXI data phase
+    if ( wvalid & wready & wlast ) begin
+        req_status_en[req_proc_ptr]           = 1'd1;
+        req_status_new[req_proc_ptr].req_data = 1'd0;
+    end
+
+    // Update status when AXI finish transaction
+    if ( (bvalid & bready) | (rvalid & rready & rlast) ) begin
+        req_status_en[req_done_ptr]           = 1'd1;
+        req_status_new[req_done_ptr].req_resp = 1'd0;
+    end
+end
+
+// Request Status Queue register
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_status <= '0;
+    end else begin
+        for (int unsigned i = 0; i < SCR1_REQ_BUF_SIZE; ++i) begin
+            if ( req_status_en[i] ) begin
+                req_status[i] <= req_status_new[i];
+            end
+        end
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n)                         req_aval_ptr <= '0;
+    else if (core_req & core_req_ack)   req_aval_ptr <= req_aval_ptr + 1'b1;
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_proc_ptr <= '0;
+    end else begin
+        if ((                                                    awvalid & awready & wvalid & wready & wlast) |
+            (~force_write & ~req_status[req_proc_ptr].req_data & awvalid & awready                          ) |
+            (~force_write & ~req_status[req_proc_ptr].req_addr &                     wvalid & wready & wlast) |
+            (               ~req_status[req_proc_ptr].req_data & arvalid & arready                          )  ) begin
+
+            req_proc_ptr <= req_proc_ptr + 1'b1;
+        end
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        req_done_ptr <= '0;
+    end else begin
+        if ((bvalid & bready | rvalid & rready & rlast) & req_status[req_done_ptr].req_resp) begin
+
+            req_done_ptr <= req_done_ptr + 1'b1;
+        end
+    end
+end
+
+
+
+assign arvalid = req_status[req_proc_ptr].req_addr & ~req_status[req_proc_ptr].req_write | force_read;
+assign awvalid = req_status[req_proc_ptr].req_addr &  req_status[req_proc_ptr].req_write | force_write;
+assign  wvalid = req_status[req_proc_ptr].req_data &  req_status[req_proc_ptr].req_write | force_write;
+
+assign araddr  = (~force_read )? req_fifo[req_proc_ptr].axi_addr : core_addr;
+assign awaddr  = (~force_write)? req_fifo[req_proc_ptr].axi_addr : core_addr;
+
+always_comb begin
+    if (bvalid & bready & req_status[req_done_ptr].req_resp) begin
+        rcvd_resp = (bresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
+                                    SCR1_MEM_RESP_RDY_ER;
+    end else begin
+        if (rvalid & rready & rlast & req_status[req_done_ptr].req_resp) begin
+            rcvd_resp = (rresp==2'b00)? SCR1_MEM_RESP_RDY_OK :
+                                        SCR1_MEM_RESP_RDY_ER;
+        end else begin
+            rcvd_resp = SCR1_MEM_RESP_NOTRDY;
+        end
+    end
+end
+
+
+
+
+// Write data signals adaptation
+always_comb begin
+    if (force_write)
+        case (core_width)
+            SCR1_MEM_WIDTH_BYTE :  wstrb = 4'h1 << core_addr[1:0];
+            SCR1_MEM_WIDTH_HWORD:  wstrb = 4'h3 << core_addr[1:0];
+            SCR1_MEM_WIDTH_WORD :  wstrb = 4'hf << core_addr[1:0];
+                         default:  wstrb = 'x;
+        endcase
+    else
+        case (req_fifo[req_proc_ptr].axi_width)
+            SCR1_MEM_WIDTH_BYTE :  wstrb = 4'h1 << req_fifo[req_proc_ptr].axi_addr[1:0];
+            SCR1_MEM_WIDTH_HWORD:  wstrb = 4'h3 << req_fifo[req_proc_ptr].axi_addr[1:0];
+            SCR1_MEM_WIDTH_WORD :  wstrb = 4'hf << req_fifo[req_proc_ptr].axi_addr[1:0];
+                         default:  wstrb = 'x;
+        endcase
+end
+
+
+
+assign wdata = (force_write)?                       core_wdata << (8*                       core_addr[1:0]) :
+                              req_fifo[req_proc_ptr].axi_wdata << (8* req_fifo[req_proc_ptr].axi_addr[1:0]);
+
+
+// Read data adaptation
+always_comb begin
+    case (req_fifo[req_done_ptr].axi_width)
+        SCR1_MEM_WIDTH_BYTE :  rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
+        SCR1_MEM_WIDTH_HWORD:  rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
+        SCR1_MEM_WIDTH_WORD :  rcvd_rdata = rdata >> (8*req_fifo[req_done_ptr].axi_addr[1:0]);
+                     default:  rcvd_rdata = 'x;
+    endcase
+end
+
+
+generate
+    if (SCR1_AXI_RESP_BP == 1) begin : axi_resp_bp
+        assign core_rdata = (rvalid & rready & rlast) ? rcvd_rdata : '0;
+        assign core_resp  = (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
+    end else begin : axi_resp_no_bp
+        always_ff @(negedge rst_n, posedge clk) begin
+            if (~rst_n)              core_resp  <= SCR1_MEM_RESP_NOTRDY;
+            else                     core_resp  <= (axi_reinit) ? SCR1_MEM_RESP_NOTRDY : rcvd_resp;
+        end
+        always_ff @(posedge clk) begin
+            if (rvalid & rready & rlast) core_rdata <= rcvd_rdata;
+        end
+    end
+endgenerate
+
+
+
+// AXI interface assignments
+assign awid     = SCR1_AXI_IDWIDTH'(1);
+assign awlen    = 8'd0;
+assign awsize   = (force_write) ? width2axsize(core_width) : width2axsize(req_fifo[req_proc_ptr].axi_width);
+assign awburst  = 2'd1;
+assign awcache  = 4'd2;
+assign awlock   = '0;
+assign awprot   = '0;
+assign awregion = '0;
+assign awuser   = '0;
+assign awqos    = '0;
+
+assign arid     = SCR1_AXI_IDWIDTH'(0);
+assign arlen    = 8'd0;
+assign arsize   = (force_read) ? width2axsize(core_width) : width2axsize(req_fifo[req_proc_ptr].axi_width);
+assign arburst  = 2'd1;
+assign arcache  = 4'd2;
+assign arprot   = '0;
+assign arregion = '0;
+assign arlock   = '0;
+assign arqos    = '0;
+assign aruser   = '0;
+
+assign wlast    = 1'd1;
+assign wuser    = '0;
+
+
+`ifdef SCR1_TRGT_SIMULATION
+//-------------------------------------------------------------------------------
+// Assertion
+//-------------------------------------------------------------------------------
+
+// X checks
+SCR1_SVA_AXI_X_CHECK0  : assert property (@(negedge clk) disable iff (~rst_n)   !$isunknown({core_req, awready, wready, bvalid, arready, rvalid}) )
+                                                                                                        else $error("AXI bridge: X state on input");
+SCR1_SVA_AXI_X_CHECK1  : assert property (@(negedge clk) disable iff (~rst_n)   core_req |->
+                                                                                    !$isunknown({core_cmd, core_width, core_addr}) )
+                                                                                                        else $error("AXI bridge: X state on input");
+SCR1_SVA_AXI_X_CHECK2  : assert property (@(negedge clk) disable iff (~rst_n)   bvalid |->
+                                                                                    !$isunknown({bid, bresp}) )
+                                                                                                        else $error("AXI bridge: X state on input");
+SCR1_SVA_AXI_X_CHECK3  : assert property (@(negedge clk) disable iff (~rst_n)   rvalid |->
+                                                                                    !$isunknown({rid, rresp}) )
+                                                                                                        else $error("AXI bridge: X state on input");
+`endif // SCR1_TRGT_SIMULATION
+
+endmodule : scr1_mem_axi
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_tcm.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_tcm.sv
new file mode 100644
index 0000000..97376cf
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_tcm.sv
@@ -0,0 +1,131 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_tcm.sv>
+/// @brief      Tightly-Coupled Memory (TCM)
+///
+
+`include "scr1_memif.svh"
+`include "scr1_arch_description.svh"
+
+`ifdef SCR1_TCM_EN
+module scr1_tcm
+#(
+    parameter SCR1_TCM_SIZE = `SCR1_IMEM_AWIDTH'h00010000
+)
+(
+    // Control signals
+    input   logic                           clk,
+    input   logic                           rst_n,
+
+    // Core instruction interface
+    output  logic                           imem_req_ack,
+    input   logic                           imem_req,
+    input   logic [`SCR1_IMEM_AWIDTH-1:0]   imem_addr,
+    output  logic [`SCR1_IMEM_DWIDTH-1:0]   imem_rdata,
+    output  type_scr1_mem_resp_e            imem_resp,
+
+    // Core data interface
+    output  logic                           dmem_req_ack,
+    input   logic                           dmem_req,
+    input   type_scr1_mem_cmd_e             dmem_cmd,
+    input   type_scr1_mem_width_e           dmem_width,
+    input   logic [`SCR1_DMEM_AWIDTH-1:0]   dmem_addr,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_wdata,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]   dmem_rdata,
+    output  type_scr1_mem_resp_e            dmem_resp
+);
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+logic                               imem_req_en;
+logic                               dmem_req_en;
+logic                               imem_rd;
+logic                               dmem_rd;
+logic                               dmem_wr;
+logic [`SCR1_DMEM_DWIDTH-1:0]       dmem_writedata;
+logic [`SCR1_DMEM_DWIDTH-1:0]       dmem_rdata_local;
+logic [3:0]                         dmem_byteen;
+logic [1:0]                         dmem_rdata_shift_reg;
+//-------------------------------------------------------------------------------
+// Core interface
+//-------------------------------------------------------------------------------
+assign imem_req_en = (imem_resp == SCR1_MEM_RESP_RDY_OK) ^ imem_req;
+assign dmem_req_en = (dmem_resp == SCR1_MEM_RESP_RDY_OK) ^ dmem_req;
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        imem_resp <= SCR1_MEM_RESP_NOTRDY;
+    end else if (imem_req_en) begin
+        imem_resp <= imem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
+    end
+end
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        dmem_resp <= SCR1_MEM_RESP_NOTRDY;
+    end else if (dmem_req_en) begin
+        dmem_resp <= dmem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY;
+    end
+end
+
+assign imem_req_ack = 1'b1;
+assign dmem_req_ack = 1'b1;
+//-------------------------------------------------------------------------------
+// Memory data composing
+//-------------------------------------------------------------------------------
+assign imem_rd  = imem_req;
+assign dmem_rd  = dmem_req & (dmem_cmd == SCR1_MEM_CMD_RD);
+assign dmem_wr  = dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR);
+
+always_comb begin
+    dmem_writedata = dmem_wdata;
+    dmem_byteen    = 4'b1111;
+    case ( dmem_width )
+        SCR1_MEM_WIDTH_BYTE : begin
+            dmem_writedata  = {(`SCR1_DMEM_DWIDTH /  8){dmem_wdata[7:0]}};
+            dmem_byteen     = 4'b0001 << dmem_addr[1:0];
+        end
+        SCR1_MEM_WIDTH_HWORD : begin
+            dmem_writedata  = {(`SCR1_DMEM_DWIDTH / 16){dmem_wdata[15:0]}};
+            dmem_byteen     = 4'b0011 << {dmem_addr[1], 1'b0};
+        end
+        default : begin
+        end
+    endcase
+end
+//-------------------------------------------------------------------------------
+// Memory instantiation
+//-------------------------------------------------------------------------------
+scr1_dp_memory #(
+    .SCR1_WIDTH ( 32            ),
+    .SCR1_SIZE  ( SCR1_TCM_SIZE )
+) i_dp_memory (
+    .clk    ( clk                                   ),
+    // Instruction port
+    // Port A
+    .rena   ( imem_rd                               ),
+    .addra  ( imem_addr[$clog2(SCR1_TCM_SIZE)-1:2]  ),
+    .qa     ( imem_rdata                            ),
+    // Data port
+    // Port B
+    .renb   ( dmem_rd                               ),
+    .wenb   ( dmem_wr                               ),
+    .webb   ( dmem_byteen                           ),
+    .addrb  ( dmem_addr[$clog2(SCR1_TCM_SIZE)-1:2]  ),
+    .qb     ( dmem_rdata_local                      ),
+    .datab  ( dmem_writedata                        )
+);
+//-------------------------------------------------------------------------------
+// Data memory output generation
+//-------------------------------------------------------------------------------
+always_ff @(posedge clk) begin
+    if (dmem_rd) begin
+        dmem_rdata_shift_reg <= dmem_addr[1:0];
+    end
+end
+
+assign dmem_rdata = dmem_rdata_local >> ( 8 * dmem_rdata_shift_reg );
+
+endmodule : scr1_tcm
+
+`endif // SCR1_TCM_EN
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_timer.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_timer.sv
new file mode 100644
index 0000000..343a93a
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_timer.sv
@@ -0,0 +1,271 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_timer.sv>
+/// @brief      Memory-mapped Timer
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_memif.svh"
+
+module scr1_timer (
+    // Common
+    input   logic                                   rst_n,
+    input   logic                                   clk,
+    input   logic                                   rtc_clk,
+
+    // Memory interface
+    input   logic                                   dmem_req,
+    input   type_scr1_mem_cmd_e                     dmem_cmd,
+    input   type_scr1_mem_width_e                   dmem_width,
+    input   logic [`SCR1_DMEM_AWIDTH-1:0]           dmem_addr,
+    input   logic [`SCR1_DMEM_DWIDTH-1:0]           dmem_wdata,
+    output  logic                                   dmem_req_ack,
+    output  logic [`SCR1_DMEM_DWIDTH-1:0]           dmem_rdata,
+    output  type_scr1_mem_resp_e                    dmem_resp,
+
+    // Timer interface
+    output  logic [63:0]                            timer_val,
+    output  logic                                   timer_irq
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters declaration
+//-------------------------------------------------------------------------------
+localparam int unsigned SCR1_TIMER_ADDR_WIDTH                               = 5;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_CONTROL             = 5'h0;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_DIVIDER             = 5'h4;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMELO             = 5'h8;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMEHI             = 5'hC;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMECMPLO          = 5'h10;
+localparam logic [SCR1_TIMER_ADDR_WIDTH-1:0] SCR1_TIMER_MTIMECMPHI          = 5'h14;
+
+localparam int unsigned SCR1_TIMER_CONTROL_EN_OFFSET                        = 0;
+localparam int unsigned SCR1_TIMER_CONTROL_CLKSRC_OFFSET                    = 1;
+localparam int unsigned SCR1_TIMER_DIVIDER_WIDTH                            = 10;
+
+//-------------------------------------------------------------------------------
+// Local signals declaration
+//-------------------------------------------------------------------------------
+logic [63:0]                                        mtime_reg;
+logic [63:0]                                        mtime_new;
+logic [63:0]                                        mtimecmp_reg;
+logic [63:0]                                        mtimecmp_new;
+logic                                               timer_en;
+logic                                               timer_clksrc_rtc;
+logic [SCR1_TIMER_DIVIDER_WIDTH-1:0]                timer_div;
+
+logic                                               control_up;
+logic                                               divider_up;
+logic                                               mtimelo_up;
+logic                                               mtimehi_up;
+logic                                               mtimecmplo_up;
+logic                                               mtimecmphi_up;
+
+logic                                               dmem_req_valid;
+
+logic [3:0]                                         rtc_sync;
+logic                                               rtc_ext_pulse;
+logic [SCR1_TIMER_DIVIDER_WIDTH-1:0]                timeclk_cnt;
+logic                                               timeclk_cnt_en;
+logic                                               time_posedge;
+logic                                               time_cmp_flag;
+
+//-------------------------------------------------------------------------------
+// Registers
+//-------------------------------------------------------------------------------
+
+// CONTROL
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        timer_en            <= 1'b1;
+        timer_clksrc_rtc    <= 1'b0;
+    end else begin
+        if (control_up) begin
+            timer_en            <= dmem_wdata[SCR1_TIMER_CONTROL_EN_OFFSET];
+            timer_clksrc_rtc    <= dmem_wdata[SCR1_TIMER_CONTROL_CLKSRC_OFFSET];
+        end
+    end
+end
+
+// DIVIDER
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        timer_div   <= '0;
+    end else begin
+        if (divider_up) begin
+            timer_div   <= dmem_wdata[SCR1_TIMER_DIVIDER_WIDTH-1:0];
+        end
+    end
+end
+
+// MTIME
+assign time_posedge = (timeclk_cnt_en & (timeclk_cnt == 0));
+
+always_comb begin
+    mtime_new   = mtime_reg;
+    if (time_posedge) begin
+        mtime_new   = mtime_reg + 1'b1;
+    end
+    if (mtimelo_up) begin
+        mtime_new[31:0]     = dmem_wdata;
+    end
+    if (mtimehi_up) begin
+        mtime_new[63:32]    = dmem_wdata;
+    end
+end
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        mtime_reg   <= '0;
+    end else begin
+        if (time_posedge | mtimelo_up | mtimehi_up) begin
+            mtime_reg   <= mtime_new;
+        end
+    end
+end
+
+// MTIMECMP
+always_comb begin
+    mtimecmp_new    = mtimecmp_reg;
+    if (mtimecmplo_up) begin
+        mtimecmp_new[31:0]  = dmem_wdata;
+    end
+    if (mtimecmphi_up) begin
+        mtimecmp_new[63:32] = dmem_wdata;
+    end
+end
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        mtimecmp_reg    <= '0;
+    end else begin
+        if (mtimecmplo_up | mtimecmphi_up) begin
+            mtimecmp_reg    <= mtimecmp_new;
+        end
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Interrupt pending
+//-------------------------------------------------------------------------------
+assign time_cmp_flag = (mtime_reg >= ((mtimecmplo_up | mtimecmphi_up) ? mtimecmp_new : mtimecmp_reg));
+
+always_ff @(posedge clk, negedge rst_n) begin
+    if (~rst_n) begin
+        timer_irq   <= 1'b0;
+    end else begin
+        if (~timer_irq) begin
+            timer_irq   <= time_cmp_flag;
+        end else begin // 1'b1
+            if (mtimecmplo_up | mtimecmphi_up) begin
+                timer_irq   <= time_cmp_flag;
+            end
+        end
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Timer divider
+//-------------------------------------------------------------------------------
+assign timeclk_cnt_en   = (~timer_clksrc_rtc ? 1'b1 : rtc_ext_pulse) & timer_en;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        timeclk_cnt <= '0;
+    end else begin
+        case (1'b1)
+            divider_up      : timeclk_cnt   <= dmem_wdata[SCR1_TIMER_DIVIDER_WIDTH-1:0];
+            time_posedge    : timeclk_cnt   <= timer_div;
+            timeclk_cnt_en  : timeclk_cnt   <= timeclk_cnt - 1'b1;
+            default         : begin end
+        endcase
+    end
+end
+
+//-------------------------------------------------------------------------------
+// RTC synchronization
+//-------------------------------------------------------------------------------
+assign rtc_ext_pulse    = rtc_sync[3] ^ rtc_sync[2];
+
+always_ff @(negedge rst_n, posedge rtc_clk) begin
+    if (~rst_n) begin
+        rtc_sync[0] <= 1'b0;
+    end else begin
+        if (timer_clksrc_rtc) begin
+            rtc_sync[0] <= ~rtc_sync[0];
+        end
+    end
+end
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        rtc_sync[3:1]   <= '0;
+    end else begin
+        if (timer_clksrc_rtc) begin
+            rtc_sync[3:1]   <= rtc_sync[2:0];
+        end
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Memory interface
+//-------------------------------------------------------------------------------
+assign dmem_req_valid   =   (dmem_width == SCR1_MEM_WIDTH_WORD) & (~|dmem_addr[1:0]) &
+                            (dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:2] <= SCR1_TIMER_MTIMECMPHI[SCR1_TIMER_ADDR_WIDTH-1:2]);
+
+assign dmem_req_ack     = 1'b1;
+
+always_ff @(negedge rst_n, posedge clk) begin
+    if (~rst_n) begin
+        dmem_resp   <= SCR1_MEM_RESP_NOTRDY;
+        dmem_rdata  <= '0;
+    end else begin
+        if (dmem_req) begin
+            if (dmem_req_valid) begin
+                dmem_resp   <= SCR1_MEM_RESP_RDY_OK;
+                if (dmem_cmd == SCR1_MEM_CMD_RD) begin
+                    case (dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:0])
+                        SCR1_TIMER_CONTROL      : dmem_rdata    <= `SCR1_DMEM_DWIDTH'({timer_clksrc_rtc, timer_en});
+                        SCR1_TIMER_DIVIDER      : dmem_rdata    <= `SCR1_DMEM_DWIDTH'(timer_div);
+                        SCR1_TIMER_MTIMELO      : dmem_rdata    <= mtime_reg[31:0];
+                        SCR1_TIMER_MTIMEHI      : dmem_rdata    <= mtime_reg[63:32];
+                        SCR1_TIMER_MTIMECMPLO   : dmem_rdata    <= mtimecmp_reg[31:0];
+                        SCR1_TIMER_MTIMECMPHI   : dmem_rdata    <= mtimecmp_reg[63:32];
+                        default                 : begin end
+                    endcase
+                end
+            end else begin
+                dmem_resp   <= SCR1_MEM_RESP_RDY_ER;
+            end
+        end else begin
+            dmem_resp   <= SCR1_MEM_RESP_NOTRDY;
+            dmem_rdata  <= '0;
+        end
+    end
+end
+
+always_comb begin
+    control_up      = 1'b0;
+    divider_up      = 1'b0;
+    mtimelo_up      = 1'b0;
+    mtimehi_up      = 1'b0;
+    mtimecmplo_up   = 1'b0;
+    mtimecmphi_up   = 1'b0;
+    if (dmem_req & dmem_req_valid & (dmem_cmd == SCR1_MEM_CMD_WR)) begin
+        case (dmem_addr[SCR1_TIMER_ADDR_WIDTH-1:0])
+            SCR1_TIMER_CONTROL      : control_up    = 1'b1;
+            SCR1_TIMER_DIVIDER      : divider_up    = 1'b1;
+            SCR1_TIMER_MTIMELO      : mtimelo_up    = 1'b1;
+            SCR1_TIMER_MTIMEHI      : mtimehi_up    = 1'b1;
+            SCR1_TIMER_MTIMECMPLO   : mtimecmplo_up = 1'b1;
+            SCR1_TIMER_MTIMECMPHI   : mtimecmphi_up = 1'b1;
+            default                 : begin end
+        endcase
+    end
+end
+
+//-------------------------------------------------------------------------------
+// Timer interface
+//-------------------------------------------------------------------------------
+assign timer_val    = mtime_reg;
+
+endmodule : scr1_timer
\ No newline at end of file
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_top_ahb.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_top_ahb.sv
new file mode 100644
index 0000000..2268a7d
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_top_ahb.sv
@@ -0,0 +1,513 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_top_ahb.sv>
+/// @brief      SCR1 AHB top
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_memif.svh"
+`include "scr1_ahb.svh"
+`ifdef SCR1_IPIC_EN
+`include "scr1_ipic.svh"
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_TCM_EN
+ `define SCR1_IMEM_ROUTER_EN
+`endif // SCR1_TCM_EN
+
+module scr1_top_ahb (
+    // Control
+    input   logic                                   pwrup_rst_n,            // Power-Up Reset
+    input   logic                                   rst_n,                  // Regular Reset signal
+    input   logic                                   cpu_rst_n,              // CPU Reset (Core Reset)
+    input   logic                                   test_mode,              // Test mode
+    input   logic                                   test_rst_n,             // Test mode's reset
+    input   logic                                   clk,                    // System clock
+    input   logic                                   rtc_clk,                // Real-time clock
+`ifdef SCR1_DBG_EN
+    output  logic                                   sys_rst_n_o,            // External System Reset output
+                                                                            //   (for the processor cluster's components or
+                                                                            //    external SOC (could be useful in small
+                                                                            //    SCR-core-centric SOCs))
+    output  logic                                   sys_rdc_qlfy_o,         // System-to-External SOC Reset Domain Crossing Qualifier
+`endif // SCR1_DBG_EN
+
+    // Fuses
+    input   logic [`SCR1_XLEN-1:0]                  fuse_mhartid,           // Hart ID
+`ifdef SCR1_DBG_EN
+    input   logic [31:0]                            fuse_idcode,            // TAPC IDCODE
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    input   logic [SCR1_IRQ_LINES_NUM-1:0]          irq_lines,              // IRQ lines to IPIC
+`else // SCR1_IPIC_EN
+    input   logic                                   ext_irq,                // External IRQ input
+`endif // SCR1_IPIC_EN
+    input   logic                                   soft_irq,               // Software IRQ input
+
+`ifdef SCR1_DBG_EN
+    // -- JTAG I/F
+    input   logic                                   trst_n,
+    input   logic                                   tck,
+    input   logic                                   tms,
+    input   logic                                   tdi,
+    output  logic                                   tdo,
+    output  logic                                   tdo_en,
+`endif // SCR1_DBG_EN
+
+    // Instruction Memory Interface
+    output  logic [3:0]                             imem_hprot,
+    output  logic [2:0]                             imem_hburst,
+    output  logic [2:0]                             imem_hsize,
+    output  logic [1:0]                             imem_htrans,
+    output  logic                                   imem_hmastlock,
+    output  logic [SCR1_AHB_WIDTH-1:0]              imem_haddr,
+    input   logic                                   imem_hready,
+    input   logic [SCR1_AHB_WIDTH-1:0]              imem_hrdata,
+    input   logic                                   imem_hresp,
+
+    // Data Memory Interface
+    output  logic [3:0]                             dmem_hprot,
+    output  logic [2:0]                             dmem_hburst,
+    output  logic [2:0]                             dmem_hsize,
+    output  logic [1:0]                             dmem_htrans,
+    output  logic                                   dmem_hmastlock,
+    output  logic [SCR1_AHB_WIDTH-1:0]              dmem_haddr,
+    output  logic                                   dmem_hwrite,
+    output  logic [SCR1_AHB_WIDTH-1:0]              dmem_hwdata,
+    input   logic                                   dmem_hready,
+    input   logic [SCR1_AHB_WIDTH-1:0]              dmem_hrdata,
+    input   logic                                   dmem_hresp
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters
+//-------------------------------------------------------------------------------
+localparam int unsigned SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM            = 2;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+// Reset logic
+logic                                               pwrup_rst_n_sync;
+logic                                               rst_n_sync;
+logic                                               cpu_rst_n_sync;
+logic                                               core_rst_n_local;
+`ifdef SCR1_DBG_EN
+logic                                               tapc_trst_n;
+`endif // SCR1_DBG_EN
+
+// Instruction memory interface from core to router
+logic                                               core_imem_req_ack;
+logic                                               core_imem_req;
+type_scr1_mem_cmd_e                                 core_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       core_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       core_imem_rdata;
+type_scr1_mem_resp_e                                core_imem_resp;
+
+// Data memory interface from core to router
+logic                                               core_dmem_req_ack;
+logic                                               core_dmem_req;
+type_scr1_mem_cmd_e                                 core_dmem_cmd;
+type_scr1_mem_width_e                               core_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       core_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       core_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       core_dmem_rdata;
+type_scr1_mem_resp_e                                core_dmem_resp;
+
+// Instruction memory interface from router to AHB bridge
+logic                                               ahb_imem_req_ack;
+logic                                               ahb_imem_req;
+type_scr1_mem_cmd_e                                 ahb_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       ahb_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       ahb_imem_rdata;
+type_scr1_mem_resp_e                                ahb_imem_resp;
+
+// Data memory interface from router to AHB bridge
+logic                                               ahb_dmem_req_ack;
+logic                                               ahb_dmem_req;
+type_scr1_mem_cmd_e                                 ahb_dmem_cmd;
+type_scr1_mem_width_e                               ahb_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       ahb_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       ahb_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       ahb_dmem_rdata;
+type_scr1_mem_resp_e                                ahb_dmem_resp;
+
+`ifdef SCR1_TCM_EN
+// Instruction memory interface from router to TCM
+logic                                               tcm_imem_req_ack;
+logic                                               tcm_imem_req;
+type_scr1_mem_cmd_e                                 tcm_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       tcm_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       tcm_imem_rdata;
+type_scr1_mem_resp_e                                tcm_imem_resp;
+
+// Data memory interface from router to TCM
+logic                                               tcm_dmem_req_ack;
+logic                                               tcm_dmem_req;
+type_scr1_mem_cmd_e                                 tcm_dmem_cmd;
+type_scr1_mem_width_e                               tcm_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       tcm_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       tcm_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       tcm_dmem_rdata;
+type_scr1_mem_resp_e                                tcm_dmem_resp;
+`endif // SCR1_TCM_EN
+
+// Data memory interface from router to memory-mapped timer
+logic                                               timer_dmem_req_ack;
+logic                                               timer_dmem_req;
+type_scr1_mem_cmd_e                                 timer_dmem_cmd;
+type_scr1_mem_width_e                               timer_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       timer_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       timer_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       timer_dmem_rdata;
+type_scr1_mem_resp_e                                timer_dmem_resp;
+
+logic                                               timer_irq;
+logic [63:0]                                        timer_val;
+
+
+//-------------------------------------------------------------------------------
+// Reset logic
+//-------------------------------------------------------------------------------
+// Power-Up Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_pwrup_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (1'b1            ),
+    .rst_n_out      (pwrup_rst_n_sync)
+);
+
+// Regular Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (rst_n           ),
+    .rst_n_out      (rst_n_sync      )
+);
+
+// CPU Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_cpu_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (cpu_rst_n       ),
+    .rst_n_out      (cpu_rst_n_sync  )
+);
+
+`ifdef SCR1_DBG_EN
+// TAPC Reset
+scr1_reset_and2_cell i_tapc_rstn_and2_cell (
+    .rst_n_in       ({trst_n, pwrup_rst_n}),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_out      (tapc_trst_n     )
+);
+`endif // SCR1_DBG_EN
+
+//-------------------------------------------------------------------------------
+// SCR1 core instance
+//-------------------------------------------------------------------------------
+scr1_core_top i_core_top (
+    // Common
+    .pwrup_rst_n                (pwrup_rst_n_sync ),
+    .rst_n                      (rst_n_sync       ),
+    .cpu_rst_n                  (cpu_rst_n_sync   ),
+    .test_mode                  (test_mode        ),
+    .test_rst_n                 (test_rst_n       ),
+    .clk                        (clk              ),
+    .core_rst_n_o               (core_rst_n_local ),
+    .core_rdc_qlfy_o            (                 ),
+`ifdef SCR1_DBG_EN
+    .sys_rst_n_o                (sys_rst_n_o      ),
+    .sys_rdc_qlfy_o             (sys_rdc_qlfy_o   ),
+`endif // SCR1_DBG_EN
+
+    // Fuses
+    .core_fuse_mhartid_i        (fuse_mhartid     ),
+`ifdef SCR1_DBG_EN
+    .tapc_fuse_idcode_i         (fuse_idcode      ),
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    .core_irq_lines_i           (irq_lines        ),
+`else // SCR1_IPIC_EN
+    .core_irq_ext_i             (ext_irq          ),
+`endif // SCR1_IPIC_EN
+    .core_irq_soft_i            (soft_irq         ),
+    .core_irq_mtimer_i          (timer_irq        ),
+
+    // Memory-mapped external timer
+    .core_mtimer_val_i          (timer_val        ),
+
+`ifdef SCR1_DBG_EN
+    // Debug interface
+    .tapc_trst_n                (tapc_trst_n      ),
+    .tapc_tck                   (tck              ),
+    .tapc_tms                   (tms              ),
+    .tapc_tdi                   (tdi              ),
+    .tapc_tdo                   (tdo              ),
+    .tapc_tdo_en                (tdo_en           ),
+`endif // SCR1_DBG_EN
+
+    // Instruction memory interface
+    .imem2core_req_ack_i        (core_imem_req_ack),
+    .core2imem_req_o            (core_imem_req    ),
+    .core2imem_cmd_o            (core_imem_cmd    ),
+    .core2imem_addr_o           (core_imem_addr   ),
+    .imem2core_rdata_i          (core_imem_rdata  ),
+    .imem2core_resp_i           (core_imem_resp   ),
+
+    // Data memory interface
+    .dmem2core_req_ack_i        (core_dmem_req_ack),
+    .core2dmem_req_o            (core_dmem_req    ),
+    .core2dmem_cmd_o            (core_dmem_cmd    ),
+    .core2dmem_width_o          (core_dmem_width  ),
+    .core2dmem_addr_o           (core_dmem_addr   ),
+    .core2dmem_wdata_o          (core_dmem_wdata  ),
+    .dmem2core_rdata_i          (core_dmem_rdata  ),
+    .dmem2core_resp_i           (core_dmem_resp   )
+);
+
+
+`ifdef SCR1_TCM_EN
+//-------------------------------------------------------------------------------
+// TCM instance
+//-------------------------------------------------------------------------------
+scr1_tcm #(
+    .SCR1_TCM_SIZE  (`SCR1_DMEM_AWIDTH'(~SCR1_TCM_ADDR_MASK + 1'b1))
+) i_tcm (
+    .clk            (clk             ),
+    .rst_n          (core_rst_n_local),
+
+    // Instruction interface to TCM
+    .imem_req_ack   (tcm_imem_req_ack),
+    .imem_req       (tcm_imem_req    ),
+    .imem_addr      (tcm_imem_addr   ),
+    .imem_rdata     (tcm_imem_rdata  ),
+    .imem_resp      (tcm_imem_resp   ),
+
+    // Data interface to TCM
+    .dmem_req_ack   (tcm_dmem_req_ack),
+    .dmem_req       (tcm_dmem_req    ),
+    .dmem_cmd       (tcm_dmem_cmd    ),
+    .dmem_width     (tcm_dmem_width  ),
+    .dmem_addr      (tcm_dmem_addr   ),
+    .dmem_wdata     (tcm_dmem_wdata  ),
+    .dmem_rdata     (tcm_dmem_rdata  ),
+    .dmem_resp      (tcm_dmem_resp   )
+);
+`endif // SCR1_TCM_EN
+
+
+//-------------------------------------------------------------------------------
+// Memory-mapped timer instance
+//-------------------------------------------------------------------------------
+scr1_timer i_timer (
+    // Common
+    .rst_n          (core_rst_n_local  ),
+    .clk            (clk               ),
+    .rtc_clk        (rtc_clk           ),
+
+    // Memory interface
+    .dmem_req       (timer_dmem_req    ),
+    .dmem_cmd       (timer_dmem_cmd    ),
+    .dmem_width     (timer_dmem_width  ),
+    .dmem_addr      (timer_dmem_addr   ),
+    .dmem_wdata     (timer_dmem_wdata  ),
+    .dmem_req_ack   (timer_dmem_req_ack),
+    .dmem_rdata     (timer_dmem_rdata  ),
+    .dmem_resp      (timer_dmem_resp   ),
+
+    // Timer interface
+    .timer_val      (timer_val         ),
+    .timer_irq      (timer_irq         )
+);
+
+
+`ifdef SCR1_IMEM_ROUTER_EN
+//-------------------------------------------------------------------------------
+// Instruction memory router
+//-------------------------------------------------------------------------------
+scr1_imem_router #(
+ `ifdef SCR1_TCM_EN
+    .SCR1_ADDR_MASK     (SCR1_TCM_ADDR_MASK),
+    .SCR1_ADDR_PATTERN  (SCR1_TCM_ADDR_PATTERN)
+ `endif // SCR1_TCM_EN
+) i_imem_router (
+    .rst_n          (core_rst_n_local ),
+    .clk            (clk              ),
+    // Interface to core
+    .imem_req_ack   (core_imem_req_ack),
+    .imem_req       (core_imem_req    ),
+    .imem_cmd       (core_imem_cmd    ),
+    .imem_addr      (core_imem_addr   ),
+    .imem_rdata     (core_imem_rdata  ),
+    .imem_resp      (core_imem_resp   ),
+    // Interface to AHB bridge
+    .port0_req_ack  (ahb_imem_req_ack ),
+    .port0_req      (ahb_imem_req     ),
+    .port0_cmd      (ahb_imem_cmd     ),
+    .port0_addr     (ahb_imem_addr    ),
+    .port0_rdata    (ahb_imem_rdata   ),
+    .port0_resp     (ahb_imem_resp    ),
+ `ifdef SCR1_TCM_EN
+    // Interface to TCM
+    .port1_req_ack  (tcm_imem_req_ack ),
+    .port1_req      (tcm_imem_req     ),
+    .port1_cmd      (tcm_imem_cmd     ),
+    .port1_addr     (tcm_imem_addr    ),
+    .port1_rdata    (tcm_imem_rdata   ),
+    .port1_resp     (tcm_imem_resp    )
+ `endif // SCR1_TCM_EN
+);
+
+`else // SCR1_IMEM_ROUTER_EN
+
+assign ahb_imem_req         = core_imem_req;
+assign ahb_imem_cmd         = core_imem_cmd;
+assign ahb_imem_addr        = core_imem_addr;
+assign core_imem_req_ack    = ahb_imem_req_ack;
+assign core_imem_resp       = ahb_imem_resp;
+assign core_imem_rdata      = ahb_imem_rdata;
+
+`endif // SCR1_IMEM_ROUTER_EN
+
+//-------------------------------------------------------------------------------
+// Data memory router
+//-------------------------------------------------------------------------------
+scr1_dmem_router #(
+
+`ifdef SCR1_TCM_EN
+    .SCR1_PORT1_ADDR_MASK       (SCR1_TCM_ADDR_MASK),
+    .SCR1_PORT1_ADDR_PATTERN    (SCR1_TCM_ADDR_PATTERN),
+`else // SCR1_TCM_EN
+    .SCR1_PORT1_ADDR_MASK       (32'h00000000),
+    .SCR1_PORT1_ADDR_PATTERN    (32'hFFFFFFFF),
+`endif // SCR1_TCM_EN
+
+    .SCR1_PORT2_ADDR_MASK       (SCR1_TIMER_ADDR_MASK),
+    .SCR1_PORT2_ADDR_PATTERN    (SCR1_TIMER_ADDR_PATTERN)
+
+) i_dmem_router (
+    .rst_n          (core_rst_n_local    ),
+    .clk            (clk                 ),
+    // Interface to core
+    .dmem_req_ack   (core_dmem_req_ack   ),
+    .dmem_req       (core_dmem_req       ),
+    .dmem_cmd       (core_dmem_cmd       ),
+    .dmem_width     (core_dmem_width     ),
+    .dmem_addr      (core_dmem_addr      ),
+    .dmem_wdata     (core_dmem_wdata     ),
+    .dmem_rdata     (core_dmem_rdata     ),
+    .dmem_resp      (core_dmem_resp      ),
+`ifdef SCR1_TCM_EN
+    // Interface to TCM
+    .port1_req_ack  (tcm_dmem_req_ack    ),
+    .port1_req      (tcm_dmem_req        ),
+    .port1_cmd      (tcm_dmem_cmd        ),
+    .port1_width    (tcm_dmem_width      ),
+    .port1_addr     (tcm_dmem_addr       ),
+    .port1_wdata    (tcm_dmem_wdata      ),
+    .port1_rdata    (tcm_dmem_rdata      ),
+    .port1_resp     (tcm_dmem_resp       ),
+`else // SCR1_TCM_EN
+    .port1_req_ack  (1'b0),
+    .port1_req      (                    ),
+    .port1_cmd      (                    ),
+    .port1_width    (                    ),
+    .port1_addr     (                    ),
+    .port1_wdata    (                    ),
+    .port1_rdata    ('0                  ),
+    .port1_resp     (SCR1_MEM_RESP_RDY_ER),
+`endif // SCR1_TCM_EN
+    // Interface to memory-mapped timer
+    .port2_req_ack  (timer_dmem_req_ack  ),
+    .port2_req      (timer_dmem_req      ),
+    .port2_cmd      (timer_dmem_cmd      ),
+    .port2_width    (timer_dmem_width    ),
+    .port2_addr     (timer_dmem_addr     ),
+    .port2_wdata    (timer_dmem_wdata    ),
+    .port2_rdata    (timer_dmem_rdata    ),
+    .port2_resp     (timer_dmem_resp     ),
+    // Interface to AHB bridge
+    .port0_req_ack  (ahb_dmem_req_ack    ),
+    .port0_req      (ahb_dmem_req        ),
+    .port0_cmd      (ahb_dmem_cmd        ),
+    .port0_width    (ahb_dmem_width      ),
+    .port0_addr     (ahb_dmem_addr       ),
+    .port0_wdata    (ahb_dmem_wdata      ),
+    .port0_rdata    (ahb_dmem_rdata      ),
+    .port0_resp     (ahb_dmem_resp       )
+);
+
+
+//-------------------------------------------------------------------------------
+// Instruction memory AHB bridge
+//-------------------------------------------------------------------------------
+scr1_imem_ahb i_imem_ahb (
+    .rst_n          (core_rst_n_local   ),
+    .clk            (clk                ),
+    // Interface to imem router
+    .imem_req_ack   (ahb_imem_req_ack   ),
+    .imem_req       (ahb_imem_req       ),
+    .imem_addr      (ahb_imem_addr      ),
+    .imem_rdata     (ahb_imem_rdata     ),
+    .imem_resp      (ahb_imem_resp      ),
+    // AHB interface
+    .hprot          (imem_hprot         ),
+    .hburst         (imem_hburst        ),
+    .hsize          (imem_hsize         ),
+    .htrans         (imem_htrans        ),
+    .hmastlock      (imem_hmastlock     ),
+    .haddr          (imem_haddr         ),
+    .hready         (imem_hready        ),
+    .hrdata         (imem_hrdata        ),
+    .hresp          (imem_hresp         )
+);
+
+
+//-------------------------------------------------------------------------------
+// Data memory AHB bridge
+//-------------------------------------------------------------------------------
+scr1_dmem_ahb i_dmem_ahb (
+    .rst_n          (core_rst_n_local   ),
+    .clk            (clk                ),
+    // Interface to dmem router
+    .dmem_req_ack   (ahb_dmem_req_ack   ),
+    .dmem_req       (ahb_dmem_req       ),
+    .dmem_cmd       (ahb_dmem_cmd       ),
+    .dmem_width     (ahb_dmem_width     ),
+    .dmem_addr      (ahb_dmem_addr      ),
+    .dmem_wdata     (ahb_dmem_wdata     ),
+    .dmem_rdata     (ahb_dmem_rdata     ),
+    .dmem_resp      (ahb_dmem_resp      ),
+    // AHB interface
+    .hprot          (dmem_hprot         ),
+    .hburst         (dmem_hburst        ),
+    .hsize          (dmem_hsize         ),
+    .htrans         (dmem_htrans        ),
+    .hmastlock      (dmem_hmastlock     ),
+    .haddr          (dmem_haddr         ),
+    .hwrite         (dmem_hwrite        ),
+    .hwdata         (dmem_hwdata        ),
+    .hready         (dmem_hready        ),
+    .hrdata         (dmem_hrdata        ),
+    .hresp          (dmem_hresp         )
+);
+
+endmodule : scr1_top_ahb
+
+
diff --git a/verilog/rtl/syntacore_scr1/src/top/scr1_top_axi.sv b/verilog/rtl/syntacore_scr1/src/top/scr1_top_axi.sv
new file mode 100644
index 0000000..735b902
--- /dev/null
+++ b/verilog/rtl/syntacore_scr1/src/top/scr1_top_axi.sv
@@ -0,0 +1,701 @@
+/// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details
+/// @file       <scr1_top_axi.sv>
+/// @brief      SCR1 AXI top
+///
+
+`include "scr1_arch_description.svh"
+`include "scr1_memif.svh"
+`ifdef SCR1_IPIC_EN
+`include "scr1_ipic.svh"
+`endif // SCR1_IPIC_EN
+
+`ifdef SCR1_TCM_EN
+ `define SCR1_IMEM_ROUTER_EN
+`endif // SCR1_TCM_EN
+
+module scr1_top_axi (
+    // Control
+    input   logic                                   pwrup_rst_n,            // Power-Up Reset
+    input   logic                                   rst_n,                  // Regular Reset signal
+    input   logic                                   cpu_rst_n,              // CPU Reset (Core Reset)
+    input   logic                                   test_mode,              // Test mode
+    input   logic                                   test_rst_n,             // Test mode's reset
+    input   logic                                   clk,                    // System clock
+    input   logic                                   rtc_clk,                // Real-time clock
+`ifdef SCR1_DBG_EN
+    output  logic                                   sys_rst_n_o,            // External System Reset output
+                                                                            //   (for the processor cluster's components or
+                                                                            //    external SOC (could be useful in small
+                                                                            //    SCR-core-centric SOCs))
+    output  logic                                   sys_rdc_qlfy_o,         // System-to-External SOC Reset Domain Crossing Qualifier
+`endif // SCR1_DBG_EN
+
+    // Fuses
+    input   logic [`SCR1_XLEN-1:0]                  fuse_mhartid,           // Hart ID
+`ifdef SCR1_DBG_EN
+    input   logic [31:0]                            fuse_idcode,            // TAPC IDCODE
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    input   logic [SCR1_IRQ_LINES_NUM-1:0]          irq_lines,              // IRQ lines to IPIC
+`else // SCR1_IPIC_EN
+    input   logic                                   ext_irq,                // External IRQ input
+`endif // SCR1_IPIC_EN
+    input   logic                                   soft_irq,               // Software IRQ input
+
+`ifdef SCR1_DBG_EN
+    // -- JTAG I/F
+    input   logic                                   trst_n,
+    input   logic                                   tck,
+    input   logic                                   tms,
+    input   logic                                   tdi,
+    output  logic                                   tdo,
+    output  logic                                   tdo_en,
+`endif // SCR1_DBG_EN
+
+    // Instruction Memory Interface
+    output  logic [3:0]                             io_axi_imem_awid,
+    output  logic [31:0]                            io_axi_imem_awaddr,
+    output  logic [7:0]                             io_axi_imem_awlen,
+    output  logic [2:0]                             io_axi_imem_awsize,
+    output  logic [1:0]                             io_axi_imem_awburst,
+    output  logic                                   io_axi_imem_awlock,
+    output  logic [3:0]                             io_axi_imem_awcache,
+    output  logic [2:0]                             io_axi_imem_awprot,
+    output  logic [3:0]                             io_axi_imem_awregion,
+    output  logic [3:0]                             io_axi_imem_awuser,
+    output  logic [3:0]                             io_axi_imem_awqos,
+    output  logic                                   io_axi_imem_awvalid,
+    input   logic                                   io_axi_imem_awready,
+    output  logic [31:0]                            io_axi_imem_wdata,
+    output  logic [3:0]                             io_axi_imem_wstrb,
+    output  logic                                   io_axi_imem_wlast,
+    output  logic [3:0]                             io_axi_imem_wuser,
+    output  logic                                   io_axi_imem_wvalid,
+    input   logic                                   io_axi_imem_wready,
+    input   logic [3:0]                             io_axi_imem_bid,
+    input   logic [1:0]                             io_axi_imem_bresp,
+    input   logic                                   io_axi_imem_bvalid,
+    input   logic [3:0]                             io_axi_imem_buser,
+    output  logic                                   io_axi_imem_bready,
+    output  logic [3:0]                             io_axi_imem_arid,
+    output  logic [31:0]                            io_axi_imem_araddr,
+    output  logic [7:0]                             io_axi_imem_arlen,
+    output  logic [2:0]                             io_axi_imem_arsize,
+    output  logic [1:0]                             io_axi_imem_arburst,
+    output  logic                                   io_axi_imem_arlock,
+    output  logic [3:0]                             io_axi_imem_arcache,
+    output  logic [2:0]                             io_axi_imem_arprot,
+    output  logic [3:0]                             io_axi_imem_arregion,
+    output  logic [3:0]                             io_axi_imem_aruser,
+    output  logic [3:0]                             io_axi_imem_arqos,
+    output  logic                                   io_axi_imem_arvalid,
+    input   logic                                   io_axi_imem_arready,
+    input   logic [3:0]                             io_axi_imem_rid,
+    input   logic [31:0]                            io_axi_imem_rdata,
+    input   logic [1:0]                             io_axi_imem_rresp,
+    input   logic                                   io_axi_imem_rlast,
+    input   logic [3:0]                             io_axi_imem_ruser,
+    input   logic                                   io_axi_imem_rvalid,
+    output  logic                                   io_axi_imem_rready,
+
+    // Data Memory Interface
+    output  logic [3:0]                             io_axi_dmem_awid,
+    output  logic [31:0]                            io_axi_dmem_awaddr,
+    output  logic [7:0]                             io_axi_dmem_awlen,
+    output  logic [2:0]                             io_axi_dmem_awsize,
+    output  logic [1:0]                             io_axi_dmem_awburst,
+    output  logic                                   io_axi_dmem_awlock,
+    output  logic [3:0]                             io_axi_dmem_awcache,
+    output  logic [2:0]                             io_axi_dmem_awprot,
+    output  logic [3:0]                             io_axi_dmem_awregion,
+    output  logic [3:0]                             io_axi_dmem_awuser,
+    output  logic [3:0]                             io_axi_dmem_awqos,
+    output  logic                                   io_axi_dmem_awvalid,
+    input   logic                                   io_axi_dmem_awready,
+    output  logic [31:0]                            io_axi_dmem_wdata,
+    output  logic [3:0]                             io_axi_dmem_wstrb,
+    output  logic                                   io_axi_dmem_wlast,
+    output  logic [3:0]                             io_axi_dmem_wuser,
+    output  logic                                   io_axi_dmem_wvalid,
+    input   logic                                   io_axi_dmem_wready,
+    input   logic [3:0]                             io_axi_dmem_bid,
+    input   logic [1:0]                             io_axi_dmem_bresp,
+    input   logic                                   io_axi_dmem_bvalid,
+    input   logic [3:0]                             io_axi_dmem_buser,
+    output  logic                                   io_axi_dmem_bready,
+    output  logic [3:0]                             io_axi_dmem_arid,
+    output  logic [31:0]                            io_axi_dmem_araddr,
+    output  logic [7:0]                             io_axi_dmem_arlen,
+    output  logic [2:0]                             io_axi_dmem_arsize,
+    output  logic [1:0]                             io_axi_dmem_arburst,
+    output  logic                                   io_axi_dmem_arlock,
+    output  logic [3:0]                             io_axi_dmem_arcache,
+    output  logic [2:0]                             io_axi_dmem_arprot,
+    output  logic [3:0]                             io_axi_dmem_arregion,
+    output  logic [3:0]                             io_axi_dmem_aruser,
+    output  logic [3:0]                             io_axi_dmem_arqos,
+    output  logic                                   io_axi_dmem_arvalid,
+    input   logic                                   io_axi_dmem_arready,
+    input   logic [3:0]                             io_axi_dmem_rid,
+    input   logic [31:0]                            io_axi_dmem_rdata,
+    input   logic [1:0]                             io_axi_dmem_rresp,
+    input   logic                                   io_axi_dmem_rlast,
+    input   logic [3:0]                             io_axi_dmem_ruser,
+    input   logic                                   io_axi_dmem_rvalid,
+    output  logic                                   io_axi_dmem_rready
+);
+
+//-------------------------------------------------------------------------------
+// Local parameters
+//-------------------------------------------------------------------------------
+localparam int unsigned SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM            = 2;
+
+//-------------------------------------------------------------------------------
+// Local signal declaration
+//-------------------------------------------------------------------------------
+// Reset logic
+logic                                               pwrup_rst_n_sync;
+logic                                               rst_n_sync;
+logic                                               cpu_rst_n_sync;
+logic                                               core_rst_n_local;
+logic                                               axi_rst_n;
+`ifdef SCR1_DBG_EN
+logic                                               tapc_trst_n;
+`endif // SCR1_DBG_EN
+
+// Instruction memory interface from core to router
+logic                                               core_imem_req_ack;
+logic                                               core_imem_req;
+type_scr1_mem_cmd_e                                 core_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       core_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       core_imem_rdata;
+type_scr1_mem_resp_e                                core_imem_resp;
+
+// Data memory interface from core to router
+logic                                               core_dmem_req_ack;
+logic                                               core_dmem_req;
+type_scr1_mem_cmd_e                                 core_dmem_cmd;
+type_scr1_mem_width_e                               core_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       core_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       core_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       core_dmem_rdata;
+type_scr1_mem_resp_e                                core_dmem_resp;
+
+// Instruction memory interface from router to AXI bridge
+logic                                               axi_imem_req_ack;
+logic                                               axi_imem_req;
+type_scr1_mem_cmd_e                                 axi_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       axi_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       axi_imem_rdata;
+type_scr1_mem_resp_e                                axi_imem_resp;
+
+// Data memory interface from router to AXI bridge
+logic                                               axi_dmem_req_ack;
+logic                                               axi_dmem_req;
+type_scr1_mem_cmd_e                                 axi_dmem_cmd;
+type_scr1_mem_width_e                               axi_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       axi_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       axi_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       axi_dmem_rdata;
+type_scr1_mem_resp_e                                axi_dmem_resp;
+
+`ifdef SCR1_TCM_EN
+// Instruction memory interface from router to TCM
+logic                                               tcm_imem_req_ack;
+logic                                               tcm_imem_req;
+type_scr1_mem_cmd_e                                 tcm_imem_cmd;
+logic [`SCR1_IMEM_AWIDTH-1:0]                       tcm_imem_addr;
+logic [`SCR1_IMEM_DWIDTH-1:0]                       tcm_imem_rdata;
+type_scr1_mem_resp_e                                tcm_imem_resp;
+
+// Data memory interface from router to TCM
+logic                                               tcm_dmem_req_ack;
+logic                                               tcm_dmem_req;
+type_scr1_mem_cmd_e                                 tcm_dmem_cmd;
+type_scr1_mem_width_e                               tcm_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       tcm_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       tcm_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       tcm_dmem_rdata;
+type_scr1_mem_resp_e                                tcm_dmem_resp;
+`endif // SCR1_TCM_EN
+
+// Data memory interface from router to memory-mapped timer
+logic                                               timer_dmem_req_ack;
+logic                                               timer_dmem_req;
+type_scr1_mem_cmd_e                                 timer_dmem_cmd;
+type_scr1_mem_width_e                               timer_dmem_width;
+logic [`SCR1_DMEM_AWIDTH-1:0]                       timer_dmem_addr;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       timer_dmem_wdata;
+logic [`SCR1_DMEM_DWIDTH-1:0]                       timer_dmem_rdata;
+type_scr1_mem_resp_e                                timer_dmem_resp;
+
+// Misc
+logic                                               timer_irq;
+logic [63:0]                                        timer_val;
+logic                                               axi_reinit;
+logic                                               axi_imem_idle;
+logic                                               axi_dmem_idle;
+
+//-------------------------------------------------------------------------------
+// Reset logic
+//-------------------------------------------------------------------------------
+// Power-Up Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_pwrup_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (1'b1            ),
+    .rst_n_out      (pwrup_rst_n_sync)
+);
+
+// Regular Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (rst_n           ),
+    .rst_n_out      (rst_n_sync      )
+);
+
+// CPU Reset synchronizer
+scr1_reset_sync_cell #(
+    .STAGES_AMOUNT       (SCR1_CLUSTER_TOP_RST_SYNC_STAGES_NUM)
+) i_cpu_rstn_reset_sync (
+    .rst_n          (pwrup_rst_n     ),
+    .clk            (clk             ),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_in       (cpu_rst_n       ),
+    .rst_n_out      (cpu_rst_n_sync  )
+);
+
+`ifdef SCR1_DBG_EN
+// TAPC Reset
+scr1_reset_and2_cell i_tapc_rstn_and2_cell (
+    .rst_n_in       ({trst_n, pwrup_rst_n}),
+    .test_rst_n     (test_rst_n      ),
+    .test_mode      (test_mode       ),
+    .rst_n_out      (tapc_trst_n     )
+);
+`endif // SCR1_DBG_EN
+
+`ifdef SCR1_DBG_EN
+assign axi_rst_n = sys_rst_n_o;
+`else // SCR1_DBG_EN
+assign axi_rst_n = rst_n_sync;
+`endif // SCR1_DBG_EN
+
+//-------------------------------------------------------------------------------
+// SCR1 core instance
+//-------------------------------------------------------------------------------
+scr1_core_top i_core_top (
+    // Common
+    .pwrup_rst_n                (pwrup_rst_n_sync ),
+    .rst_n                      (rst_n_sync       ),
+    .cpu_rst_n                  (cpu_rst_n_sync   ),
+    .test_mode                  (test_mode        ),
+    .test_rst_n                 (test_rst_n       ),
+    .clk                        (clk              ),
+    .core_rst_n_o               (core_rst_n_local ),
+    .core_rdc_qlfy_o            (                 ),
+`ifdef SCR1_DBG_EN
+    .sys_rst_n_o                (sys_rst_n_o      ),
+    .sys_rdc_qlfy_o             (sys_rdc_qlfy_o   ),
+`endif // SCR1_DBG_EN
+
+    // Fuses
+    .core_fuse_mhartid_i        (fuse_mhartid     ),
+`ifdef SCR1_DBG_EN
+    .tapc_fuse_idcode_i         (fuse_idcode      ),
+`endif // SCR1_DBG_EN
+
+    // IRQ
+`ifdef SCR1_IPIC_EN
+    .core_irq_lines_i           (irq_lines        ),
+`else // SCR1_IPIC_EN
+    .core_irq_ext_i             (ext_irq          ),
+`endif // SCR1_IPIC_EN
+    .core_irq_soft_i            (soft_irq         ),
+    .core_irq_mtimer_i          (timer_irq        ),
+
+    // Memory-mapped external timer
+    .core_mtimer_val_i          (timer_val        ),
+
+`ifdef SCR1_DBG_EN
+    // Debug interface
+    .tapc_trst_n                (tapc_trst_n      ),
+    .tapc_tck                   (tck              ),
+    .tapc_tms                   (tms              ),
+    .tapc_tdi                   (tdi              ),
+    .tapc_tdo                   (tdo              ),
+    .tapc_tdo_en                (tdo_en           ),
+`endif // SCR1_DBG_EN
+
+    // Instruction memory interface
+    .imem2core_req_ack_i        (core_imem_req_ack),
+    .core2imem_req_o            (core_imem_req    ),
+    .core2imem_cmd_o            (core_imem_cmd    ),
+    .core2imem_addr_o           (core_imem_addr   ),
+    .imem2core_rdata_i          (core_imem_rdata  ),
+    .imem2core_resp_i           (core_imem_resp   ),
+
+    // Data memory interface
+    .dmem2core_req_ack_i        (core_dmem_req_ack),
+    .core2dmem_req_o            (core_dmem_req    ),
+    .core2dmem_cmd_o            (core_dmem_cmd    ),
+    .core2dmem_width_o          (core_dmem_width  ),
+    .core2dmem_addr_o           (core_dmem_addr   ),
+    .core2dmem_wdata_o          (core_dmem_wdata  ),
+    .dmem2core_rdata_i          (core_dmem_rdata  ),
+    .dmem2core_resp_i           (core_dmem_resp   )
+);
+
+
+`ifdef SCR1_TCM_EN
+//-------------------------------------------------------------------------------
+// TCM instance
+//-------------------------------------------------------------------------------
+scr1_tcm #(
+    .SCR1_TCM_SIZE  (`SCR1_DMEM_AWIDTH'(~SCR1_TCM_ADDR_MASK + 1'b1))
+) i_tcm (
+    .clk            (clk             ),
+    .rst_n          (core_rst_n_local),
+
+    // Instruction interface to TCM
+    .imem_req_ack   (tcm_imem_req_ack),
+    .imem_req       (tcm_imem_req    ),
+    .imem_addr      (tcm_imem_addr   ),
+    .imem_rdata     (tcm_imem_rdata  ),
+    .imem_resp      (tcm_imem_resp   ),
+
+    // Data interface to TCM
+    .dmem_req_ack   (tcm_dmem_req_ack),
+    .dmem_req       (tcm_dmem_req    ),
+    .dmem_cmd       (tcm_dmem_cmd    ),
+    .dmem_width     (tcm_dmem_width  ),
+    .dmem_addr      (tcm_dmem_addr   ),
+    .dmem_wdata     (tcm_dmem_wdata  ),
+    .dmem_rdata     (tcm_dmem_rdata  ),
+    .dmem_resp      (tcm_dmem_resp   )
+);
+`endif // SCR1_TCM_EN
+
+
+//-------------------------------------------------------------------------------
+// Memory-mapped timer instance
+//-------------------------------------------------------------------------------
+scr1_timer i_timer (
+    // Common
+    .rst_n          (core_rst_n_local  ),
+    .clk            (clk               ),
+    .rtc_clk        (rtc_clk           ),
+
+    // Memory interface
+    .dmem_req       (timer_dmem_req    ),
+    .dmem_cmd       (timer_dmem_cmd    ),
+    .dmem_width     (timer_dmem_width  ),
+    .dmem_addr      (timer_dmem_addr   ),
+    .dmem_wdata     (timer_dmem_wdata  ),
+    .dmem_req_ack   (timer_dmem_req_ack),
+    .dmem_rdata     (timer_dmem_rdata  ),
+    .dmem_resp      (timer_dmem_resp   ),
+
+    // Timer interface
+    .timer_val      (timer_val         ),
+    .timer_irq      (timer_irq         )
+);
+
+
+`ifdef SCR1_IMEM_ROUTER_EN
+//-------------------------------------------------------------------------------
+// Instruction memory router
+//-------------------------------------------------------------------------------
+scr1_imem_router #(
+    .SCR1_ADDR_MASK     (SCR1_TCM_ADDR_MASK),
+    .SCR1_ADDR_PATTERN  (SCR1_TCM_ADDR_PATTERN)
+) i_imem_router (
+    .rst_n          (core_rst_n_local ),
+    .clk            (clk              ),
+
+    // Interface to core
+    .imem_req_ack   (core_imem_req_ack),
+    .imem_req       (core_imem_req    ),
+    .imem_cmd       (core_imem_cmd    ),
+    .imem_addr      (core_imem_addr   ),
+    .imem_rdata     (core_imem_rdata  ),
+    .imem_resp      (core_imem_resp   ),
+
+    // Interface to AXI bridge
+    .port0_req_ack  (axi_imem_req_ack ),
+    .port0_req      (axi_imem_req     ),
+    .port0_cmd      (axi_imem_cmd     ),
+    .port0_addr     (axi_imem_addr    ),
+    .port0_rdata    (axi_imem_rdata   ),
+    .port0_resp     (axi_imem_resp    ),
+
+    // Interface to TCM
+    .port1_req_ack  (tcm_imem_req_ack ),
+    .port1_req      (tcm_imem_req     ),
+    .port1_cmd      (tcm_imem_cmd     ),
+    .port1_addr     (tcm_imem_addr    ),
+    .port1_rdata    (tcm_imem_rdata   ),
+    .port1_resp     (tcm_imem_resp    )
+);
+
+`else // SCR1_IMEM_ROUTER_EN
+
+assign axi_imem_req         = core_imem_req;
+assign axi_imem_cmd         = core_imem_cmd;
+assign axi_imem_addr        = core_imem_addr;
+assign core_imem_req_ack    = axi_imem_req_ack;
+assign core_imem_resp       = axi_imem_resp;
+assign core_imem_rdata      = axi_imem_rdata;
+
+`endif // SCR1_IMEM_ROUTER_EN
+
+
+//-------------------------------------------------------------------------------
+// Data memory router
+//-------------------------------------------------------------------------------
+scr1_dmem_router #(
+
+`ifdef SCR1_TCM_EN
+    .SCR1_PORT1_ADDR_MASK       (SCR1_TCM_ADDR_MASK),
+    .SCR1_PORT1_ADDR_PATTERN    (SCR1_TCM_ADDR_PATTERN),
+`else // SCR1_TCM_EN
+    .SCR1_PORT1_ADDR_MASK       (32'h00000000),
+    .SCR1_PORT1_ADDR_PATTERN    (32'hFFFFFFFF),
+`endif // SCR1_TCM_EN
+
+    .SCR1_PORT2_ADDR_MASK       (SCR1_TIMER_ADDR_MASK),
+    .SCR1_PORT2_ADDR_PATTERN    (SCR1_TIMER_ADDR_PATTERN)
+
+) i_dmem_router (
+    .rst_n          (core_rst_n_local    ),
+    .clk            (clk                 ),
+
+    // Interface to core
+    .dmem_req_ack   (core_dmem_req_ack   ),
+    .dmem_req       (core_dmem_req       ),
+    .dmem_cmd       (core_dmem_cmd       ),
+    .dmem_width     (core_dmem_width     ),
+    .dmem_addr      (core_dmem_addr      ),
+    .dmem_wdata     (core_dmem_wdata     ),
+    .dmem_rdata     (core_dmem_rdata     ),
+    .dmem_resp      (core_dmem_resp      ),
+
+`ifdef SCR1_TCM_EN
+    // Interface to TCM
+    .port1_req_ack  (tcm_dmem_req_ack    ),
+    .port1_req      (tcm_dmem_req        ),
+    .port1_cmd      (tcm_dmem_cmd        ),
+    .port1_width    (tcm_dmem_width      ),
+    .port1_addr     (tcm_dmem_addr       ),
+    .port1_wdata    (tcm_dmem_wdata      ),
+    .port1_rdata    (tcm_dmem_rdata      ),
+    .port1_resp     (tcm_dmem_resp       ),
+`else // SCR1_TCM_EN
+    .port1_req_ack  (1'b0                ),
+    .port1_req      (                    ),
+    .port1_cmd      (                    ),
+    .port1_width    (                    ),
+    .port1_addr     (                    ),
+    .port1_wdata    (                    ),
+    .port1_rdata    ('0                  ),
+    .port1_resp     (SCR1_MEM_RESP_RDY_ER),
+`endif // SCR1_TCM_EN
+
+    // Interface to memory-mapped timer
+    .port2_req_ack  (timer_dmem_req_ack  ),
+    .port2_req      (timer_dmem_req      ),
+    .port2_cmd      (timer_dmem_cmd      ),
+    .port2_width    (timer_dmem_width    ),
+    .port2_addr     (timer_dmem_addr     ),
+    .port2_wdata    (timer_dmem_wdata    ),
+    .port2_rdata    (timer_dmem_rdata    ),
+    .port2_resp     (timer_dmem_resp     ),
+
+    // Interface to AXI bridge
+    .port0_req_ack  (axi_dmem_req_ack    ),
+    .port0_req      (axi_dmem_req        ),
+    .port0_cmd      (axi_dmem_cmd        ),
+    .port0_width    (axi_dmem_width      ),
+    .port0_addr     (axi_dmem_addr       ),
+    .port0_wdata    (axi_dmem_wdata      ),
+    .port0_rdata    (axi_dmem_rdata      ),
+    .port0_resp     (axi_dmem_resp       )
+);
+
+
+//-------------------------------------------------------------------------------
+// Instruction memory AXI bridge
+//-------------------------------------------------------------------------------
+scr1_mem_axi #(
+`ifdef SCR1_IMEM_AXI_REQ_BP
+    .SCR1_AXI_REQ_BP    (1),
+`else // SCR1_IMEM_AXI_REQ_BP
+    .SCR1_AXI_REQ_BP    (0),
+`endif // SCR1_IMEM_AXI_REQ_BP
+`ifdef SCR1_IMEM_AXI_RESP_BP
+    .SCR1_AXI_RESP_BP   (1)
+`else // SCR1_IMEM_AXI_RESP_BP
+    .SCR1_AXI_RESP_BP   (0)
+`endif // SCR1_IMEM_AXI_RESP_BP
+) i_imem_axi (
+    .clk            (clk                    ),
+    .rst_n          (axi_rst_n              ),
+    .axi_reinit     (axi_reinit             ),
+
+    // Interface to core
+    .core_idle      (axi_imem_idle          ),
+    .core_req_ack   (axi_imem_req_ack       ),
+    .core_req       (axi_imem_req           ),
+    .core_cmd       (axi_imem_cmd           ),
+    .core_width     (SCR1_MEM_WIDTH_WORD    ),
+    .core_addr      (axi_imem_addr          ),
+    .core_wdata     ('0                     ),
+    .core_rdata     (axi_imem_rdata         ),
+    .core_resp      (axi_imem_resp          ),
+
+    // AXI I/O
+    .awid           (io_axi_imem_awid       ),
+    .awaddr         (io_axi_imem_awaddr     ),
+    .awlen          (io_axi_imem_awlen      ),
+    .awsize         (io_axi_imem_awsize     ),
+    .awburst        (io_axi_imem_awburst    ),
+    .awlock         (io_axi_imem_awlock     ),
+    .awcache        (io_axi_imem_awcache    ),
+    .awprot         (io_axi_imem_awprot     ),
+    .awregion       (io_axi_imem_awregion   ),
+    .awuser         (io_axi_imem_awuser     ),
+    .awqos          (io_axi_imem_awqos      ),
+    .awvalid        (io_axi_imem_awvalid    ),
+    .awready        (io_axi_imem_awready    ),
+    .wdata          (io_axi_imem_wdata      ),
+    .wstrb          (io_axi_imem_wstrb      ),
+    .wlast          (io_axi_imem_wlast      ),
+    .wuser          (io_axi_imem_wuser      ),
+    .wvalid         (io_axi_imem_wvalid     ),
+    .wready         (io_axi_imem_wready     ),
+    .bid            (io_axi_imem_bid        ),
+    .bresp          (io_axi_imem_bresp      ),
+    .bvalid         (io_axi_imem_bvalid     ),
+    .buser          (io_axi_imem_buser      ),
+    .bready         (io_axi_imem_bready     ),
+    .arid           (io_axi_imem_arid       ),
+    .araddr         (io_axi_imem_araddr     ),
+    .arlen          (io_axi_imem_arlen      ),
+    .arsize         (io_axi_imem_arsize     ),
+    .arburst        (io_axi_imem_arburst    ),
+    .arlock         (io_axi_imem_arlock     ),
+    .arcache        (io_axi_imem_arcache    ),
+    .arprot         (io_axi_imem_arprot     ),
+    .arregion       (io_axi_imem_arregion   ),
+    .aruser         (io_axi_imem_aruser     ),
+    .arqos          (io_axi_imem_arqos      ),
+    .arvalid        (io_axi_imem_arvalid    ),
+    .arready        (io_axi_imem_arready    ),
+    .rid            (io_axi_imem_rid        ),
+    .rdata          (io_axi_imem_rdata      ),
+    .rresp          (io_axi_imem_rresp      ),
+    .rlast          (io_axi_imem_rlast      ),
+    .ruser          (io_axi_imem_ruser      ),
+    .rvalid         (io_axi_imem_rvalid     ),
+    .rready         (io_axi_imem_rready     )
+);
+
+
+//-------------------------------------------------------------------------------
+// Data memory AXI bridge
+//-------------------------------------------------------------------------------
+scr1_mem_axi #(
+`ifdef SCR1_DMEM_AXI_REQ_BP
+    .SCR1_AXI_REQ_BP    (1),
+`else // SCR1_DMEM_AXI_REQ_BP
+    .SCR1_AXI_REQ_BP    (0),
+`endif // SCR1_DMEM_AXI_REQ_BP
+`ifdef SCR1_DMEM_AXI_RESP_BP
+    .SCR1_AXI_RESP_BP   (1)
+`else // SCR1_DMEM_AXI_RESP_BP
+    .SCR1_AXI_RESP_BP   (0)
+`endif // SCR1_DMEM_AXI_RESP_BP
+) i_dmem_axi (
+    .clk            (clk                    ),
+    .rst_n          (axi_rst_n              ),
+    .axi_reinit     (axi_reinit             ),
+
+    // Interface to core
+    .core_idle      (axi_dmem_idle          ),
+    .core_req_ack   (axi_dmem_req_ack       ),
+    .core_req       (axi_dmem_req           ),
+    .core_cmd       (axi_dmem_cmd           ),
+    .core_width     (axi_dmem_width         ),
+    .core_addr      (axi_dmem_addr          ),
+    .core_wdata     (axi_dmem_wdata         ),
+    .core_rdata     (axi_dmem_rdata         ),
+    .core_resp      (axi_dmem_resp          ),
+
+    // AXI I/O
+    .awid           (io_axi_dmem_awid       ),
+    .awaddr         (io_axi_dmem_awaddr     ),
+    .awlen          (io_axi_dmem_awlen      ),
+    .awsize         (io_axi_dmem_awsize     ),
+    .awburst        (io_axi_dmem_awburst    ),
+    .awlock         (io_axi_dmem_awlock     ),
+    .awcache        (io_axi_dmem_awcache    ),
+    .awprot         (io_axi_dmem_awprot     ),
+    .awregion       (io_axi_dmem_awregion   ),
+    .awuser         (io_axi_dmem_awuser     ),
+    .awqos          (io_axi_dmem_awqos      ),
+    .awvalid        (io_axi_dmem_awvalid    ),
+    .awready        (io_axi_dmem_awready    ),
+    .wdata          (io_axi_dmem_wdata      ),
+    .wstrb          (io_axi_dmem_wstrb      ),
+    .wlast          (io_axi_dmem_wlast      ),
+    .wuser          (io_axi_dmem_wuser      ),
+    .wvalid         (io_axi_dmem_wvalid     ),
+    .wready         (io_axi_dmem_wready     ),
+    .bid            (io_axi_dmem_bid        ),
+    .bresp          (io_axi_dmem_bresp      ),
+    .bvalid         (io_axi_dmem_bvalid     ),
+    .buser          (io_axi_dmem_buser      ),
+    .bready         (io_axi_dmem_bready     ),
+    .arid           (io_axi_dmem_arid       ),
+    .araddr         (io_axi_dmem_araddr     ),
+    .arlen          (io_axi_dmem_arlen      ),
+    .arsize         (io_axi_dmem_arsize     ),
+    .arburst        (io_axi_dmem_arburst    ),
+    .arlock         (io_axi_dmem_arlock     ),
+    .arcache        (io_axi_dmem_arcache    ),
+    .arprot         (io_axi_dmem_arprot     ),
+    .arregion       (io_axi_dmem_arregion   ),
+    .aruser         (io_axi_dmem_aruser     ),
+    .arqos          (io_axi_dmem_arqos      ),
+    .arvalid        (io_axi_dmem_arvalid    ),
+    .arready        (io_axi_dmem_arready    ),
+    .rid            (io_axi_dmem_rid        ),
+    .rdata          (io_axi_dmem_rdata      ),
+    .rresp          (io_axi_dmem_rresp      ),
+    .rlast          (io_axi_dmem_rlast      ),
+    .ruser          (io_axi_dmem_ruser      ),
+    .rvalid         (io_axi_dmem_rvalid     ),
+    .rready         (io_axi_dmem_rready     )
+);
+
+//-------------------------------------------------------------------------------
+// AXI reinit logic
+//-------------------------------------------------------------------------------
+always_ff @(negedge core_rst_n_local, posedge clk) begin
+    if (~core_rst_n_local)                      axi_reinit <= 1'b1;
+    else if (axi_imem_idle & axi_dmem_idle)     axi_reinit <= 1'b0;
+end
+
+endmodule : scr1_top_axi