基于Verilog的mx25L1605A(Serial Flash)模型
更新时间:2024-07-11 17:09:01 阅读量: 综合文库 文档下载
/*---------------------------------------------------------------------------- *
* mx25L1605A.v - 16M-BIT CMOS Serial Flash *
* COPYRIGHT 2005 BY Macronix International Corporation *
*----------------------------------------------------------------------------- * Creation Date: 2005/5/ * Doc : REV.0.00, MAY. 11, 2005 * VERSION : V 0.01
* Note : This model do not include test mode * Description :
* module flash_16m -> behavior model for the 16M serial flash *----------------------------------------------------------------------------- */
`timescale 1ns / 1ps
// Define controller state
`define STANDBY_STATE 0 `define ACTION_STATE 1 `define CMD_STATE 2 `define BAD_CMD_STATE 3
`define SECTOR_ERASE_TIME 90_000_000 // 90 ms `define BLOCK_ERASE_TIME 1_000_000_000 // 1 s `define CHIP_ERASE_TIME 32_000_000 // 32 s `define PROG_TIME 1_400_000 // 1.4 ms // Time delay to write instruction
`define PUW_TIME 10_000_000 // 10 ms
`define MX25L1605A //MX25L4005
`ifdef MX25L4005
`define FLASH_ADDR 19 `define SECTOR_ADDR 7 `define BLOCK_ADDR 4 `else
`ifdef MX25L1605A
`define FLASH_ADDR 21 `define SECTOR_ADDR 9 `define BLOCK_ADDR 5 `endif `endif
`define FLASH_TYPE 0
module flash_16m( SCLK, CS, SI, SO, WP, HOLD);
//--------------------------------------------------------------------- // Declaration of ports (input,output, inout)
//--------------------------------------------------------------------- input SCLK, // Signal of Clock Input CS, // Chip select (Low active) SI, // Serial Data Input
WP, // Write Protection:connect to GND HOLD; //
output SO; // Serial Data Output
//--------------------------------------------------------------------- // Declaration of parameter (parameter)
//---------------------------------------------------------------------
parameter FLASH_SIZE = 1 << `FLASH_ADDR, // 2M bytes SECTOR_SIZE = 1 << 12, // 4K bytes BLOCK_SIZE = 1 << 16, // 64K bytes
tAA = 12, // Access Time [ns],tAA = tSKH + tCLQ
tC = 14, // Clock Cycle Time,tC = tSKH + tSKL
//tSKH = 9, // Clock High Time //tSKL = 9, // Clock Low Time
tSHQZ = 6, // CS High to SO Float Time [ns] tCLQV = 1, // Clock Low to Output Valid tDP = 3_000, // 3 us tRES1 = 3_000, // 3 us tRES2 = 1_800, // 1.8 us
tW_SRWD = 15_000_000, // 15 ms tW_BP = 500_000_000, // 500 ms tW_WIP = 30_000_000, // 30 ms tW_WEL = 30_000_000; // 30 ms
parameter [7:0] ID_MXIC = 8'hc2; `ifdef MX25L4005
parameter [7:0] ID_Device = 8'h13; // MX25L4005 `else
`ifdef MX25L1605A
parameter [7:0] ID_Device = 8'h14; // MX25L1605A `endif `endif
parameter [7:0] WREN = 8'h06, //WriteEnable = 8'h06, WRDI = 8'h04, //WriteDisable = 8'h04, RDID = 8'h9F, //ReadID = 8'h9f, RDSR = 8'h05, //ReadStatus = 8'h05, WRSR = 8'h01, //WriteStatus = 8'h01, READ = 8'h03, //ReadData = 8'h03,
FASTREAD = 8'h0b, //FastReadData = 8'h0b,
PARALLELMODE = 8'h55, //PallelMode = 8'h55, SE = 8'h20, //SectorErase = 8'h20 BE = 8'hd8, //BlockErase = 8'hd8
CE1 = 8'h60, //ChipErase = 8'h60,//8'hc7 CE2 = 8'hc7, //ChipErase = 8'h60,//8'hc7 PP = 8'h02, //PageProgram = 8'h02, DP = 8'hb9, //DeepPowerDown = 8'hb9, EN4K = 8'ha5, //Enter4kbSector= 8'ha5, EX4K = 8'hb5, //Exit4kbSector = 8'hb5,
RDP = 8'hab, //ReleaseFromDeepPowerDwon = 8'hab, RES = 8'hab, //ReadElectricID = 8'hab,
REMS = 8'h90; //ReadElectricManufacturerDeviceID = 90;
/******************************************************/ wire[7:0] dataspi; reg[`FLASH_ADDR - 1:0] addrspi;
/******************************************************/
//--------------------------------------------------------------------- // Declaration of internal-register (reg)
//---------------------------------------------------------------------
// memory array
reg [7:0] ROM_ARRAY[ 0:FLASH_SIZE-1 ]; reg [7:0] status_reg; // Status Register
reg [256*8-1:0] si_reg; // temp reg to store serial in reg [23:0] address; //
reg [256*8-1:0] psi_reg; // temp reg to store serial in reg [256*8-1:0] dummy_A; // page size
reg [12:0] segment_addr; // A[20:8] segment address reg [7:0] offset_addr; // A[7:0] means 256 bytes
reg [`SECTOR_ADDR - 1:0] sector; // means 512 sectors
reg [2:0] state, rState;
reg ENB_S0,ENB_P0,ENB_S1,ENB_P1; reg SO_reg;
reg PO_reg6,PO_reg5,PO_reg4,PO_reg3,PO_reg2,PO_reg1,PO_reg0; reg
latch_SO,latch_PO6,latch_PO5,latch_PO4,latch_PO3,latch_PO2,latch_PO1,latch_PO0; reg pp_p;
reg pmode; // parallel mode
reg dpmode; // deep power down mode reg enter4kbmode; // enter 4kb mode reg chip_erase_oe;
integer i,chip_erase_count; wire wp_reg = WP;
assign SO = pp_p ? 8'bz : SO_reg; always @(SO) begin latch_SO = SO; //latch_PO6 = PO6; end
/*-------------------------------------------------------*/
/* initial variable value */ /*-------------------------------------------------------*/ initial begin
pp_p = 1'b0; enter4kbmode = 1'b0; dpmode = 1'b0; pmode = 1'b0; chip_erase_oe = 1'b0; chip_erase_count = 0;
status_reg = 8'b0000_0000;
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; i = 0; end
/*-------------------------------------------------------*/
/* latch signal SI into si_reg */ /*-------------------------------------------------------*/ always @( posedge SCLK ) begin if ( $time > `PUW_TIME ) begin if ( CS == 1'b0 ) begin
{ si_reg[ 256*8-1:0 ] } = { si_reg[ 256*8-2:0 ], SI }; end end end
/*-------------------------------------------------------*/
/* chip erase process */ /*-------------------------------------------------------*/ always @( posedge chip_erase_oe ) begin
chip_erase_count = 0; for ( chip_erase_count = 0;chip_erase_count<=`CHIP_ERASE_TIME;chip_erase_count=chip_erase_count+1) begin #1000; end
//WIP : write in process bit chip_erase_count = 0;
for( chip_erase_count = 0; chip_erase_count < FLASH_SIZE; chip_erase_count = chip_erase_count+1 ) begin
ROM_ARRAY[ chip_erase_count ] <= 8'hff; end
chip_erase_count = 0; //WIP : write in process bit status_reg[0] <= 1'b0;//WIP //WEL : write enable latch status_reg[1] <= 1'b0;//WEL chip_erase_oe = 1'b0; end
/*-------------------------------------------------------*/
/* Finite state machine to control Flash operation */ /*-------------------------------------------------------*/ always @( posedge SCLK or posedge CS ) begin if ( CS == 1'b1 ) begin // Chip Disable state <= #(tC-1) `STANDBY_STATE; SO_reg <= #tCLQV 1'bz; end
else begin // Chip Enable case ( state )
`STANDBY_STATE: begin SO_reg <= #tCLQV 1'bz; dummy_cycle( 6 );
state <= #(tC-1) `CMD_STATE; end
`CMD_STATE: begin //每8个SCLK进入`CMD_STATE一次 #1;
if ( si_reg[ 7:0 ] == WREN ) begin
//$display( $stime, \ write_enable;
//$display( $stime, \ state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == WRDI ) begin
//$display( $stime, \ write_disable;
//$display( $stime, \ state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == RDID ) begin
//$display( $stime, \ read_id;
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == RDSR ) begin
//$display( $stime, \ read_status ( status_reg );
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == WRSR ) begin
//$display( $stime, \ write_status;
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == READ ) begin
$display( $stime, \ dummy_cycle( 24 ); // to get 24 bits address read_data;
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == FASTREAD ) begin
//$display( $stime, \ dummy_cycle( 24 ); // to get 24 bits address fast_read_data;
//$display( $stime, \ state <= `STANDBY_STATE; end
//else if ( si_reg[ 7:0 ] == PARALLELMODE ) begin
// //$display( $stime, \ // parallel_mode;
// //$display( $stime, \ // state <= `STANDBY_STATE; //end
else if ( si_reg[ 7:0 ] == SE ) begin
//$display( $stime, \ dummy_cycle( 24 ); // to get 24 bits address sector_erase;
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == BE ) begin
//$display( $stime, \ dummy_cycle( 24 ); // to get 24 bits address block_erase;
//$display( $stime, \
state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == CE1 || si_reg[ 7:0 ] == CE2 ) begin //$display( $stime, \ chip_erase;
//$display( $stime, \ state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == PP ) begin
//$display( $stime, \ dummy_cycle( 24 ); // to get 24 bits address setup_addr( si_reg, segment_addr, offset_addr ); page_program( segment_addr, offset_addr ); update_array( segment_addr, offset_addr );
//$display( $stime, \ state <= `STANDBY_STATE; end
else if ( si_reg[ 7:0 ] == DP ) begin
//$display( $stime, \ deep_power_down;
//$display( $stime, \ state <= `STANDBY_STATE; end
//else if ( si_reg[ 7:0 ] == EN4K ) begin
// //$display( $stime, \ // enter_4kb_sector;
// //$display( $stime, \ // state <= `STANDBY_STATE;
Function ...\
Function ...\
Function ...\
Function ...\
//end //else if ( si_reg[ 7:0 ] == EX4K ) begin
// //$display( $stime, \ // exit_4kb_sector;
// //$display( $stime, \ // state <= `STANDBY_STATE; //end else if ( si_reg[ 7:0 ] == RDP || si_reg[ 7:0 ] == RES ) begin
//$display( $stime, \Enter Release from Deep Power Dwon release_from_deep_power_dwon;
//$display( $stime, \Leave Release from Deep Power Dwon state <= `STANDBY_STATE; end else if ( si_reg[ 7:0 ] == REMS ) begin
//$display( $stime, \Enter Read Electronic Manufacturer & ID dummy_cycle ( 16 ); // 2 dummy cycle dummy_cycle ( 8 ); // 1 AD
read_electronic_manufacturer_device_id;
//$display( $stime, \Leave Read Electronic Manufacturer & ID state <= `STANDBY_STATE; end
else begin
state <= #1 `BAD_CMD_STATE; end end `BAD_CMD_STATE: begin
//SO <= #tSHQZ 1'bz; SO_reg <= #tSHQZ 1'bz;
state <= #(tC-1) `BAD_CMD_STATE; end
default: begin
SO_reg <= #tAA 1'bx;
state <= #(tC-1) `STANDBY_STATE; end endcase
end // else begin
end // always @( posedge SCLK or posedge CS ) begin
////////////////////////////////////////////////////////////////////// // Module Task Declaration
//////////////////////////////////////////////////////////////////////
/*---------------------------------------------------------------*/
/* Description: define a wait dummy cycle task /* INPUT /* cnum: cycle number /*---------------------------------------------------------------*/ task dummy_cycle; input [31:0] cnum;
begin
repeat( cnum ) begin
@( posedge SCLK ); end end endtask
/*---------------------------------------------------------------*/
/* Description: setup segment address and offset address from /* 4-byte serial input. /* INPUT /* si: 4-byte serial input /* OUTPUT /* segment: segment address /* offset : offset address /*---------------------------------------------------------------*/ task setup_addr;
input [23:0] si;
output [13:0] segment; output [7:0] offset;
*/
*/ */ */
*/
*/ */
*/ */ */
begin #1;
{ offset[ 7:0 ] } = { si_reg[ 7:0 ] }; { segment[ 13:0 ] } = { si_reg[ 23:8 ] }; end endtask
/*---------------------------------------------------------------*/
/* Description: setup sector address */
/* INPUT */ /* si: 2-byte serial input */
/* OUTPUT */ /* sector: sector address */ /*---------------------------------------------------------------*/ task setup_sector; input [23:0] si;
output [`SECTOR_ADDR -1:0] sector; // A[`SECTOR_ADDR -1:16] defines a sector
begin #1;
{ sector[`SECTOR_ADDR -1:0 ] } = { si_reg[ 11:4 ] }; end endtask
/*---------------------------------------------------------------*/
/* Description: define a write enable task */ /*---------------------------------------------------------------*/ task write_enable; begin
//$display( $stime, \ forever begin
@( posedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode status_reg[1] = 1'b1;
//$display( $stime, \ if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0};
end
end
disable write_enable; //disable描述,退出forever end
else begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b0,1'b1,1'b0,1'b0};
end end end end end endtask
/*---------------------------------------------------------------*/
/* Description: define a write disable task (WRDI) */ /*---------------------------------------------------------------*/ task write_disable; begin
//$display( $stime, \
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end forever begin
@( posedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b0,1'b1,1'b0,1'b0};
=
=
=
=
end
status_reg[1] = 1'b0;
//$display( $stime, \ end
disable write_disable; end
else begin end end end endtask
/*---------------------------------------------------------------*/
/* Description: define a read id task (WRID) */ /*---------------------------------------------------------------*/ task read_id;
reg [ 23:0 ] dummy_ID; integer dummy_count; begin
dummy_ID = {ID_MXIC,8'h20,ID_Device}; dummy_count = 0; if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
forever begin
@( negedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b0,1'b1,1'b0,1'b0};
end
SO_reg <= #tCLQV 1'bz; //SO = #tCLQV 1'bz; end
disable read_id; end
= = else begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if ( pmode == 1'b0) begin // check parallel mode (2)
{ SO_reg, dummy_ID } <= #tCLQV { dummy_ID, dummy_ID[ 23 ] };
end
else begin
if ( dummy_count == 0 ) begin
SO_reg <= #tCLQV ID_MXIC; dummy_count = 1; end
else if ( dummy_count == 1 ) begin SO_reg <= #tCLQV 8'h00; dummy_count = 2; end
else if ( dummy_count == 2 ) begin SO_reg <= #tCLQV ID_Device; dummy_count = 0; end end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a read status task (WRSR) */ /*---------------------------------------------------------------*/ task read_status;
input [ 7:0 ] s_reg;
reg [ 7:0 ] dummy_reg; integer dummy_count; begin
dummy_reg = s_reg; dummy_count = 8;
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end
forever begin
@( negedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0};
end
SO_reg <= #tCLQV 1'bz; //SO = #tCLQV 1'bz; end
disable read_status; end
else begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if ( pmode == 1'b0 ) begin if (dummy_count) begin
{ SO_reg, dummy_reg } <= #tCLQV { dummy_reg, dummy_reg[ 7 ] };
dummy_count = dummy_count - 1; end
else begin
dummy_reg = s_reg;
{ SO_reg, dummy_reg } <= #tCLQV { dummy_reg, dummy_reg[ 7 ] };
dummy_count = 7; end end
else begin
SO_reg <= #tCLQV s_reg; end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a write status task */ /*---------------------------------------------------------------*/
task write_status;
integer dummy_count; begin
dummy_count=0;
//$display( $stime, \
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end forever begin
@( posedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
if ( !(wp_reg ==1'b0 && status_reg[7]==1'b1) ) begin // do work on not PM (2)
if ( status_reg[1] == 1'b1 ) begin //WEL:Write Enable Latch (3) if ( dummy_count == 8 ) begin
if( (status_reg[7] == si_reg[7] ) && (status_reg[5:2] == si_reg[5:2] )) begin
//WIP:Write Enable Latch status_reg[0] <= 1'b1;
status_reg[0] <= #tW_WEL 1'b0; //WEL:Write Enable Latch
status_reg[1] <= #tW_WEL 1'b0; end else begin
//SRWD:Status Register Write Protect status_reg[7] <= #tW_BP si_reg[7]; status_reg[5:2] <= #tW_BP si_reg[5:2]; //WIP:Write Enable Latch status_reg[0] <= 1'b1;
status_reg[0] <= #tW_BP 1'b0; //WEL:Write Enable Latch
status_reg[1] <= #tW_BP 1'b0;
end end
else begin
//WIP:Write Enable Latch status_reg[0] <= 1'b1;
status_reg[0] <= #tW_WIP 1'b0; //WEL:Write Enable Latch
status_reg[1] <= #tW_WEL 1'b0; end end
else begin // do not work on WEL = 1'b0 //WEL:Write Enable Latch
status_reg[1] <= #tW_WEL 1'b0; end end else begin
//WEL:Write Enable Latch status_reg[1] = 1'b0;
//$display( $stime, \ end end
disable write_status; end
else begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode dummy_count = dummy_count + 1; end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a read data task */ /*---------------------------------------------------------------*/
task read_data;
reg [`FLASH_ADDR - 1:0] rom_addr; // rom_addr = {segment, offset} integer dummy_count, tmp_int; reg [7:0] out_buf;
begin
dummy_count = 8;
rom_addr = si_reg[23:0]; addrspi = rom_addr; /////////////////////*****************************************
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b0,1'b1,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b0,1'b0,1'b1}; end
#1 out_buf = dataspi; /////////////////////ROM_ARRAY[ rom_addr ]; end
forever begin
@( negedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0};
end
SO_reg <= #tCLQV 1'bz; end
disable read_data; end
else if ( status_reg[0] == 1'b0 ) begin //WIP:write in rpocess bit = 0 (1)
if ( dpmode == 1'b0) begin //do work on non deep power down mode
if ( dummy_count ) begin
{ SO_reg, out_buf } <= #tCLQV { out_buf, out_buf[6] };
dummy_count = dummy_count - 1; end
else begin
rom_addr = rom_addr + 1; addrspi = rom_addr; /////////////////////*****************************************
#1 out_buf = dataspi; //////////////////// ROM_ARRAY[ rom_addr ];
{ SO_reg, out_buf } <= #tCLQV { out_buf, out_buf[6] };
dummy_count = 7 ; end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a fast read data task */
/* 0B AD1 AD2 AD3 X */ /*---------------------------------------------------------------*/ task fast_read_data;
reg [`FLASH_ADDR - 1:0] rom_addr; // rom_addr = {segment, offset} integer dummy_count, tmp_int; reg [7:0] out_buf; begin
dummy_count = 8;
rom_addr = si_reg[23:0];
if ( dpmode == 1'b0) begin //do work on non deep power down mode out_buf = ROM_ARRAY[ rom_addr ]; if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end
dummy_cycle( 8 ); forever begin
@( negedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode SO_reg <= #tCLQV 1'bz; if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b1,1'b0,1'b0,1'b0};
end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} {1'b0,1'b1,1'b0,1'b0};
end end
= = disable fast_read_data; end
else if ( status_reg[0] == 1'b0 ) begin //WIP:write in rpocess bit = 0 (1)
if ( dpmode == 1'b0) begin //do work on non deep power down mode
if ( dummy_count ) begin
{ SO_reg, out_buf } <= #tCLQV { out_buf, out_buf[6] };
dummy_count = dummy_count - 1; end
else begin
rom_addr = rom_addr + 1;
out_buf = ROM_ARRAY[ rom_addr ]; { SO_reg, out_buf } <= #tCLQV { out_buf, out_buf[6] };
dummy_count = 7 ; end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a parallel mode task */ /*---------------------------------------------------------------*/ // task parallel_mode; // begin
// @( posedge CS ); // if( CS == 1'b1 ) begin
// if ( dpmode == 1'b0) begin //do work on non deep power down mode // //$display( $stime, \// pmode = 1;
// {ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; // //$display( $stime, \// end // end // end // endtask //
/*---------------------------------------------------------------*/
/* Description: define a block erase task */
/* D8 AD1 AD2 AD3 */ /*---------------------------------------------------------------*/
task block_erase;
reg [`BLOCK_ADDR - 1:0] block; reg [15:0] offset; // 64K Byte
reg [`FLASH_ADDR - 1:0] rom_addr;
integer i, start_addr,end_addr,start_4kb_addr,end_4kb_addr; reg bp0; reg bp1; reg bp2; reg bp3; begin
block[`BLOCK_ADDR - 1:0] = si_reg[19:16]; offset = 16'h0;
start_addr = (si_reg[19:16]<<16) + 16'h0;
end_addr = (si_reg[19:16]<<16) + 16'hf;
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end forever begin
@( posedge CS );
if( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
if(wp_reg==1'b0||status_reg[7]==1'b1) begin // Protected Mode end
else if(dpmode == 1'b1) begin // deep power down mode end
else begin
if ( protected_area({block[`BLOCK_ADDR - 1:0],4'b0}) == 1'b1) begin
end
else if ( 16 <= block && block <=31 && bp2==1'b1 &&
bp1==1'b0 && bp0 ==1'b1) begin end
else begin
//WIP : write in process bit status_reg[0] = 1'b1;
for( i = start_addr; i < (end_addr+1); i = i + 1 ) begin
ROM_ARRAY[ i ] <= #`BLOCK_ERASE_TIME 8'hff;
end
//WIP : write in process bit
status_reg[0] <= #`BLOCK_ERASE_TIME 1'b0;//WIP //WEL : write enable latch
status_reg[1] <= #`BLOCK_ERASE_TIME 1'b0;//WEL end end end
disable block_erase; end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a sector erase task */
/* 20(D8) AD1 AD2 AD3 */ /*---------------------------------------------------------------*/ task sector_erase;
reg [`SECTOR_ADDR - 1:0] sector; reg [15:0] offset; // 64K Byte
reg [`FLASH_ADDR - 1:0] rom_addr;
integer i, start_addr,end_addr,start_4kb_addr,end_4kb_addr; reg bp0; reg bp1; reg bp2; reg bp3; begin
sector[`SECTOR_ADDR - 1:0] = si_reg[19:12]; offset = 12'h0;
start_addr = (si_reg[19:12]<<12) + 12'h000;
end_addr = (si_reg[19:12]<<12) + 12'hfff; start_4kb_addr = 9'h000;
end_4kb_addr = 9'h1ff;
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end end forever begin
@( posedge CS );
if( CS == 1'b1 ) begin
if ( dpmode == 1'b0) begin //do work on non deep power down mode if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
if(wp_reg==1'b0||status_reg[7]==1'b1) begin // Protected Mode end
else if(dpmode == 1'b1) begin // deep power down mode end
else begin
if ( protected_area(sector[`SECTOR_ADDR - 1:0]) == 1'b1) begin
end
else if ( 16 <= sector && sector <=31 && bp2==1'b1 && bp1==1'b0 && bp0 ==1'b1) begin end
else begin
//WIP : write in process bit status_reg[0] = 1'b1;
for( i = start_addr; i < (end_addr+1); i = i + 1 ) begin
ROM_ARRAY[ i ] <= #`SECTOR_ERASE_TIME 8'hff;
end
//WIP : write in process bit
status_reg[0] <= #`SECTOR_ERASE_TIME 1'b0;//WIP //WEL : write enable latch status_reg[1] <= #`SECTOR_ERASE_TIME
1'b0;//WEL
end end end
disable sector_erase; end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a chip erase task */
/* 60(C7) */ /*---------------------------------------------------------------*/ task chip_erase; integer i;
begin
forever begin
@( posedge CS );
if( CS == 1'b1 ) begin
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode
if ( wp_reg !=1'b0 && status_reg[7]!=1'b1 ) begin// protected mode
if ( status_reg[1] == 1'b1 ) begin //WEL:Write Enable Latch if ( status_reg[2] == 1'b0 && status_reg[3] == 1'b0 && status_reg[3] == 1'b0 ) begin
// WIP : write in process bit chip_erase_oe = 1'b1; status_reg[0] <= 1'b1;
//for( i = 0; i < FLASH_SIZE; i = i+1 ) //begin
// ROM_ARRAY[ i ] <= #`CHIP_ERASE_TIME 8'hff;
//end
////WIP : write in process bit
//status_reg[0] <= #`CHIP_ERASE_TIME 1'b0;//WIP
////WEL : write enable latch
//status_reg[1] <= #`CHIP_ERASE_TIME 1'b0;//WEL
end end end
end
disable chip_erase; end // CS == 1'b1 end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a page program task */
/* 02 AD1 AD2 AD3 */ /*---------------------------------------------------------------*/ task page_program;
input [12:0] segment; input [7:0] offset;
reg [`FLASH_ADDR - 1:0] rom_addr; // rom_addr = {segment, offset} integer dummy_count, tmp_int, i;
begin
dummy_count = 256; // page size
//offset[7:0] = 8'h00; // the start address of the page
rom_addr[`FLASH_ADDR - 1:0] = { segment[ 12:0 ],offset[7:0] };
/*------------------------------------------------*/
/* Store 256 bytes into a temp buffer - dummy_A */ /*------------------------------------------------*/ while ( dummy_count ) begin
rom_addr[`FLASH_ADDR - 1:0 ] = { segment[ 12:0 ], offset[ 7:0 ] }; dummy_count = dummy_count - 1;
tmp_int = dummy_count << 3; /* transfer byte to bit */ { dummy_A[ tmp_int+7 ], dummy_A[ tmp_int+6 ], dummy_A[ tmp_int+5 ], dummy_A[ tmp_int+4 ], dummy_A[ tmp_int+3 ], dummy_A[ tmp_int+2 ], dummy_A[ tmp_int+1 ], dummy_A[ tmp_int ] } = ROM_ARRAY[ rom_addr ];
offset = offset + 1; end
tmp_int = 0;
sector[`SECTOR_ADDR - 1:0] = rom_addr[`FLASH_ADDR - 1:12]; address[23:0] = si_reg[23:0]; if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end
else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; pp_p = #100 1'b1; end
forever begin
@( posedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode if ( status_reg[0] == 1'b0 ) begin //WIP
if ( wp_reg !=1'b0 && status_reg[7]!=1'b1 ) begin// protected mode
if ( status_reg[1] == 1'b1 ) begin //WEL:Write Enable Latch
if ( protected_area(sector[`SECTOR_ADDR - 1:0]) == 1'b0 ) begin // check protected area (3)
//$display( $stime, \Total write %d bits\tmp_int );
if ( pmode == 1'b0 ) begin
for( i = 1; i <= tmp_int; i=i+1 ) begin
if( dummy_A[ 256*8-i ] == 1'b1 ) begin // 1 -> 1 ,1 -> 0
dummy_A[ 256*8-i ] = si_reg[ tmp_int-i ];
end end end else begin
for( i = 1; i <= tmp_int; i=i+1 ) begin if( dummy_A[ 256*8-i ] == 1'b1 ) begin // 1 -> 1 ,1 -> 0
dummy_A[ 256*8-i ] = psi_reg[ tmp_int-i ];
end end
// for( i = 1; i <= tmp_int; i=i+8 ) begin
// if( dummy_A[ 256*8-i-0 ] == 1'b1 ) begin
// dummy_A[ 256*8-i-0 ] = psi_reg[ tmp_int-i-0 ];
// end
// if( dummy_A[ 256*8-i-1 ] == 1'b1 ) begin
// dummy_A[ 256*8-i-1 ] = psi_reg[ tmp_int-i-1 ];
// end
// if( dummy_A[ 256*8-i-2 ] == 1'b1 ) begin
// dummy_A[ 256*8-i-2 ] = psi_reg[ tmp_int-i-2 ];
// end
// if( dummy_A[ 256*8-i-3 ] == 1'b1 ) begin
psi_reg[ tmp_int-i-3 ];
1'b1 ) begin
psi_reg[ tmp_int-i-4 ];
1'b1 ) begin
psi_reg[ tmp_int-i-5 ];
1'b1 ) begin
psi_reg[ tmp_int-i-6 ];
1'b1 ) begin
psi_reg[ tmp_int-i-7 ];
{1'b1,1'b0,1'b0,1'b0};
// dummy_A[ 256*8-i-3 ] = // end
// if( dummy_A[ 256*8-i-4 ] == // dummy_A[ 256*8-i-4 ] = // end
// if( dummy_A[ 256*8-i-5 ] == // dummy_A[ 256*8-i-5 ] = // end
// if( dummy_A[ 256*8-i-6 ] == // dummy_A[ 256*8-i-6 ] = // end
// if( dummy_A[ 256*8-i-7 ] == // dummy_A[ 256*8-i-7 ] = // end // end end end end end
if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} =
{1'b0,1'b1,1'b0,1'b0};
end end end
pp_p = #90 1'b0;
disable page_program; end
else if (status_reg[0] == 1'b0)begin // count how many bits been shifted if ( dpmode == 1'b0 ) begin // do work on non deep power down mode if ( pmode == 1'b0 ) begin tmp_int = tmp_int + 1; end else begin
{ psi_reg[ 256*8-1:0 ] } = { psi_reg[ 256*8-2:0 ],latch_SO}; tmp_int = tmp_int + 8; end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a deep power down (DP) */ /*---------------------------------------------------------------*/ task deep_power_down; begin
//$display( $stime, \ if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
forever begin
@( posedge CS );
if( CS == 1'b1 ) begin
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode (1) if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
dpmode <= #tDP 1'b1;
//$display( $stime, \ end
disable deep_power_down; end
end // end forever end endtask
// /*---------------------------------------------------------------*/
// /* Description: define a enter 4kb sector task */ // /*---------------------------------------------------------------*/ // task enter_4kb_sector; // begin
// //$display( $stime, \// forever begin
// @( posedge CS );
// if( CS == 1'b1 ) begin
// if ( dpmode == 1'b0 ) begin // do work on non deep power down mode (1) // if (status_reg[0] == 1'b0) begin // WIP (2) // enter4kbmode = 1;
// //$display( $stime, \New Enter 4kb Sector Register = %b\enter4kbmode );
// disable enter_4kb_sector; // end // end // end
// end // end forever // end // endtask //
// /*---------------------------------------------------------------*/
// /* Description: define a exit 4kb sector task */ // /*---------------------------------------------------------------*/ // task exit_4kb_sector; // begin
// //$display( $stime, \// forever begin
// @( posedge CS );
// if( CS == 1'b1 ) begin
// if ( dpmode == 1'b0 ) begin // do work on non deep power down mode (1) // if (status_reg[0] == 1'b0) begin // WIP (2) // enter4kbmode = 0;
// //$display( $stime, \New Enter 4kb Sector Register = %b\
enter4kbmode );
// disable exit_4kb_sector; // end // end // end
// end // end forever // end // endtask //
/*---------------------------------------------------------------*/
/* Description: define a release from deep power dwon task (RDP)*/ /*---------------------------------------------------------------*/ task release_from_deep_power_dwon; begin
//$display( $stime, \ forever begin
@( posedge SCLK or posedge CS ); if( CS == 1'b1 ) begin
dpmode <= #tRES2 1'b0;
//$display( $stime, \ disable release_from_deep_power_dwon; end
else begin
//$display( $stime, \ dummy_cycle( 23 ); read_electronic_id;
//$display( $stime, \ disable release_from_deep_power_dwon; end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a read electronic ID (RES) */
/* AB X X X */ /*---------------------------------------------------------------*/ task read_electronic_id;
reg [ 7:0 ] dummy_ID; begin
//$display( $stime, \ if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end
else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
dummy_ID = ID_Device; forever begin
@( negedge SCLK or posedge CS ); if( CS == 1'b1 ) begin if (pmode == 0) begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b1,1'b0,1'b0,1'b0}; end else begin
{ENB_S0,ENB_P0,ENB_S1,ENB_P1} = {1'b0,1'b1,1'b0,1'b0}; end
{SO_reg,PO_reg6,PO_reg5,PO_reg4,PO_reg3,PO_reg2,PO_reg1,PO_reg0} <= #tCLQV {1'bz,1'bz,1'bz,1'bz,1'bz,1'bz,1'bz,1'bz}; dpmode <= #tRES2 1'b0;
//$display( $stime, \ disable read_electronic_id; end
else begin
if ( pmode == 1'b0 ) begin
{ SO_reg, dummy_ID } <= #tCLQV { dummy_ID, dummy_ID[ 7 ] };
end
else begin
SO_reg <= #tCLQV ID_Device; end end
end // end forever end endtask
/*-----------------------------------------------------------------*/
/* Description: define a read electronic manufacturer & device ID */ /*-----------------------------------------------------------------*/
task read_electronic_manufacturer_device_id; reg [ 15:0 ] dummy_ID; integer dummy_count; begin
//$width(negedge SCLK,1);
//$period( posedge SCLK, tCY ); // SCLK _/~ -> _/~ if ( si_reg[0]==1'b0 ) begin
dummy_ID = {ID_MXIC,ID_Device+1}; end
else begin
dummy_ID = {ID_Device,ID_MXIC}; end
dummy_count = 0; forever begin
@( negedge SCLK or posedge CS ); if ( CS == 1'b1 ) begin
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode SO_reg <= #tCLQV 1'bz; end
disable read_electronic_manufacturer_device_id; end
else begin
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode if ( pmode == 1'b0) begin // check parallel mode (2)
{ SO_reg, dummy_ID } <= #tCLQV { dummy_ID, dummy_ID[ 15 ] };
end else begin
if ( dummy_count == 0 ) begin
SO_reg = #tCLQV dummy_ID[15:8]; dummy_count = 1; end
else begin
SO_reg = #tCLQV dummy_ID[7:0]; dummy_count = 0; end end end end
end // end forever end endtask
/*---------------------------------------------------------------*/
/* Description: define a program chip task */
/* INPUT */ /* segment: segment address */ /* offset : offset address */ /*---------------------------------------------------------------*/ task update_array;
input [12:0] segment; input [7:0] offset;
reg [`FLASH_ADDR - 1:0] rom_addr; // rom_addr = {segment, offset} integer dummy_count, tmp_int;
reg [`SECTOR_ADDR - 1:0] sector; begin
dummy_count = 256;
/*------------------------------------------------*/
/* Store 256 bytes back to ROM Page */ /*------------------------------------------------*/
if ( dpmode == 1'b0 ) begin // do work on non deep power down mode (1) if (status_reg[0] == 1'b0) begin // WIP (2)
sector[`SECTOR_ADDR - 1:0] = rom_addr[`FLASH_ADDR - 1:12]; if ( wp_reg !=1'b0 || status_reg[7]!=1'b1 ) begin // protected mode (3) if ( status_reg[1] == 1'b1 ) begin // WEL:Write Enable Latch (4) if ( protected_area(sector[`SECTOR_ADDR - 1:0]) == 1'b0 ) begin // check protected area (5)
// initial start rom addrress offset = 8'h00;
rom_addr[`FLASH_ADDR - 1:0] = { segment[12:0], offset[7:0] };
// in write operation status_reg[0]<= 1'b1;
// not in write operation after PROG_TIME status_reg[0]<= #`PROG_TIME 1'b0; // WEL : write enable latch
status_reg[1]<= #`PROG_TIME 1'b0; while ( dummy_count ) begin
rom_addr[`FLASH_ADDR - 1:0] = { segment[12:0], offset[7:0] };
dummy_count = dummy_count - 1;
tmp_int = dummy_count << 3; /* byte to bit */ ROM_ARRAY[ rom_addr ] <= #`PROG_TIME { dummy_A[ tmp_int+7 ], dummy_A[ tmp_int+6 ],
dummy_A[ tmp_int+5 ], dummy_A[ tmp_int+4 ],
dummy_A[ tmp_int+3 ], dummy_A[ tmp_int+2 ],
dummy_A[ tmp_int+1 ], dummy_A[ tmp_int ] };
offset = offset + 1;
end
end // end protected area
end // end WEL:Write Enable Latch end end end end endtask
/*---------------------------------------------------------------*/
/* Description: define a protected_area area function */
/* INPUT */ /* sector : sector address */ /*---------------------------------------------------------------*/ function protected_area; input [7:0] sector; begin
`ifdef MX25L4005
if (status_reg[5:2]==4'b0000) begin protected_area = 1'b0; end
else if (status_reg[5:2]==4'b0001) begin
if (sector[`SECTOR_ADDR - 1:4] == 7) begin protected_area = 1'b1; end else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0010) begin
if (sector[`SECTOR_ADDR - 1:4] >= 6 && sector[`SECTOR_ADDR - 1:4] <= 7) begin
protected_area = 1'b1; end else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0011) begin
if (sector[`SECTOR_ADDR - 1:4] >= 4 && sector[`SECTOR_ADDR - 1:4] <= 7) begin
protected_area = 1'b1; end else begin
protected_area = 1'b0;
end end
else if (status_reg[5:2]==4'b0100) begin protected_area = 1'b1; end
else if (status_reg[5:2]==4'b0101) begin protected_area = 1'b1; end
else if (status_reg[5:2]==4'b0110) begin protected_area = 1'b1; end
else if (status_reg[5:2]==4'b0111) begin protected_area = 1'b1; end else begin
protected_area = 1'b1; end `else
`ifdef MX25L1605A
if (status_reg[5:2]==4'b0000) begin protected_area = 1'b0; end
else if (status_reg[5:2]==4'b0001) begin
if (sector[`SECTOR_ADDR - 1:4] == 31) begin protected_area = 1'b1; end else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0010) begin
if (sector[`SECTOR_ADDR - 1:4] >= 30 && sector[`SECTOR_ADDR - 1:4] <= 31) begin
protected_area = 1'b1; end else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0011) begin
if (sector[`SECTOR_ADDR - 1:4] >= 28 && sector[`SECTOR_ADDR - 1:4] <= 31) begin
protected_area = 1'b1; end
else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0100) begin
if (sector[`SECTOR_ADDR - 1:4] >= 24 && sector[`SECTOR_ADDR - 1:4] <= 31) begin
protected_area = 1'b1; end else begin
protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0101) begin if (sector[`SECTOR_ADDR - 1:4] >= 16 && sector[`SECTOR_ADDR - 1:4] <= 31) begin
protected_area = 1'b1; end else begin protected_area = 1'b0; end end
else if (status_reg[5:2]==4'b0110) begin protected_area = 1'b1; end
else if (status_reg[5:2]==4'b0111) begin protected_area = 1'b1; end else begin
protected_area = 1'b1; end `endif `endif end
endfunction
////////////////////////////////////////////////////////////////////// // AC Timing Check Section
////////////////////////////////////////////////////////////////////// specify
//====================================================== // AC Timing Parameter
//====================================================== specparam tCYC = 14, // Clock Cycle Time [ns]
tCH = 7, // Clock High Time (min) [ns] tCL = 7, // Clock Low Time (min) [ns]
tSLCH = 5, // CS Lead Clock Time (min) [ns] tCHSL = 5, // CS Lag Clock Time (min) [ns] tSHSL = 100, // CS High Time (min) [ns] tDVCH = 2, // SI Setup Time (min) [ns] tCHDX = 5; // SI Hold Time (min) [ns]
//====================================================== // Timing Check
//====================================================== $period( posedge SCLK , tCYC ); // SCLK _/~ -> _/~ $period( negedge SCLK , tCYC ); // SCLK ~\\_ -> ~\\_ $width ( posedge SCLK , tCH ); // SCLK _/~~\\_ $width ( negedge SCLK , tCL ); // SCLK ~\\__/~ $width ( posedge CS , tSHSL ); // CS _/~\\_
$setuphold( posedge SCLK &&& ~CS, SI, tDVCH, tCHDX ); $setup ( CS, posedge SCLK &&& ~CS, tSLCH ); $hold ( negedge SCLK &&& ~CS, CS, tCHSL );
endspecify endmodule
tCH = 7, // Clock High Time (min) [ns] tCL = 7, // Clock Low Time (min) [ns]
tSLCH = 5, // CS Lead Clock Time (min) [ns] tCHSL = 5, // CS Lag Clock Time (min) [ns] tSHSL = 100, // CS High Time (min) [ns] tDVCH = 2, // SI Setup Time (min) [ns] tCHDX = 5; // SI Hold Time (min) [ns]
//====================================================== // Timing Check
//====================================================== $period( posedge SCLK , tCYC ); // SCLK _/~ -> _/~ $period( negedge SCLK , tCYC ); // SCLK ~\\_ -> ~\\_ $width ( posedge SCLK , tCH ); // SCLK _/~~\\_ $width ( negedge SCLK , tCL ); // SCLK ~\\__/~ $width ( posedge CS , tSHSL ); // CS _/~\\_
$setuphold( posedge SCLK &&& ~CS, SI, tDVCH, tCHDX ); $setup ( CS, posedge SCLK &&& ~CS, tSLCH ); $hold ( negedge SCLK &&& ~CS, CS, tCHSL );
endspecify endmodule
正在阅读:
基于Verilog的mx25L1605A(Serial Flash)模型07-11
525心理活动策划08-07
吉林省城市建设管理条例12-27
2013-08-12《中关村科学城发展规划(2011-2015)》06-16
新人教版一年级语文下册期末复习教案01-08
学校学习宪法活动实施方案07-31
计算机 网络试卷复习题(及答案)10-11
政府经济学模拟试题(一)09-24
同学的绰号作文450字07-05
学术学位硕士研究生学位论文开题报告03-20
- 多层物业服务方案
- (审判实务)习惯法与少数民族地区民间纠纷解决问题(孙 潋)
- 人教版新课标六年级下册语文全册教案
- 词语打卡
- photoshop实习报告
- 钢结构设计原理综合测试2
- 2014年期末练习题
- 高中数学中的逆向思维解题方法探讨
- 名师原创 全国通用2014-2015学年高二寒假作业 政治(一)Word版
- 北航《建筑结构检测鉴定与加固》在线作业三
- XX县卫生监督所工程建设项目可行性研究报告
- 小学四年级观察作文经典评语
- 浅谈110KV变电站电气一次设计-程泉焱(1)
- 安全员考试题库
- 国家电网公司变电运维管理规定(试行)
- 义务教育课程标准稿征求意见提纲
- 教学秘书面试技巧
- 钢结构工程施工组织设计
- 水利工程概论论文
- 09届九年级数学第四次模拟试卷
- mx25L1605A
- 模型
- 基于
- Verilog
- Serial
- Flash
- 高进、精育、严管、优出 F大学辅导员队伍建设显成效
- 小学五年级英语阅读理解24篇
- 大学物理 - 第三版 - (下)答案 - 赵近芳
- 共青团干部队伍建设的调查与思考
- 小学一年级轻声词语
- 小英雄宋振中
- 冀教版小学英语五年级上册第3单元
- 计算机组成 数据的机器层次表示 练习题
- 数学文卷·2018届湖北省重点中学、齐鲁名校教科研协作体(临沂一
- 2009年普通高等学校招生统一考试安徽省理综卷
- PCBA外包加工技术质量协议书
- 注射用胸腺五肽说明书--瑞力能
- 轻钢结构建筑物的防雷及接地
- Bi3 —Fe3 混合溶液各组分含量的测定
- 南平市餐饮消费安全专项整治工作方案
- 大学英语精读1--第三版--课文英汉对照.
- POLYCOM视频会议系统解决方案-高清2012-01-04
- “十三五”重点项目-创意设计项目申请报告
- 结构化面试经典真题解析
- 高一数学必修三算法初步复习提纲+习题