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

📄 state_machine.v

📁 ---简化版
💻 V
📖 第 1 页 / 共 2 页
字号:
//	Module  state_machine
//
/*   This module is called state_machine.  It's purpose is to control
  the bus cycle timing of the PCI and bkend Interface signals. 
  The outputs of this block also control output enables for 
  3 state buffers in the design.
 
  The PCI Target State Machine is at the heart of this Reference Design. 
  The State Machine goes from the idle state to one of three possible 
  paths during any given PCI operation.  While in the PCI address phase 
  of a transaction the values on  pci_cbe and pci_idsel determine 
  if the transaction is a: 
		Configuration Read or Write, 
		Memory-I/O Read, or a 
		Memory-I/O Write. 

  The designer can modify the state machine HDL code if the 
  functionality of the Back End Device has special system requirements. 
  It may be necessary to implement wait states, or new enable signals 
  for particular applications.  These would require modifications to 
  the HDL code, but embedded HDL comments will guide the designer 
  through the state machine implementation and signal descriptions.
*/

module state_machine 
(
    input pci_rst_l, pci_clk, pci_frame_l, pci_idsel, pci_irdy_l,
    input [3:0]  pci_cbe,   // The command or byte enables 
    input [31:0] pci_ad, 	// raw pci address data bus
    input hit_ba0_l, 		// The pci address is in base address 0
    input hit_ba1_l, 		// The pci address is in base address 1
    input [1:0] com,
    inout  reg devsel_l, 	// input to 3 state
    inout  reg trdy_l, 	    // input to 3 state
    inout  reg stop_l, 	    // input to 3 state
    output reg pci_ad_oe,   // OE for PCI address bus
    output reg par_oe,      // OE control for pci_par
    output reg bk_ba0_l,    // chip selects to the backend 
    output reg bk_ba1_l,    // chip selects to the backend
    output reg r_w_l, 		// read == 1 & write == 0
    output reg data_wr_l, 	// used as a clock enable for the pci_clk to the bkend device
    output reg data_rd_l, 	// the read strobe for the backend device
    output reg [3:0] tps,
    
    output reg [31:0] pci_addr_reg, // first clock's address
    output reg [3:0] pci_cbe_reg,   // first clock's command
    output reg pci_idsel_reg        // config cycle ID
);
 
