`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
1万+

被折叠的 条评论
为什么被折叠?



