📄 serirq_fsm.v
字号:
// -*- Mode: Verilog -*-
// Filename : serirq_fsm.v
// Description : Serialized IRQ Control FSM
// Author : James Rao
// Created On : Thu Dec 18 10:20:53 2008
// Last Modified By: .
// Last Modified On: .
//--------------------------------------------------------------------------------
// Copyright (c) by Kontron (China) Ltd. This model is the confidential and
// proprietary property of Kontron Ltd. And the possession or use of this
// file requires a written license from Kontron (China) Ltd.
//--------------------------------------------------------------------------------
// Update Count : 0
// Status : Unknown, Use with caution!
//
// Updata History :
// Version Date Author Description
// 0.1 2008-12-18 James Rao Initial design
module serirq_fsm (/*AUTOARG*/
// Outputs
serirq_en, serirq_out,
// Inputs
reset_n, clk, serirq_in, csr_irq_num, irq
) ;
//Global I/F
input reset_n;
input clk;
//LPC I/F
input serirq_in;
output serirq_en;
output serirq_out;
//Other I/F
input [4:0] csr_irq_num;//IRQ line assigned.
input irq;//Interrupt from UARTs.
parameter IDLE = 2'h0,
START_FRAM = 2'h1,
IRQ_FRAM = 2'h2,
WAIT_STOP = 2'h3;
reg [1:0] ns;
reg [1:0] cs;
reg serirq_en;
reg serirq_out;
reg quiet_mode;
reg eof_start_frame;
reg illegal_start;
reg eof_irq_frame;
reg [6:0] frame_cyc_cntr;
reg illegal_irq_num;
reg [6:0] irq_cyc;
reg irq_recov_cyc;
wire irq_cyc_rdy;
wire start_1stcyc_quiet;
/***************************************************************************
1. Control FSM for Serialized IRQ
***************************************************************************/
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
cs <= #1 IDLE;
else
cs <= #1 ns;
end
always @(/*AUTOSENSE*/cs or eof_irq_frame or eof_start_frame
or frame_cyc_cntr or illegal_irq_num or illegal_start
or irq or quiet_mode or serirq_in) begin
case (cs)
IDLE: begin
if (((irq && serirq_in && quiet_mode) || !serirq_in) && !illegal_irq_num)
ns = START_FRAM;
else
ns = IDLE;
end//IRQ
START_FRAM: begin
if (illegal_start)
ns = IDLE;
else if (eof_start_frame)
ns = IRQ_FRAM;
else
ns = START_FRAM;
end
IRQ_FRAM: begin
if (eof_irq_frame)
ns = WAIT_STOP;
else
ns = IRQ_FRAM;
end
WAIT_STOP: begin
if (frame_cyc_cntr == 7'h2)
ns = IDLE;
else
ns = WAIT_STOP;
end
default: begin
ns = IDLE;
end
endcase // case(cs)
end // always @ (...
/***************************************************************************
2. FSM Control & Output Signals
***************************************************************************/
//1) irq_cyc -- decided by the IRQ register.
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
irq_cyc <= #1 7'h0;
else begin
case (csr_irq_num)
5'h0: irq_cyc <= #1 7'h0;//IRQ0
5'h1: irq_cyc <= #1 7'h3;//IRQ1
5'h2: irq_cyc <= #1 7'h6;//SMI#
5'h3: irq_cyc <= #1 7'h9;//IRQ3
5'h4: irq_cyc <= #1 7'hC;//IRQ4
5'h5: irq_cyc <= #1 7'hF;//IRQ5
5'h6: irq_cyc <= #1 7'h12;//IRQ6
5'h7: irq_cyc <= #1 7'h15;//IRQ7
5'h8: irq_cyc <= #1 7'h18;//IRQ8
5'h9: irq_cyc <= #1 7'h1B;//IRQ9
5'hA: irq_cyc <= #1 7'h1E;//IRQ10
5'hB: irq_cyc <= #1 7'h21;//IRQ11
5'hC: irq_cyc <= #1 7'h24;//IRQ12
5'hD: irq_cyc <= #1 7'h27;//IRQ13
5'hE: irq_cyc <= #1 7'h2A;//IRQ14
5'hF: irq_cyc <= #1 7'h2D;//IRQ15
5'h10: irq_cyc <= #1 7'h30;//IOCHK#
5'h11: irq_cyc <= #1 7'h33;//INTA#
5'h12: irq_cyc <= #1 7'h36;//INTB#
5'h13: irq_cyc <= #1 7'h39;//INTC#
5'h14: irq_cyc <= #1 7'h3C;//INTD#
default: irq_cyc <= #1 7'h5D;//Unassigned
endcase // case(csr_irq_num)
end // else: !if(!reset_n)
end // always @ (posedge clk or negedge reset_n)
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
illegal_irq_num <= #1 1'b0;
else if (csr_irq_num > 5'h14)
illegal_irq_num <= #1 1'b1;
end
//2) Quiet mode -- when STOP is 2-cycle wide.
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
quiet_mode <= #1 1'b0;
else if (serirq_in && (cs == WAIT_STOP) && (frame_cyc_cntr == 7'h2))
quiet_mode <= #1 1'b1;
else if (cs == WAIT_STOP)
quiet_mode <= #1 1'b0;
end
always @(/*AUTOSENSE*/cs or frame_cyc_cntr or serirq_in) begin
if (serirq_in && (cs == START_FRAM)) begin
case (frame_cyc_cntr)
7'h4, 7'h6, 7'h8: eof_start_frame <= #1 1'b1;
default: eof_start_frame <= #1 1'b0;
endcase // case(frame_cyc_cntr)
end
else
eof_start_frame <= #1 1'b0;
end // always @ (...
always @(/*AUTOSENSE*/cs or frame_cyc_cntr or quiet_mode
or serirq_in) begin
if (serirq_in && (cs == START_FRAM)) begin
if (quiet_mode)
case (frame_cyc_cntr)
7'h4 ,7'h6, 7'h8: illegal_start <= #1 1'b0;
default: illegal_start <= #1 1'b1;
endcase // case(frame_cyc_cntr)
end
else
illegal_start <= #1 1'b0;
end // always @ (...
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
eof_irq_frame <= #1 1'b0;
else
eof_irq_frame <= #1 (cs == IRQ_FRAM) & (frame_cyc_cntr == irq_cyc);
end
//7-bit frame cycle counter for state transfer.
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
frame_cyc_cntr <= #1 7'h0;
else begin
case (cs)
START_FRAM: begin
if (!serirq_in)
frame_cyc_cntr <= #1 frame_cyc_cntr + 1;
else if (eof_start_frame)
frame_cyc_cntr <= #1 7'h0;
end
IRQ_FRAM: begin
if (eof_irq_frame)
frame_cyc_cntr <= #1 7'h0;
else
frame_cyc_cntr <= #1 frame_cyc_cntr + 1;
end
WAIT_STOP: begin
if (!serirq_in)
frame_cyc_cntr <= #1 frame_cyc_cntr + 1;
end
default: frame_cyc_cntr <= #1 7'h0;
endcase // case(cs)
end // else: !if(!reset_n)
end // always @ (posedge clk or negedge reset_n)
assign start_1stcyc_quiet = (irq & serirq_in & quiet_mode) & (cs == IDLE);
assign irq_cyc_rdy = irq & (cs == IRQ_FRAM) & (frame_cyc_cntr == irq_cyc);
always @(posedge clk or negedge reset_n) begin
if (!reset_n)
irq_recov_cyc <= #1 1'b0;
else
irq_recov_cyc <= #1 irq_cyc_rdy;
end
//serirq output and enable.
always @(posedge clk or negedge reset_n) begin
if (!reset_n) begin
serirq_en <= #1 1'b0;
serirq_out <= #1 1'b1;
end
else begin
serirq_en <= #1 start_1stcyc_quiet | irq_cyc_rdy | irq_recov_cyc;
serirq_out <= #1 ~(start_1stcyc_quiet | irq_cyc_rdy);
end
end
endmodule // serirq_fsm
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -