diff --git a/modules/vme_interface/InterruptManagerWb.v b/modules/vme_interface/InterruptManagerWb.v index a6bf857d1dce6444b882b68b3efeda08f5262051..cebcd2a026ea0566f93ff0ad6c2e741fd4a01d02 100644 --- a/modules/vme_interface/InterruptManagerWb.v +++ b/modules/vme_interface/InterruptManagerWb.v @@ -1,20 +1,21 @@ //============================================================================================\\ //################################## Module Information ##################################\\ //============================================================================================\\ -// -// Company: CERN (BE-BI) -// -// File Name: InterruptManagerWb.v +// +// Company: CERN (BE-BI) +// +// File Name: InterruptManagerWb.v // // File versions history: // // DATE VERSION AUTHOR DESCRIPTION +// - 16/12/16 1.2 T. Levens - Split vector/level into separate regs // - 05/12/16 1.1 M. Barros Marin - Removed Revision ID registers -// - Cosmetic modifications +// - Cosmetic modifications // - 05/11/14 1.0 A. Boccardi First module definition // -// Language: Verilog 2005 -// +// Language: Verilog 2005 +// // Targeted device: // // - Vendor: Agnostic @@ -23,7 +24,7 @@ // Description: // // The module support 32 interrupt sources. Each source can be masked individually. -// The Interrupt requests are assumed synchronous to the clock. A new request is registered +// The Interrupt requests are assumed synchronous to the clock. A new request is registered // each time there is a change of state on its line from 0 to 1. // The interrupt release mechanism can be set dynamically to ROACK or RORA. In this last case // the register to read to complete the release mechanism is the fpga_status_reg. @@ -31,47 +32,52 @@ // If 2 or more interrupt requests are asserted at the same time they are store all asserted in // the FIFO at the same location and will appear as multiple bit set in the status register, // that is actually a copy of the FIFO output and is cleared at each readout as at the same time -// a read request is sent to the FIFO itself. +// a read request is sent to the FIFO itself. // The module has a configuration register, a status register where the source of the current -// interrupt can be read, a mask register (a 1 in bin n mask the interrupt source n) and a -// release ID register: -// -// Status register (Addr:0x0) : -// bits[31:0] = interrupt source => reading this register also advances the pointer of the +// interrupt can be read, a mask register (a 1 in bin n mask the interrupt source n) and +// vector and level registers. +// +// Addr=0x0 : Status register +// bits[31:0] = interrupt source => reading this register also advances the pointer of the // interrupt FIFO and therefore it should be read only once // per interrupt -// Configuration Register (Addr:0x1) -// bits[31:24] = 0 -// bits[23] = 0 -// bits[22:20] = Interrupt Level -// bits[19:12] = Interrupt Vector -// bit[11] = IntEnabele => Enables the interrupt handling -// bit[10:9] = 0 -// bit[8] = RoraMode => a 1 set the module into RORA mode (int line released on the readout -// of the Status register), a 0 in ROAK -// bits[7:0] = 0 -// +// Addr=0x1 : Configuration Register +// bits[31:2] = 0 +// bits[1] = 1=RORA mode, 0=ROAK mode +// bits[0] = interrupt Enable +// +// Addr=0x2 : Mask Register +// bits[31:0] = interrupt mask +// +// Addr=0x3 : Vector Register +// bits[31:8] = 0 +// bits[7:0] = interrupt vector +// +// Addr=0x4 : Level Register +// bits[31:3] = 0 +// bits[2:0] = interrupt level +// //============================================================================================\\ //############################################################################################\\ //============================================================================================\\ -`timescale 1ns/100ps +`timescale 1ns/100ps -module InterruptManagerWb -//==================================== Global Parameters ===================================\\ -#(parameter g_FifoAddressWidth = 3) -//======================================== I/O ports =======================================\\ -( +module InterruptManagerWb +//==================================== Global Parameters ===================================\\ +#(parameter g_FifoAddressWidth = 3) +//======================================== I/O ports =======================================\\ +( input Rst_irq, input Clk_ik, input Cyc_i, input Stb_i, input We_i, - input [ 1:0] Adr_ib2, + input [ 2:0] Adr_ib3, input [31:0] Dat_ib32, output reg [31:0] Dat_oab32, - output reg Ack_oa, - input [31:0] IntRequestLines_ib32, + output reg Ack_oa, + input [31:0] IntRequestLines_ib32, output IntEnable_o, output IntModeRora_o, output [ 2:0] IntLevel_ob3, @@ -80,74 +86,91 @@ module InterruptManagerWb output reg NewIntRequest_oq // Comment: Used for ROAK ); -//======================================= Declarations =====================================\\ +//======================================= Declarations =====================================\\ -localparam c_StatusRegAddr_b2 = 2'b00; -localparam c_ConfigRegAddr_b2 = 2'b01; -localparam c_MaskRegAddr_b2 = 2'b10; +localparam c_StatusRegAddr_b2 = 3'b000; +localparam c_ConfigRegAddr_b2 = 3'b001; +localparam c_MaskRegAddr_b2 = 3'b010; +localparam c_VectorRegAddr_b2 = 3'b011; +localparam c_LevelRegAddr_b2 = 3'b100; -reg Ack_d = 0; -wire [31:0] IntSourceFifoOut_b32; -wire IntSourceFifoFull, IntSourceFifoEmpty; -reg IntSourceFifoRead; -reg [31:0] ConfigReg_bq32 = 32'hFF; -reg [31:0] MaskReg_bq32 = 32'hFFFFFFFF; +reg Ack_d = 0; +wire [31:0] IntSourceFifoOut_b32; +wire IntSourceFifoFull, IntSourceFifoEmpty; +reg IntSourceFifoRead; +reg [31:0] ConfigReg_bq32 = 32'h0000_0000; +reg [31:0] MaskReg_bq32 = 32'hFFFF_FFFF; +reg [31:0] VectorReg_bq32 = 32'h0000_0000; +reg [31:0] LevelReg_bq32 = 32'h0000_0000; wire [31:0] IntRequestMasked_b32; -reg [31:0] IntRequestMasked_db32 = 32'hFFFFFFFF; +reg [31:0] IntRequestMasked_db32 = 32'hFFFF_FFFF; reg [31:0] IntRequestSource_qb32 = 32'h0; wire IntSourceFifoReset; -//======================================= User Logic =======================================\\ - -assign IntLevel_ob3 = ConfigReg_bq32[22:20]; -assign IntVector_ob8 = ConfigReg_bq32[19:12]; -assign IntEnable_o = ConfigReg_bq32[11]; -assign IntModeRora_o = ConfigReg_bq32[8]; - +//======================================= User Logic =======================================\\ + +assign IntLevel_ob3 = LevelReg_bq32[2:0]; +assign IntVector_ob8 = VectorReg_bq32[7:0]; +assign IntEnable_o = ConfigReg_bq32[0]; +assign IntModeRora_o = ConfigReg_bq32[1]; + assign IntRequestMasked_b32 = IntRequestLines_ib32 & ~MaskReg_bq32; always @(posedge Clk_ik) IntRequestMasked_db32 <= #1 IntRequestMasked_b32; always @(posedge Clk_ik) IntRequestSource_qb32 <= #1 IntRequestMasked_b32 & ~IntRequestMasked_db32; always @(posedge Clk_ik) NewIntRequest_oq <= #1 ~IntSourceFifoFull && IntEnable_o && |(IntRequestMasked_b32 & ~IntRequestMasked_db32); - -always @(posedge Clk_ik) - if (Rst_irq) ConfigReg_bq32 <= # 1 32'h0; - else if (Cyc_i && We_i && Stb_i && Adr_ib2==c_ConfigRegAddr_b2) ConfigReg_bq32 <= # 1 Dat_ib32; - -always @(posedge Clk_ik) - if (Rst_irq) MaskReg_bq32 <= # 1 32'hffffffff; - else if (Cyc_i && We_i && Stb_i && Adr_ib2==c_MaskRegAddr_b2) MaskReg_bq32 <= # 1 Dat_ib32; - + +always @(posedge Clk_ik) begin + if (Rst_irq) begin + ConfigReg_bq32 <= # 1 32'h0000_0000; + MaskReg_bq32 <= # 1 32'hFFFF_FFFF; + VectorReg_bq32 <= # 1 32'h0000_0000; + LevelReg_bq32 <= # 1 32'h0000_0000; + end + else begin + if (Cyc_i && We_i && Stb_i) begin + case (Adr_ib3) + c_ConfigRegAddr_b2 : ConfigReg_bq32 <= # 1 Dat_ib32; + c_MaskRegAddr_b2 : MaskReg_bq32 <= # 1 Dat_ib32; + c_VectorRegAddr_b2 : VectorReg_bq32 <= # 1 Dat_ib32; + c_LevelRegAddr_b2 : LevelReg_bq32 <= # 1 Dat_ib32; + endcase + end + end +end + assign IntSourceFifoReset = Rst_irq || ~IntEnable_o; - + generic_fifo_dc_gray_mod #( - .dw (32), - .aw (g_FifoAddressWidth)) -i_IntSourceFifo ( - .rd_clk (Clk_ik), - .wr_clk (Clk_ik), - .rst(1'b1), - .clr (IntSourceFifoReset), - .din (IntRequestSource_qb32), - .we (NewIntRequest_oq), - .dout (IntSourceFifoOut_b32), - .re (IntSourceFifoRead), - .full (IntSourceFifoFull), - .empty (IntSourceFifoEmpty)); - -assign IntSourceToRead_o = ~IntSourceFifoEmpty; - -always @(posedge Clk_ik) IntSourceFifoRead <= #1 ~IntSourceFifoEmpty && (Adr_ib2==c_StatusRegAddr_b2) && Ack_d && ~Ack_oa; + .dw (32), + .aw (g_FifoAddressWidth)) +i_IntSourceFifo ( + .rd_clk (Clk_ik), + .wr_clk (Clk_ik), + .rst (1'b1), + .clr (IntSourceFifoReset), + .din (IntRequestSource_qb32), + .we (NewIntRequest_oq), + .dout (IntSourceFifoOut_b32), + .re (IntSourceFifoRead), + .full (IntSourceFifoFull), + .empty (IntSourceFifoEmpty)); + +assign IntSourceToRead_o = ~IntSourceFifoEmpty; + +always @(posedge Clk_ik) IntSourceFifoRead <= #1 ~IntSourceFifoEmpty && (Adr_ib3 == c_StatusRegAddr_b2) && Ack_d && ~Ack_oa; always @(posedge Clk_ik) begin - Ack_oa <= #1 Stb_i&&Cyc_i; - Ack_d <= #1 Ack_oa; - case(Adr_ib2) - c_StatusRegAddr_b2 : Dat_oab32 <= #1 IntSourceFifoEmpty ? 32'h0000_0000 : IntSourceFifoOut_b32; - c_ConfigRegAddr_b2 : Dat_oab32 <= #1 ConfigReg_bq32; - c_MaskRegAddr_b2 : Dat_oab32 <= #1 MaskReg_bq32; - default: Dat_oab32 <= 32'hdead_beef; + Ack_oa <= #1 Stb_i&&Cyc_i; + Ack_d <= #1 Ack_oa; + case(Adr_ib3) + c_StatusRegAddr_b2 : Dat_oab32 <= #1 IntSourceFifoEmpty ? 32'h0000_0000 : IntSourceFifoOut_b32; + c_ConfigRegAddr_b2 : Dat_oab32 <= #1 ConfigReg_bq32; + c_MaskRegAddr_b2 : Dat_oab32 <= #1 MaskReg_bq32; + c_VectorRegAddr_b2 : Dat_oab32 <= #1 VectorReg_bq32; + c_LevelRegAddr_b2 : Dat_oab32 <= #1 LevelReg_bq32; + default : Dat_oab32 <= 32'hFFFF_FFFF; endcase end - -endmodule \ No newline at end of file + +endmodule