📄 bmd_intr_ctrl.v
字号:
//--------------------------------------------------------------------------------//--//-- This file is owned and controlled by Xilinx and must be used solely//-- for design, simulation, implementation and creation of design files//-- limited to Xilinx devices or technologies. Use with non-Xilinx//-- devices or technologies is expressly prohibited and immediately//-- terminates your license.//--//-- Xilinx products are not intended for use in life support//-- appliances, devices, or systems. Use in such applications is//-- expressly prohibited.//--//-- **************************************//-- ** Copyright (C) 2005, Xilinx, Inc. **//-- ** All Rights Reserved. **//-- **************************************//--//--------------------------------------------------------------------------------//-- Filename: BMD_INTR_CTRL.v//--//-- Description: Endpoint Intrrupt Controller//--//--------------------------------------------------------------------------------`timescale 1ns/1ns`define BMD_INTR_RST 3'b001`define BMD_INTR_RD 3'b010`define BMD_INTR_WR 3'b100`define BMD_INTR_RD_RST 6'b000001`define BMD_INTR_RD_ACT 6'b000010`define BMD_INTR_RD_ACK 6'b000100`define BMD_INTR_RD_DUN 6'b001000`define BMD_INTR_RD_Legacy_ACT 6'b010000`define BMD_INTR_RD_Legacy_DUN 6'b100000`define BMD_INTR_WR_RST 6'b000001`define BMD_INTR_WR_ACT 6'b000010`define BMD_INTR_WR_ACK 6'b000100`define BMD_INTR_WR_DUN 6'b001000`define BMD_INTR_WR_Legacy_ACT 6'b010000`define BMD_INTR_WR_Legacy_DUN 6'b100000module BMD_INTR_CTRL ( clk, // I rst_n, // I init_rst_i, // I mrd_done_i, // I mwr_done_i, // I cfg_interrupt_rdy_n_i, // I cfg_interrupt_n_o, // O cfg_interrupt_assert_n_o, // O cfg_interrupt_di_o, // O cfg_interrupt_do_i, // I cfg_interrupt_mmenable_i, // I cfg_interrupt_msienable_i, // I int_src_rd_o, // O int_src_wr_o, // O int_clear_i // I ); input clk; input rst_n; input init_rst_i; input mrd_done_i; input mwr_done_i; input cfg_interrupt_rdy_n_i; output cfg_interrupt_n_o; output cfg_interrupt_assert_n_o; output [7:0] cfg_interrupt_di_o; input [7:0] cfg_interrupt_do_i; input [2:0] cfg_interrupt_mmenable_i; input cfg_interrupt_msienable_i; output int_src_rd_o; output int_src_wr_o; input int_clear_i; // Local Registers reg [2:0] intr_state; reg [2:0] next_intr_state; reg [5:0] rd_intr_state; reg [5:0] next_rd_intr_state; reg [5:0] wr_intr_state; reg [5:0] next_wr_intr_state; wire rd_intr_n; wire wr_intr_n; reg mrd_done; reg mwr_done; wire cfg_interrupt_assert_n_rd; wire cfg_interrupt_assert_n_wr; assign cfg_interrupt_n_o = rd_intr_n & wr_intr_n; assign wr_intr_n = ((wr_intr_state == `BMD_INTR_WR_ACT) || (wr_intr_state == `BMD_INTR_WR_Legacy_ACT)) ? 1'b0:1'b1; assign rd_intr_n = ((rd_intr_state == `BMD_INTR_RD_ACT) || (rd_intr_state == `BMD_INTR_RD_Legacy_ACT)) ? 1'b0:1'b1; assign cfg_interrupt_di_o = cfg_interrupt_msienable_i?cfg_interrupt_do_i:8'b0; assign cfg_interrupt_assert_n_o = ((wr_intr_state == `BMD_INTR_WR_ACT) ||( rd_intr_state== `BMD_INTR_RD_ACT) )?1'b0:1'b1; assign int_src_wr_o = ((wr_intr_state == `BMD_INTR_WR_ACK)) ? 1'b1:1'b0; assign int_src_rd_o = ((rd_intr_state == `BMD_INTR_RD_ACK)) ? 1'b1:1'b0; // // Resolve mrd_done_i and mwr_done_i // always @(mrd_done_i or mwr_done_i or rd_intr_state or intr_state or rd_intr_state or wr_intr_state) begin case (intr_state) /* synthesis full_case */ /* synthesis parallel_case */ `BMD_INTR_RST : begin if (mrd_done_i) begin mrd_done = 1'b1; mwr_done = 1'b0; next_intr_state = `BMD_INTR_RD; end else if (mwr_done_i) begin mrd_done = 1'b0; mwr_done = 1'b1; next_intr_state = `BMD_INTR_WR; end else begin mrd_done = 1'b0; mwr_done = 1'b0; next_intr_state = `BMD_INTR_RST; end end `BMD_INTR_RD : begin if (mwr_done_i && (rd_intr_state == `BMD_INTR_RD_Legacy_DUN)) begin mwr_done = 1'b1; mrd_done = 1'b1; end else begin mwr_done = 1'b0; mrd_done = 1'b1; end next_intr_state = `BMD_INTR_RD; end `BMD_INTR_WR : begin if (mrd_done_i && (wr_intr_state == `BMD_INTR_WR_Legacy_DUN)) begin mrd_done = 1'b1; mwr_done = 1'b1; end else begin mrd_done = 1'b0; mwr_done = 1'b1; end next_intr_state = `BMD_INTR_WR; end endcase end // // Read Interrupt Control // always @(rd_intr_state or mrd_done or cfg_interrupt_rdy_n_i or cfg_interrupt_msienable_i or int_clear_i) begin case (rd_intr_state) /* synthesis full_case */ /* synthesis parallel_case */ `BMD_INTR_RD_RST : begin if (mrd_done)begin next_rd_intr_state = `BMD_INTR_RD_ACT; end else begin next_rd_intr_state = `BMD_INTR_RD_RST; end end `BMD_INTR_RD_ACT : begin if (!cfg_interrupt_rdy_n_i) begin next_rd_intr_state = `BMD_INTR_RD_ACK; end else begin next_rd_intr_state = `BMD_INTR_RD_ACT; end end `BMD_INTR_RD_ACK : begin if (int_clear_i) begin next_rd_intr_state = `BMD_INTR_RD_DUN; end else begin next_rd_intr_state = `BMD_INTR_RD_ACK; end end `BMD_INTR_RD_DUN : begin if (cfg_interrupt_msienable_i) // Legacy Interrupt need more states next_rd_intr_state = `BMD_INTR_RD_Legacy_DUN; else next_rd_intr_state = `BMD_INTR_RD_Legacy_ACT; end `BMD_INTR_RD_Legacy_ACT : begin if (!cfg_interrupt_rdy_n_i) begin next_rd_intr_state = `BMD_INTR_RD_Legacy_DUN; end else begin next_rd_intr_state = `BMD_INTR_RD_Legacy_ACT; end end `BMD_INTR_RD_Legacy_DUN : begin next_rd_intr_state = `BMD_INTR_RD_Legacy_DUN; end endcase end // // Write Interrupt Control // always @(wr_intr_state or mwr_done or cfg_interrupt_rdy_n_i or cfg_interrupt_msienable_i or int_clear_i) begin case (wr_intr_state) /* synthesis full_case */ /* synthesis parallel_case */ `BMD_INTR_WR_RST : begin if (mwr_done)begin next_wr_intr_state = `BMD_INTR_WR_ACT; end else begin next_wr_intr_state = `BMD_INTR_WR_RST; end end `BMD_INTR_WR_ACT : begin if (!cfg_interrupt_rdy_n_i) begin next_wr_intr_state = `BMD_INTR_WR_ACK; end else begin next_wr_intr_state = `BMD_INTR_WR_ACT; end end `BMD_INTR_WR_ACK : begin if (int_clear_i) begin next_wr_intr_state = `BMD_INTR_WR_DUN; end else begin next_wr_intr_state = `BMD_INTR_WR_ACK; end end `BMD_INTR_WR_DUN : begin if (cfg_interrupt_msienable_i) // Legacy Interrupt need more states next_wr_intr_state = `BMD_INTR_WR_Legacy_DUN; else next_wr_intr_state = `BMD_INTR_WR_Legacy_ACT; end `BMD_INTR_WR_Legacy_ACT : begin if (!cfg_interrupt_rdy_n_i) begin next_wr_intr_state = `BMD_INTR_WR_Legacy_DUN; end else begin next_wr_intr_state = `BMD_INTR_WR_Legacy_ACT; end end `BMD_INTR_WR_Legacy_DUN : begin next_wr_intr_state = `BMD_INTR_WR_Legacy_DUN; end endcase end always @(posedge clk or negedge rst_n) begin if ( !rst_n ) begin rd_intr_state <= `BMD_INTR_RD_RST; wr_intr_state <= `BMD_INTR_WR_RST; intr_state <= `BMD_INTR_RST; end else begin if (init_rst_i) begin rd_intr_state <= `BMD_INTR_RD_RST; wr_intr_state <= `BMD_INTR_WR_RST; intr_state <= `BMD_INTR_RST; end else begin rd_intr_state <= next_rd_intr_state; wr_intr_state <= next_wr_intr_state; intr_state <= next_intr_state; end end end// always @( wr_intr_state or rd_intr_state ) begin//// if ((wr_intr_state == `BMD_INTR_WR_ACT) ||( rd_intr_state== `BMD_INTR_RD_ACT) ) begin// cfg_interrupt_assert_n_o = 1'b0;// end else begin// cfg_interrupt_assert_n_o = 1'b1;// end// endendmodule//The following pseudo-code shows the processing required:// Value MSI_Vector_Num must be in range: 0 <= MSI_Vector_Num <= (2^cfg_interrupt_mmenable)-1//if (cfg_interrupt_msienable) { // MSI Enabled// if (cfg_interrupt_mmenable > 0) { // Multi-Vector MSI Enabled// cfg_interrupt_di[7:0] = {Padding_0s, MSI_Vector_Num};// } else { // Single-Vector MSI Enabled// cfg_interrupt_di[7:0] = Padding_0s;// }//} else {// Legacy Interrupts Enabled//}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -