61 lines
2.0 KiB
Verilog
61 lines
2.0 KiB
Verilog
module int_ctrl (
|
|
input wire clk,
|
|
input wire resetn,
|
|
input wire [31:0] int_en,
|
|
input wire [31:0] int_edge,
|
|
input wire [31:0] int_pol,
|
|
input wire [31:0] int_in,
|
|
input wire [31:0] int_clr,
|
|
input wire [31:0] int_set,
|
|
output wire [31:0] int_out
|
|
);
|
|
|
|
// 同步异步输入信号,防止亚稳态
|
|
reg [31:0] int_in_sync_d1;
|
|
reg [31:0] int_in_sync_d2;
|
|
reg [31:0] int_in_sync_d3; // 用于边沿检测
|
|
|
|
always @(posedge clk or negedge resetn) begin
|
|
if (!resetn) begin
|
|
int_in_sync_d1 <= 32'b0;
|
|
int_in_sync_d2 <= 32'b0;
|
|
int_in_sync_d3 <= 32'b0;
|
|
end else begin
|
|
int_in_sync_d1 <= int_in;
|
|
int_in_sync_d2 <= int_in_sync_d1;
|
|
int_in_sync_d3 <= int_in_sync_d2;
|
|
end
|
|
end
|
|
|
|
// 生成同步后的边沿信号
|
|
wire [31:0] rising_edge = int_in_sync_d2 & ~int_in_sync_d3;
|
|
wire [31:0] falling_edge = ~int_in_sync_d2 & int_in_sync_d3;
|
|
|
|
// 边沿触发状态寄存器
|
|
reg [31:0] edge_int_state;
|
|
integer i;
|
|
always @(posedge clk or negedge resetn) begin
|
|
if (!resetn) begin
|
|
edge_int_state <= 32'b0;
|
|
end else begin
|
|
for (i = 0; i < 32; i = i + 1) begin
|
|
// 硬件检测优先级通常建议高于软件清除,防止丢失极窄脉冲
|
|
if (int_edge[i]) begin
|
|
if ((int_pol[i] && rising_edge[i]) || (!int_pol[i] && falling_edge[i]))
|
|
edge_int_state[i] <= 1'b1;
|
|
else if (int_set[i])
|
|
edge_int_state[i] <= 1'b1;
|
|
else if (int_clr[i])
|
|
edge_int_state[i] <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
// 电平触发逻辑
|
|
wire [31:0] level_int_state = int_in_sync_d2 ^ ~int_pol;
|
|
|
|
// 最终输出
|
|
assign int_out = int_en & ((int_edge & edge_int_state) | (~int_edge & level_int_state));
|
|
|
|
endmodule |