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  

原文地址:https://www.cnblogs.com/riskyer/p/3402453.html