zoukankan      html  css  js  c++  java
  • PCI总线目标接口状态机设计

    module state_machine (devsel_l, trdy_l, stop_l, pci_ad_oe, 
        dts_oe, par_oe, bk_oe, pci_ad_en, hit_ba0_l, hit_ba1_l, 
        pci_frame_l, pci_idsel, pci_irdy_l, pci_ad, pci_cbe_l, 
        pci_clk, pci_rst_l, abort_sig, data_stop_l, com, 
        data_write_l, ready_l, bkend_abort_l, count_rst_l, count_en_l, 
        retry_l, base_region0_l, base_region1_l, r_w_l, data_read_l,
        be_oe);
     
      output devsel_l; 
      output trdy_l; 
      output stop_l; 
      output pci_ad_oe;     // OE for PCI address bus
      output dts_oe;        // OE control for the devsel, trdy_l, stop_l (dts)
      output par_oe;        // OE control for pci_par
      output bk_oe;         // OE control for bkend_dat bus
      output pci_ad_en;     // clock enable for the PCI address latch register
      output abort_sig;     // sets the status register bit for abort
      output data_write_l;  // used as a clock enable for the pci_clk
                            // to the bkend device
      output count_rst_l;   // async reset to the retry counter
      output count_en_l;    // the clock enable for the retry counter
      output base_region0_l; // chip selects to the backend 
      output base_region1_l; // chip selects to the backend
      output r_w_l;          // read == 1 & write == 0
      output data_read_l;    // the read strobe for the backend device
      output be_oe;          // enables the byte enables for the backend
      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 pci_frame_l;     // The pci_frame_l signal
      input pci_idsel;      // The pci idsel signal
      input pci_irdy_l;     // The pci irdy signal
      input [31:0] pci_ad;  // raw pci address data bus
      input [3:0] pci_cbe_l; // The command or byte enables 
      input pci_clk;
      input pci_rst_l;
      input bkend_abort_l;  // bkend has had a fatal error
      input data_stop_l;    // bkend requesting transaction to stop
      input [1:0] com;
      input ready_l;        // bkend is ready to start a transaction cycle
      input retry_l;        // when active retry counter has timed out 


      
      reg devsel_l; 
      reg trdy_l, stop_l, pci_ad_oe; 
      reg dts_oe, par_oe, bk_oe; 
      reg pci_ad_en;
      reg be_oe;
      reg abort_sig;
      reg count_rst_l, count_en_l;
      reg base_region0_l, base_region1_l;
      reg r_w_l;
      reg read_flag, single_read_flag;
     
      
      reg [11:0] cstate;
     
     
      parameter [11:0] 


         idle =         12'b0000_0000_0001,
         con_wait =     12'b0000_0000_0010,
         con_wait2 =    12'b0000_0000_0100,
         con =          12'b0000_0000_1000,
         read_wait =    12'b0000_0001_0000,
         rw =           12'b0000_0010_0000,
         rw_wait =      12'b0000_0100_0000,
         rw_wait2 =     12'b0000_1000_0000,
         last_rw =      12'b0001_0000_0000,
         backoff =      12'b0010_0000_0000,
         retry =        12'b0100_0000_0000,
         abort =        12'b1000_0000_0000;




     
     `define config_read (pci_cbe_l == 4'b1010)
     `define config_write (pci_cbe_l == 4'b1011)
     `define func_zero_type_zero (pci_ad[10:8] == 3'b000) && (pci_ad[1:0] == 2'b00)


     `define write_ba0 pci_addr[7:2] == 6'h10
     `define write_ba1 pci_addr[7:2] == 6'h14
     
     `define no_config (!pci_idsel && !pci_frame_l)
     `define io_read ((pci_cbe_l == 4'b0010)  && com[0]) 
     `define io_write ((pci_cbe_l == 4'b0011) && com[0])
     `define mem_read ((pci_cbe_l == 4'b0110) && com[1])
     `define mem_write ((pci_cbe_l == 4'b0111) && com[1])


     
     // mealy state machine 
     always @ (posedge pci_clk or negedge pci_rst_l)
       begin 
         if (!pci_rst_l) begin 
    cstate <= #1 idle;
    devsel_l <= #1 1; 
             trdy_l <= #1 1; 
    stop_l <= #1 1;
    pci_ad_oe <= #13 0; 
             dts_oe <= #13 0; 
    par_oe <= #13 0; 
    bk_oe <= #13 0; 
             abort_sig <= #1 0;
    count_rst_l <= #1 1;
    count_en_l <= #1 1;
    base_region0_l <= #1 1;
    base_region1_l <= #1 1;
    r_w_l <= #1 1; 
    read_flag <= #1 0;
    single_read_flag <= #1 0;
            end 
            else begin 
    case (cstate) 
      idle:
           begin 
          if ((`config_read || `config_write) && `func_zero_type_zero
    && !pci_frame_l && pci_idsel) begin 
           cstate <= #1 con_wait;
     dts_oe <= #13 1;
             if (`config_read) begin 
       pci_ad_oe <= #13 1; 
     end
     else begin 
       pci_ad_oe <= #13 0; 
     end
     par_oe <= #13 0;
     devsel_l <= #1 1;
     trdy_l <= #1 1; 
     stop_l <= #1 1; 
     count_rst_l <= #1 1;
             count_en_l <= #1 1;
     abort_sig <= #1 0;
     base_region0_l <= #1 1;
             base_region1_l <= #1 1;
             r_w_l <= #1 1;
    end


    else if ((`io_read || `mem_read) && `no_config ) begin 
     cstate <= #1 rw_wait;
     read_flag <= #1 1; 
     dts_oe <= #13 1; 
     devsel_l <= #1 1; 
     trdy_l <= #1 1;
     stop_l <= #1 1; 
     count_rst_l <= #1 0; 
             count_en_l <= #1 1;
     abort_sig <= #1 0; 
     base_region0_l <= #1 1;
             base_region1_l <= #1 1;
             r_w_l <= #1 1;
    end
    else if ((`io_write || `mem_write) && `no_config )begin 
     cstate <= #1 rw_wait;
     read_flag <= #1 0; 
     dts_oe <= #13 1; 
     devsel_l <= #1 1;
     trdy_l <= #1 1; 
     stop_l <= #1 1; 
     count_rst_l <= #1 0;
             count_en_l <= #1 1;
     abort_sig <= #1 0; 
     base_region0_l <= #1 1;
             base_region1_l <= #1 1;
             r_w_l <= #1 1; 
    end
    else begin 
     cstate <= #1 idle;
             devsel_l <= #1 1; 
                      trdy_l <= #1 1; 
             stop_l <= #1 1;
             pci_ad_oe <= #13 0; 
                      dts_oe <= #13 0; 
             par_oe <= #13 0; 
             bk_oe <= #13 0; 
                      abort_sig <= #1 0;
             count_rst_l <= #1 1;
             count_en_l <= #1 1;
     abort_sig <= #1 0; 
     base_region0_l <= #1 1;
             base_region1_l <= #1 1;
             r_w_l <= #1 1;
    end      
         end
         
            con_wait: 
         begin 
            cstate <= con_wait2;
                     devsel_l <= #1 0;
         end


    con_wait2: 
         begin 
    cstate <= con;
    par_oe <= #13 1; 
      trdy_l <= #1 0; 
                    if (!pci_frame_l)  
     stop_l <= #1 0; 
                    
    else
     stop_l <= #1 1; 
         end


    con:
         begin 
    if (!pci_irdy_l) begin 
     
     cstate <= backoff;
     devsel_l <= #1 1;
     trdy_l <= #1 1;
     stop_l <= #1 1;
     pci_ad_oe <= #13 0;
    end
    else begin 
     
     cstate <= con;
     devsel_l <= #1 0;
     trdy_l <= #1 0;
     if (!pci_frame_l)  
       stop_l <= #1 0; 
                      
     else
         stop_l <= #1 1; 
    end
         end




         rw_wait:
            begin 

          if (pci_frame_l && read_flag) begin 
        single_read_flag <= #1 1;
              end
              else begin 
        single_read_flag <= #1 0; 
              end


          if (!hit_ba0_l) begin 
              cstate <= #1 rw_wait2;
              count_rst_l <= #1 1;
      count_en_l <= #1 0; 
      base_region0_l <= #1 0;
      base_region1_l <= #1 1;
      dts_oe <= #13 1; 
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 1;
      if (read_flag) begin 
        bk_oe <= #13 0;
        r_w_l <= #1 1;
        end
      else begin 
        bk_oe <= #13 1; 
        r_w_l <= #1 0;
      end 
    end
    else if (!hit_ba1_l) begin 
      cstate <= #1 rw_wait2;
              count_rst_l <= #1 1;
      count_en_l <= #1 0;
      base_region0_l <= #1 1; 
      base_region1_l <= #1 0;
      dts_oe <= #13 1; 
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 1; 
      if (read_flag) begin 
        bk_oe <= #13 0; 
        r_w_l <= #1 1;
        end
      else begin 
        bk_oe <= #13 1; 
        r_w_l <= #1 0;
      end 
    end
    else begin 
      cstate <= #1 idle;
      bk_oe <= #13 0;  
              count_rst_l <= #1 1; 
      count_en_l <= #1 1;
      r_w_l <= #1 1;
      base_region0_l <= #1 1;
      base_region1_l <= #1 1; 
      dts_oe <= #13 0; 
      devsel_l <= #1 1; 
      trdy_l <= #1 1;
      stop_l <= #1 1;
    end
        end

        
              rw_wait2: // don't monitor abort here
         begin 

    if (read_flag) begin 
             pci_ad_oe <= #13 1;
     par_oe <= #13 1;
     end
    else begin 
                      pci_ad_oe <= #13 0; 
    end

    if (!retry_l) begin 
     // retry timeout
     cstate <= #1 retry;
     devsel_l <= #1 0; 
     trdy_l <= #1 1; 
     stop_l <= #1 0; 
    end
    else if (retry_l && !ready_l && !pci_frame_l && data_stop_l) begin 
     // normal burst write or read with no timeout or stop
     devsel_l <= #1 0; 
     stop_l <= #1 1; 
                      if (read_flag) begin 
       cstate <= read_wait;
       trdy_l <= #1 1;
     end
     else begin 
       cstate <= rw;
       trdy_l <= #1 0;
     end
    end
    else if (retry_l && !ready_l && pci_frame_l) begin 
     // single read or write with no timeout & stop is don't care
     devsel_l <= #1 0; 
     stop_l <= #1 1;
       if (read_flag) begin 
       cstate <= read_wait;
       trdy_l <= #1 1;
     end
     else begin 
       cstate <= last_rw;
       trdy_l <= #1 0;
     end
    end
    else if (retry_l && !ready_l && !data_stop_l) begin 
     // single read or write & backend only wants one cycle
     if (read_flag ) begin 
       cstate <= read_wait;
       devsel_l <= #1 0; 
               trdy_l <= #1 1;
       stop_l <= #1 1;
     end
     else begin 
       cstate <= last_rw; 
       devsel_l <= #1 0; 
       trdy_l <= #1 0; 
       stop_l <= #1 0; 
     end
    end
    else if (retry_l && ready_l) begin 
     // enable retry counter
     cstate <= #1 rw_wait2;
     count_en_l <= #1 0;
     devsel_l <= #1 0; 
     trdy_l <= #1 1; 
     stop_l <= #1 1; 
    end
    else if (!bkend_abort_l) begin 
     cstate <= #1 abort;
     devsel_l <= #1 1; 
     trdy_l <= #1 1; 
     stop_l <= #1 0;
       abort_sig <= #1 1;
    end
    else begin 
     cstate <= rw_wait2;
    end
         
         end


              read_wait: 
        //This state is used to READ the first piece of data
         begin   
            if ( !bkend_abort_l) begin 
      cstate <= #1 abort;
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 0;
      bk_oe <= #13 0;
      base_region0_l <= #1 1; 
      base_region1_l <= #1 1; 
      abort_sig <= #1 1;
    end
    else if (!pci_frame_l && bkend_abort_l && data_stop_l) begin 
      cstate <= #1 rw; 
      devsel_l <= #1 0; 
      trdy_l <= #1 0; 
      stop_l <= #1 1; 
    end
            else if (pci_frame_l && bkend_abort_l && data_stop_l) begin 
      cstate <= #1 last_rw; 
      devsel_l <= #1 0; 
      trdy_l <= #1 0; 
      stop_l <= #1 1;
    end
     
    else if (!data_stop_l) begin 
      cstate <= last_rw;
      devsel_l <= #1 0; 
      trdy_l <= #1 0; 
      stop_l <= #1 0;
      bk_oe <= #13 0;
    end
    else  begin 
      cstate <= idle;
    end
          
         end

     rw:
         begin 
           if ( !bkend_abort_l) begin 
      cstate <= #1 abort;
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 0;
        bk_oe <= #13 0;  
      base_region0_l <= #1 1; 
      base_region1_l <= #1 1; 
      abort_sig <= #1 1;
    end
    else if (!pci_frame_l && bkend_abort_l && data_stop_l) begin 
      cstate <= #1 rw;
      devsel_l <= #1 0; 
      trdy_l <= #1 0; 
      stop_l <= #1 1; 
    end
    else if (pci_frame_l && bkend_abort_l && data_stop_l) begin 
      cstate <= #1 backoff;
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 1;
      pci_ad_oe <= #13 0;
        bk_oe <= #13 0;  
      base_region0_l <= #1 1; 
      base_region1_l <= #1 1; 
    end
    else if (pci_frame_l && !data_stop_l) begin 
      cstate <= backoff;
      devsel_l <= #1 1; 
      trdy_l <= #1 1; 
      stop_l <= #1 1;
      bk_oe <= #13 0;  
                       base_region0_l <= #1 1; 
      base_region1_l <= #1 1; 
    end
    else if (!data_stop_l) begin 
      cstate <= last_rw; 
      devsel_l <= #1 0; 
      trdy_l <= #1 0; 
      stop_l <= #1 0;
    end
    else  begin 
      cstate <= idle;
    end
          
         end
     last_rw:
           begin 
    if (pci_frame_l) begin 
     // pci_frame_l end gracefully
     cstate <= backoff;
     devsel_l <= #1 1; 
     trdy_l <= #1 1; 
     stop_l <= #1 1;
                      bk_oe <= #13 0;  
     pci_ad_oe <= #13 0;
                      base_region0_l <= #1 1; 
     base_region1_l <= #1 1; 
    end
    else if (!pci_frame_l) begin 
     cstate <= last_rw; 
     devsel_l <= #1 0; 
       trdy_l <= #1 1;
     stop_l <= #1 0;
    end
    else begin 
                      cstate <= idle;
    end     
         end
    retry:
             begin
           if (!pci_frame_l) begin 
     cstate <= retry;
     dts_oe <= #13 1; 
     devsel_l <= #1 0; 
     trdy_l <= #1 1; 
     stop_l <= #1 0;
       bk_oe <= #13 0;  
                      base_region0_l <= #1 1; 
     base_region1_l <= #1 1;   
    end
    else if (pci_frame_l) begin 
     cstate <= backoff;
     devsel_l <= #1 1; 
     trdy_l <= #1 1; 
     stop_l <= #1 1;
                      bk_oe <= #13 0; 
       pci_ad_oe <= #13 0;
     base_region0_l <= #1 1; 
     base_region1_l <= #1 1;  
    end
         end
             abort:
         begin 
    if (!pci_frame_l) begin 
     cstate <= abort;
     devsel_l <= #1 1; 
     trdy_l <= #1 1; 
     stop_l <= #1 0;
     abort_sig <= #1 0;
    end
    else if (pci_frame_l) begin 
     cstate <= backoff;
     devsel_l <= #1 1; 
     trdy_l <= #1 1; 
     stop_l <= #1 1;
     bk_oe <= #13 0;
     pci_ad_oe <= #13 0;
     abort_sig <= #1 0; 
    end
         end
    backoff:
             begin 
    cstate <= idle;
    pci_ad_oe <= #13 0; 
    dts_oe <= #13 0; 
    par_oe <= #13 0; 
    bk_oe <=#13 0; 
         end


    default:
         begin 
    cstate <= #1 idle;
           devsel_l <= #1 1; 
                    trdy_l <= #1 1; 
           stop_l <= #1 1;
           pci_ad_oe <= #13 0; 
                    dts_oe <= #13 0; 
           par_oe <= #13 0; 
           bk_oe <= #13 0; 
                    abort_sig <= #1 0;
         end
    endcase
           end
       
       end
     
    always @ (cstate)
      begin 
        if (cstate == idle || cstate == backoff) begin 
            be_oe <= #1 0;
          end
          else begin 
    be_oe <= #1 1;
          end
      
      end




    always @ (pci_frame_l or cstate)
      begin 
        if (cstate == idle && !pci_frame_l) begin 
            pci_ad_en <= #1 1;
          end
          else begin 
    pci_ad_en <= #1 0;
          end
      
      end




    assign #1 data_write_l = (!trdy_l && !pci_irdy_l && !read_flag && !ready_l) ? 0 : 1;




    assign #1 data_read_l = ( (single_read_flag && (cstate == rw_wait2) && !ready_l ) || (!single_read_flag && read_flag && !pci_frame_l && !pci_irdy_l && !ready_l && (cstate == rw_wait2 || cstate == rw || cstate == last_rw || cstate == abort)) ) ? 0 : 1;       
     
    endmodule  

  • 相关阅读:
    第010讲~第011讲:一个打了激素的数组
    练习15--阅读文件
    第007讲~第009讲:了不起的分支和循环
    第006讲:Python之常用操作符
    第005讲:闲聊之python的数据类型
    练习14--提示和传递
    第004讲:改进我们的小游戏
    ICPC Central Europe Regional Contest 2019 H. Ponk Warshall
    2019 ICPC Asia Yinchuan Regional G. Pot!!(线段树 区间更新 区间查询)
    CF1286A Garland
  • 原文地址:https://www.cnblogs.com/riskyer/p/3402453.html
Copyright © 2011-2022 走看看