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

📄 state_machine.v

📁 基于pci的verolog hdl 状态机描述
💻 V
字号:
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  

⌨️ 快捷键说明

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