详细的code

`ifdef   DLY
`else
   `define     DLY   #1
`endif

module efuse_ctrl (
//   Port Name     I/O  Width   Deiscription
// --------------------------------------------------------
      input wire         i_clk                // I     1    clock                                          
     ,input wire         i_rstb               // I     1    negative reset                                 
     ,input wire         i_rd_req             // I     1    read request                                   
     ,input wire         i_wr_req             // I     1    write request                                  
     ,input wire         i_pwr_rdy                                                                         
     ,input wire [ 7: 0] i_wr_dat             // I     8   write data in                                                                                                
     ,input wire [ 3: 0] i_Trs                // I     4    RST to CEB setup time (T)                         // default= 1    (T)(for -20% margin)        
     ,input wire [13: 0] i_Trp                // I     4    RST pulse width time (T) more than 1              // default= 5    (T)(for -20% margin)        
     ,input wire [ 3: 0] i_Trsq               // I     4    RST to data valid (T)                             // default= 5    (T)(for -20% margin)        
     ,input wire [13: 0] i_Tps                // I     4    PRG to CEB setup time(T)                          // default= 50   (T)(for -20% margin)        
     ,input wire [13: 0] i_Tpp                // I     14   PRG pulse width (T)                               // default= 5000 (T)(for -20% margin)        
     ,input wire [ 3: 0] i_Tpi                // I     4    program pulse interval (T) more than 1            // default= 1    (T)(for -20% margin)        
//   ,input wire [19: 0] i_tm_ctrl            // I     19    Test Mode control                                // test mode dircet input                    
//   ,input wire         i_tm_en              // I     1    Test Mode enable                                  // test enable   1:enable    0:disable                                      
     ,input wire [ 1: 0] ptm                  // I     2                                                                                                
     ,input wire [ 6: 0] fix_addr             // I      7           
     ,input wire         fix_a_d              // I      1 
     ,input wire         pdin_inv             // I      default 0 
//   ,input wire         otp_wr_dat_inv    
     ,input wire         index_programed                     
     ,input wire         index_trim                          
     ,input wire         index_gamma                         
     ,input wire         index_gip                           
     ,input wire         index_vcom_sel_1                    
     ,input wire         index_vcom_sel_2                    
     ,input wire         index_vcom_sel_3                    
     ,input wire         index_vcom_sel_4                                    
     ,input wire         index_other                         
     ,input wire         index_power                         
     ,input wire         index_custo                         
     ,input wire         index_i2c_sa 
     ,input wire         index_non_otp  
     ,input wire         index_dummy_otp   
     
     ,output reg          o_rdy                // O      1    ready               
     ,output reg          otp_read_en          // O      1
     ,output reg          otp_prog_en          // O      1
     ,output reg          otp_w_reg_clk        // O      1    OTP write regfile clk   //otp write to regfile clk
     ,output reg          prog_end             // O      1
     ,output wire [ 6: 0] addr_sel             // O      7
     ,output wire [ 7: 0] pdin_sel             // O      8    
     ,output wire [ 1: 0] ptm_sel              // O      2
     ,output wire         prg_sel              // O      1
     ,output wire         pprog_sel            // O      1  
     ,output wire         rst_sel              // O      1
     ,output wire [15: 0] efuse_ctrl_probe
      );

// STATE MACHINE SEQUENCE
// PROG : IDLE>> PG_Tps>> PG_Tpp>> PG_Tpi >> RADY>> IDLE
// READ : IDLE>> RD_Trs>> RD_Trp>> RD_Trsq>>RD_TWS>>RD_TWP>>RD_TWSQ>> RADY>> IDLE

   parameter IDLE             = 13'b00000_0000_0001 ;
   parameter WAIT_PWR         = 13'b00000_0000_0010 ;
   parameter PG_TPS           = 13'b00000_0000_0100 ;
   parameter PG_TPP           = 13'b00000_0000_1000 ;
   parameter PG_TPI           = 13'b00000_0001_0000 ;
   parameter WAIT_PWR_RELEASE = 13'b00000_0010_0000 ;
   parameter RD_TRS           = 13'b00000_0100_0000 ;
   parameter RD_TRP           = 13'b00000_1000_0000 ;
   parameter RD_TRSQ          = 13'b00001_0000_0000 ;
   parameter RD_TWS           = 13'b00010_0000_0000 ;
   parameter RD_TWP           = 13'b00100_0000_0000 ;
   parameter RD_TWSQ          = 13'b01000_0000_0000 ;
   parameter RADY             = 13'b10000_0000_0000 ;

// Input/Output Definition -------
   

// output         ceb_sel        ; //switch otp write clk active low                 
   reg    [12:0]  efuse_cs       ; // function state machine
   reg    [12:0]  efuse_ns       ; // function state machine
   reg    [10:0]  addr           ; // address (counter at prog mode)
   reg    [13:0]  Timing_cnt     ; // all timing parameter counter
   reg    [13:0]  Timing         ; // timing constant register
   reg            din            ;
         
//   wire   [ 7:0]  i_wr_datb      ;

   wire ceb ;    
   wire rst ;    
   wire prg ;    
   reg  ceb_sel    ;


//   wire ceb_sel_tmp;
   reg prg_sel_tmp;
   reg rst_sel_tmp;
   wire din_sel    ;
   wire T_reach    ;
   wire idle_st    ;
   wire wait_pwr_st;
   wire pg_tps_st  ;
   wire pg_tpp_st  ;
   wire pg_tpi_st  ;
   wire pwr_ris_st ;
   wire rd_trs_st  ;
   wire rd_trp_st  ;
   wire rd_trsq_st ;
   wire rd_tws_st  ;
   wire rd_twp_st  ;
   wire rd_twsq_st ;
   wire rady_st    ;
   wire prog_st    ;
   wire read_st    ;
   wire en_reg_clk    ;
   wire w_reg_clk;
   wire [7:0] pdin;
   wire pdin_prog;
  
             
   assign idle_st    = efuse_cs[ 0] ;
   assign wait_pwr_st= efuse_cs[ 1] ;
   assign pg_tps_st  = efuse_cs[ 2] ;
   assign pg_tpp_st  = efuse_cs[ 3] ;
   assign pg_tpi_st  = efuse_cs[ 4] ;
   assign pwr_ris_st = efuse_cs[ 5] ;
   
   assign rd_trs_st  = efuse_cs[ 6] ;
   assign rd_trp_st  = efuse_cs[ 7] ;
   assign rd_trsq_st = efuse_cs[ 8] ;
   assign rd_tws_st  = efuse_cs[ 9] ; 
   assign rd_twp_st  = efuse_cs[10] ; 
   assign rd_twsq_st = efuse_cs[11] ;
   assign rady_st    = efuse_cs[12] ;
     
   assign prog_st = (efuse_cs>=WAIT_PWR) & (efuse_cs<=WAIT_PWR_RELEASE)  ;
   assign read_st = (efuse_cs>=RD_TRS) & (efuse_cs<=RD_TWSQ) ;

   
   
   //---------- TIMING SETTING -------------
   always @ (*)
   begin
      case(efuse_cs)
      PG_TPS         : Timing[13:0] = (addr==7'b0) ? 14'd500 : i_Tps  ;
      PG_TPP         : Timing[13:0] = i_Tpp  ;
      PG_TPI         : Timing[13:0] = i_Tpi  ;
      RD_TRS         : Timing[13:0] = i_Trs  ;   
      RD_TRP         : Timing[13:0] = i_Trp  ;        
      RD_TRSQ        : Timing[13:0] = i_Trsq ;
      RD_TWS         : Timing[13:0] = i_Trs  ;
      RD_TWP         : Timing[13:0] = i_Trp  ;
      RD_TWSQ        : Timing[13:0] = i_Trsq ;      
      default        : Timing[13:0] =  14'h000f ;// ready state length
      endcase
   end
   
   assign T_reach = ( Timing_cnt >= Timing ) ;
   
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)
            Timing_cnt <= `DLY 14'd0 ;
      else if(prog_st | read_st |rady_st )
      begin
         if(T_reach | wait_pwr_st)
            Timing_cnt <= `DLY 14'd1 ;
         else 
            Timing_cnt <= `DLY Timing_cnt + 14'd1 ;
      end
      else 
            Timing_cnt <= `DLY 14'd0 ;
   end
  
   //---------- ADDRESS SETTING ---------------
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)
         addr <= `DLY 10'd0 ;
      else if(ceb)
         addr <= `DLY 10'd0 ;
      else if(fix_a_d)
         addr <= `DLY {fix_addr,3'b000};   
      else if( prog_st & pg_tpi_st & T_reach )
         addr <= `DLY addr + 10'd1 ;
      else if( read_st & rd_twsq_st & T_reach )
         addr <= `DLY addr + 10'd32 ;
      else
         addr <= `DLY addr ;
   end

   //-------- OUTPUT FOR APR SETTING--------
   
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)   
         o_rdy <= `DLY 1'b0   ;
      else if( i_rd_req | i_wr_req )          
         o_rdy <= `DLY 1'b0   ;
      else if(efuse_cs[12] & efuse_ns[0])
         o_rdy <= `DLY 1'b1   ;
   end
  
   always @(posedge i_clk or negedge i_rstb)
   begin                                    
      if(~i_rstb)                           
         prog_end <= `DLY 1'b0   ;             
      else if( i_wr_req )        
         prog_end <= `DLY 1'b0   ;             
      else if(pwr_ris_st)   
         prog_end <= `DLY 1'b1   ;             
   end                                      
   //----------- STATE MACHINE ------------
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)   
         efuse_cs <= `DLY IDLE ;
      else          
         efuse_cs <= `DLY efuse_ns ;
   end
   
   always @ (*)
   begin
      case(efuse_cs)
         IDLE :  //01
         begin 
            if(i_rd_req)
               efuse_ns = RD_TRS ;
            else if(i_wr_req)
               efuse_ns = WAIT_PWR ;
            else
               efuse_ns = IDLE ;
         end
         WAIT_PWR://02
         begin
            if(i_pwr_rdy)
               efuse_ns = PG_TPS ;
            else
               efuse_ns = WAIT_PWR ;   
         end        
         PG_TPS  ://04
         begin
            if (din_sel)
            begin
               if (T_reach)
                  efuse_ns = PG_TPP ;
               else
                  efuse_ns = PG_TPS ;
            end
            else
                  efuse_ns = PG_TPI;
         end            
         PG_TPP  ://08
         begin
            if (T_reach)
               efuse_ns = PG_TPI ;
            else
               efuse_ns = PG_TPP ;
         end
         PG_TPI  ://10
         begin
            if (T_reach)
            begin
               if((addr[9:3]>=7'd127)||(fix_a_d))
                  efuse_ns = WAIT_PWR_RELEASE ;
               else
                  efuse_ns = PG_TPS ;//02
            end
            else
               efuse_ns = PG_TPI ;
         end
         WAIT_PWR_RELEASE://20
         begin
            if(i_pwr_rdy==1'b0)
               efuse_ns = RADY;
            else if(i_wr_req)
               efuse_ns = PG_TPS ;
            else
               efuse_ns = WAIT_PWR_RELEASE;   
         end         
         
         
         
         RD_TRS  ://40
         begin
            if (T_reach)
               efuse_ns = RD_TRP ;
            else
               efuse_ns = RD_TRS ;
         end
         RD_TRP  ://80
         begin
            if (T_reach)
               efuse_ns = RD_TRSQ ;
            else
               efuse_ns = RD_TRP ;
         end
         RD_TRSQ ://100
         begin
            if (T_reach)
            begin
               if(en_reg_clk)   
               efuse_ns = RD_TWS ;
               else
               efuse_ns = RADY; 
            end   
            else
               efuse_ns = RD_TRSQ ;
         end
         RD_TWS   ://200
         begin
             if (T_reach)
               efuse_ns = RD_TWP ;
            else
               efuse_ns = RD_TWS ;
         end
         
         RD_TWP://400
         begin
             if (T_reach)
               efuse_ns = RD_TWSQ ;
            else
               efuse_ns = RD_TWP ;
         end
         
         RD_TWSQ://800
         begin
              if (T_reach)
            begin
               if((addr[9:5] >= 5'd31)||(fix_a_d))
                  efuse_ns = RADY ;
               else
                  efuse_ns = RD_TRS ;
            end
            else
               efuse_ns = RD_TWSQ;
         end
                          
         RADY ://1000
         begin
            if(T_reach)
               efuse_ns = IDLE ;
            else
               efuse_ns = RADY ;
         end

         default : efuse_ns = IDLE ;
      
      endcase
    end

//-------- OUTPUT FOR E-FUSE SETTING ------
   assign w_reg_clk = rd_twp_st & en_reg_clk;
   assign rst = rd_trp_st ;
   assign ceb = !(read_st | prog_st) ;

   assign prg = pg_tpp_st ? din : 1'b0 ;
   assign din_sel       =(din & prog_st & pdin_prog) ; 
//   assign din = ~&pdin; 
//   assign i_wr_datb = ~i_wr_dat; 
// assign i_wr_datb = fix_a_d ? ~fix_pdin : ~i_wr_dat;


always @ (*)
begin
   case(addr[9:3])
7'h00:din=index_programed;
7'h01:din=index_programed;
7'h02:din=index_programed;
7'h03:din=index_programed;  
7'h04:din=index_trim;
7'h05:din=index_trim;
7'h06:din=index_trim;
7'h07:din=index_trim;      
7'h08:din=index_trim;
7'h09:din=index_trim;
7'h0a:din=index_non_otp;
7'h0b:din=index_non_otp;      
7'h0c:din=index_custo;
7'h0d:din=index_custo;
7'h0e:din=index_custo;
7'h0f:din=index_custo;      
7'h10:din=index_custo;
7'h11:din=index_custo;
7'h12:din=index_custo;
7'h13:din=index_custo;      
7'h14:din=index_gamma;
7'h15:din=index_gamma;
7'h16:din=index_gamma;
7'h17:din=index_gamma;
7'h18:din=index_gamma;
7'h19:din=index_gamma;
7'h1a:din=index_gamma;
7'h1b:din=index_gamma;      
7'h1c:din=index_gamma;
7'h1d:din=index_gamma;
7'h1e:din=index_gamma;
7'h1f:din=index_gamma;
7'h20:din=index_gamma;
7'h21:din=index_gamma;
7'h22:din=index_gamma;
7'h23:din=index_gamma;      
7'h24:din=index_gamma;
7'h25:din=index_gamma;
7'h26:din=index_gamma;
7'h27:din=index_gamma;
7'h28:din=index_gamma;
7'h29:din=index_gamma;
7'h2a:din=index_gamma;
7'h2b:din=index_gamma;
7'h2c:din=index_dummy_otp;
7'h2d:din=index_dummy_otp;
7'h2e:din=index_dummy_otp;
7'h2f:din=index_dummy_otp;
7'h30:din=index_non_otp;
7'h31:din=index_other;
7'h32:din=index_other;
7'h33:din=index_other;
7'h34:din=index_other;
7'h35:din=index_other;      
7'h36:din=index_power;
7'h37:din=index_power;      
7'h38:din=index_power;
7'h39:din=index_power;
7'h3a:din=index_power;
7'h3b:din=index_power;      
7'h3c:din=index_gip;
7'h3d:din=index_gip;
7'h3e:din=index_gip;
7'h3f:din=index_gip;
7'h40:din=index_gip;
7'h41:din=index_gip;
7'h42:din=index_gip;
7'h43:din=index_gip;
7'h44:din=index_gip;
7'h45:din=index_gip;
7'h46:din=index_gip;
7'h47:din=index_gip;
7'h48:din=index_gip;
7'h49:din=index_gip;
7'h4a:din=index_gip;
7'h4b:din=index_non_otp;
7'h4c:din=index_non_otp;
7'h4d:din=index_non_otp;
7'h4e:din=index_non_otp;
7'h4f:din=index_non_otp;
7'h50:din=index_gip;
7'h51:din=index_gip;
7'h52:din=index_gip;
7'h53:din=index_gip;
7'h54:din=index_gip;
7'h55:din=index_gip;
7'h56:din=index_non_otp;
7'h57:din=index_non_otp;
7'h58:din=index_non_otp;
7'h59:din=index_non_otp;      
7'h5a:din=index_non_otp;
7'h5b:din=index_non_otp;      
7'h5c:din=index_i2c_sa;
7'h5d:din=index_other;
7'h5e:din=index_other;
7'h5f:din=index_other;
7'h60:din=index_other;
7'h61:din=index_other;
7'h62:din=index_other;
7'h63:din=index_other;
7'h64:din=index_other;
7'h65:din=index_other;
7'h66:din=index_other;
7'h67:din=index_other;
7'h68:din=index_other;
7'h69:din=index_other;
7'h6a:din=index_other;
7'h6b:din=index_other;
7'h6c:din=index_other;
7'h6d:din=index_other;
7'h6e:din=index_non_otp;
7'h6f:din=index_non_otp;
7'h70:din=index_other;
7'h71:din=index_other;
7'h72:din=index_other;
7'h73:din=index_other;
7'h74:din=index_other;
7'h75:din=index_other;
7'h76:din=index_other;
7'h77:din=index_other;
7'h78:din=index_other;
7'h79:din=index_other;
7'h7a:din=index_other;
7'h7b:din=index_non_otp;
7'h7c:din=index_vcom_sel_1;
7'h7d:din=index_vcom_sel_2;
7'h7e:din=index_vcom_sel_3;
7'h7f:din=index_vcom_sel_4;
   default: din =1'b0;
   endcase
   
end  
  

//wire [7:0] pdin_pre;
//assign pdin_pre = otp_wr_dat_inv ? i_wr_dat : i_wr_datb;

reg [7:0] pdin_temp;
always @ (*)
begin
   case (addr[2:0])
   3'd0: pdin_temp = i_wr_dat & 8'b0000_0001;
   3'd1: pdin_temp = i_wr_dat & 8'b0000_0010;   
   3'd2: pdin_temp = i_wr_dat & 8'b0000_0100;
   3'd3: pdin_temp = i_wr_dat & 8'b0000_1000;
   3'd4: pdin_temp = i_wr_dat & 8'b0001_0000;
   3'd5: pdin_temp = i_wr_dat & 8'b0010_0000;
   3'd6: pdin_temp = i_wr_dat & 8'b0100_0000;
   3'd7: pdin_temp = i_wr_dat & 8'b1000_0000;
default: pdin_temp = 8'b0;
   endcase
end


//pdin=0,prg then pdin_inv =0;
//pdin=1,pro then pidn_inv =1;

assign pdin = pdin_inv ? pdin_temp : ~pdin_temp ;
assign pdin_prog = pdin_inv ? |pdin : ~&pdin;


/*
   always @ (*)
   begin
      if ((prog_st==1'b1) && (addr==7'b0))
      pdin ={i_wr_datb[7:1],1'b0};  
      else     
      pdin = i_wr_datb;
   end
*/   
   assign en_reg_clk = 1'b1;   
/*   
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)
         en_reg_clk <= `DLY  1'b0  ; 
      else if((addr[6:2] == 5'd0)&&(rd_trp_st))
         en_reg_clk <= `DLY  1'b1  ;
      else if(fix_a_d&&prog_st)
         en_reg_clk <= `DLY  1'b1;   
      else
         en_reg_clk <= `DLY en_reg_clk;           
   end
*/


reg pprog_tmp;
         
   always @(posedge i_clk or negedge i_rstb)
   begin
      if(~i_rstb)
      begin
         ceb_sel            <= `DLY  1'b1  ;
         prg_sel_tmp        <= `DLY  1'b0  ;  
         rst_sel_tmp        <= `DLY  1'b0  ;
         otp_w_reg_clk      <= `DLY  1'b0  ;
         pprog_tmp          <= `DLY  1'b0  ;
         otp_read_en        <= `DLY  1'b0  ;
         otp_prog_en        <= `DLY  1'b0  ;

      end   
      else
      begin

         ceb_sel            <= `DLY  ceb;
         prg_sel_tmp        <= `DLY  prg;  
         rst_sel_tmp        <= `DLY  rst;
         otp_w_reg_clk      <= `DLY  w_reg_clk;
         pprog_tmp          <= `DLY  prog_st  ;
         otp_read_en        <= `DLY  read_st;
         otp_prog_en        <= `DLY  prog_st;
         
      end   
   end      

/*
   //------------ TEST MODE  -----------------------
   assign ptm_sel   = i_tm_en ? i_tm_ctrl[19:18]  : ptm        ;//PTM[1:0]
   assign pprog_sel = i_tm_en ? i_tm_ctrl[17]     : pprog_tmp  ;//PPROG
   assign prg_sel   = i_tm_en ? i_tm_ctrl[16]     : prg_sel_tmp;//PWE
   assign rst_sel   = i_tm_en ? i_tm_ctrl[15]     : rst_sel_tmp;//POR
   assign pdin_sel  = i_tm_en ? i_tm_ctrl[14:7]   : pdin       ;//PDIN[7:0]
   assign addr_sel  = i_tm_en ? i_tm_ctrl[6:0]    : addr[9:3]       ;//PA[6:0]
*/


   //------------ TEST MODE  -----------------------                            
   assign ptm_sel   = ptm        ;//PTM[1:0]      
   assign pprog_sel = pprog_tmp  ;//PPROG         
   assign prg_sel   = prg_sel_tmp;//PWE           
   assign rst_sel   = rst_sel_tmp;//POR           
   assign pdin_sel  = pdin       ;//PDIN[7:0]     
   assign addr_sel  = addr[9:3]       ;//PA[6:0]  


   
   //---------- INSTANCE EFUSE ---------------
   assign efuse_ctrl_probe ={o_rdy,otp_read_en,otp_prog_en,otp_w_reg_clk,prog_end,prg_sel,pprog_sel,rst_sel,pdin};


   

   
endmodule       

  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

妙妙米奇屋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值