⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serirq_fsm.v

📁 LPC总线从设备的verilog设计,包含状态机和中断功能。
💻 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 + -