/*********************************************/
/* begin statemachine declarations           */
/*********************************************/
    reg read_flag;      // data cycle:   read == 1; write == 0;
    reg con_read_flag;  // config cycle: read == 1; write == 0;
    reg [11:0] cstate;
    parameter   idle         = 12'b0000_0000_0001,
                con_wait_med = 12'b0000_0000_0010,
                con_wait_slw = 12'b0000_0000_0100,
                con          = 12'b0000_0000_1000,
                rw_wait_hit  = 12'b0000_0001_0000,
                rw_wait      = 12'b0000_0010_0000,
                read_wait    = 12'b0000_0100_0000,
                read_last    = 12'b0000_1000_0000,
                write_wait   = 12'b0001_0000_0000,
                backoff      = 12'b0010_0000_0000,
                retry        = 12'b0100_0000_0000,
                abort        = 12'b1000_0000_0000;

 /***********************************************/
 /* The following `defines are defined here to  */
 /* keep the state machine clean.               */
 /***********************************************/
    `define func_zero_type_zero ((pci_ad[10:8] == 3'b000) && (pci_ad[1:0] == 2'b00))
    `define no_config    (!pci_idsel && !pci_frame_l)
    `define config_read  (pci_cbe == 4'b1010)
    `define config_write (pci_cbe == 4'b1011)
    `define io_read      ((pci_cbe == 4'b0010) && com[0]) 
    `define io_write     ((pci_cbe == 4'b0011) && com[0])
    `define mem_read     ((pci_cbe == 4'b0110) && com[1])
    `define mem_write    ((pci_cbe == 4'b0111) && com[1])
    `define delay #3
    
// mealy state machine with synchronous outputs
    always @ (posedge pci_clk or negedge pci_rst_l) begin
        if (!pci_rst_l) begin // System Reset
            cstate      <= `delay idle;
            devsel_l    <= `delay 1'bZ; 
            trdy_l 		<= `delay 1'bZ; 
            stop_l 		<= `delay 1'bZ;
            pci_ad_oe 	<= `delay 0; 
            par_oe 		<= `delay 0; 
            bk_ba0_l    <= `delay 1;
            bk_ba1_l    <= `delay 1;
            data_rd_l   <= `delay 1;
            data_wr_l   <= `delay 1;
            r_w_l 		<= `delay 0;     // default to write
            read_flag 	<= `delay 0;     // default to write
            con_read_flag 	<= `delay 0; // default to write
            end 
            
        else begin 
            case (cstate) // parallel_case full_case
            
            idle: begin 
                //  总线地址期:锁存pci_cbe, pci_addr 及 pci_idsel 信号。
                if (!pci_frame_l) begin
                    pci_addr_reg  <= #1 pci_ad;     // register address
                    pci_cbe_reg   <= #1 pci_cbe;
                    pci_idsel_reg <= #1 pci_idsel;
                    end
                else begin
                    pci_addr_reg  <= #1 pci_addr_reg;
                    pci_cbe_reg   <= #1 pci_cbe_reg;
                    pci_idsel_reg <= #1 pci_idsel_reg;
                    end
                //     
                if ((`config_read || `config_write) && `func_zero_type_zero	&& !pci_frame_l && pci_idsel) begin 
                    cstate   <= `delay con_wait_med;
                    devsel_l <= `delay 1;    // disabled at first
                    trdy_l   <= `delay 1;    // disabled at first
                    stop_l   <= `delay 1;    // disabled at first
                    par_oe   <= `delay 0;
                    if (`config_read)     // config read 
                        con_read_flag <= `delay 1; // takes 1 tic
                    else  // config write
                        con_read_flag <= `delay 0; // takes 1 tic
                    tps[3] <= 1;
                    end
                //else if ((`io_read || `mem_read) && `no_config ) begin // Intel CPU
                else if ((`io_read || `mem_read) && !pci_frame_l) begin // AMD CPU
                    cstate 		<= `delay rw_wait_hit;
                    devsel_l 	<= `delay 1; 
                    trdy_l 	    <= `delay 1; 
                    stop_l 	    <= `delay 1;
                    pci_ad_oe   <= `delay 0; 
                    par_oe 	    <= `delay 0; 
                    bk_ba0_l    <= `delay 1;
                    bk_ba1_l    <= `delay 1;
                    data_rd_l   <= `delay 1;
                    data_wr_l   <= `delay 1;
                    r_w_l 	    <= `delay 0;
                    read_flag 	<= `delay 1;  // set because it's a read
                    tps[3] <= 1;
                    end
                //else if ((`io_write || `mem_write) && `no_config ) begin // Intel CPU
                else if ((`io_write || `mem_write) && !pci_frame_l) begin // AMD CPU
                    cstate 		<= `delay rw_wait_hit;
                    devsel_l 	<= `delay 1; 
                    trdy_l 	    <= `delay 1; 
                    stop_l 	    <= `delay 1;
                    pci_ad_oe   <= `delay 0; 
                    par_oe 	    <= `delay 0; 
                    bk_ba0_l    <= `delay 1;
                    bk_ba1_l    <= `delay 1;
                    data_rd_l   <= `delay 1;
                    data_wr_l   <= `delay 1;
                    r_w_l 	    <= `delay 0;
                    read_flag 	<= `delay 0;  // clear because it's a write
                    tps[3] <= 1;
                    end
                else begin // idle
                    cstate 	    <= `delay idle;
                    devsel_l 	<= `delay 1'bZ; 
                    trdy_l 	    <= `delay 1'bZ; 
                    stop_l 	    <= `delay 1'bZ;
                    pci_ad_oe   <= `delay 0; 
                    par_oe 	    <= `delay 0; 
                    bk_ba0_l    <= `delay 1;
                    bk_ba1_l    <= `delay 1;
                    data_rd_l   <= `delay 1;
                    data_wr_l   <= `delay 1;
                    r_w_l 		<= `delay 0;     // default to write
                    read_flag 	<= `delay 0;     // default to write
                    con_read_flag 	<= `delay 0; // default to write
                    tps[3:0] <= 4'b0;
                    end	      
            end
            
            con_wait_med: begin // 2'th clock : config cycle;
                 
                    cstate   <= `delay con_wait_slw;
                    devsel_l <= `delay 0;
                    if (con_read_flag)      // config read 
                        pci_ad_oe <= `delay 1; // takes 1 tic
                    else                    // config write
                        pci_ad_oe <= `delay 0; // takes 1 tic
                    tps[2] <= 1;
                    end

            con_wait_slw: begin // 3'th clock : config cycle;
                 	// ready to transfer
                    cstate <= `delay con;
                    trdy_l <= `delay 0;     // ready to transfer next tic
                    if (!pci_frame_l)  
                        stop_l <= `delay 0; // burst config not supported
                    else
                        stop_l <= `delay 1; // single Config is OK
                    tps[1] <= 1;
                    end

            con: begin // 4'th clock : config cycle;
                 if (!pci_irdy_l) begin // transfer data
                    cstate   <= `delay backoff;
                    devsel_l <= `delay 1;
                    trdy_l   <= `delay 1;
                    stop_l   <= `delay 1;
                    if (con_read_flag)   // config read
						par_oe <= `delay 1;
                    end
                else begin // wait for pci_irdy_l == 0
                    cstate   <= `delay con;
                    trdy_l   <= `delay 0;
                    if (!pci_frame_l)  
                        stop_l <= `delay 0; // burst config not supported
                                             // disconnect A or B
                    else
                        stop_l <= `delay 1; // single Config is OK
                    end
                end

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -