📄 at25320a.vhd
字号:
----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN IF Instruct = WRSR AND WEN = '1' AND not(WPEN = '1' AND WPNeg = '0') THEN -- can not execute if HPM is entered -- or if WEN bit is zero next_state <= WRITE_SR; ELSIF Instruct = PP AND WEN = '1' THEN blck := Address / 16#400#; IF Block_Prot(blck) = '0' THEN next_state <= PAGE_PG; END IF; ELSE next_state <= IDLE; END IF; END IF; WHEN WRITE_SR => IF rising_edge(WDONE) THEN next_state <= IDLE; END IF; WHEN PAGE_PG => IF rising_edge(WDONE) THEN next_state <= IDLE; END IF; END CASE;END PROCESS StateGen; --------------------------------------------------------------------------- --FSM Output generation and general funcionality --------------------------------------------------------------------------- Functional : PROCESS(write,read_out, WDONE, current_state, CSNeg_ipd, HOLDNeg_ipd, Instruct, Address, WByte, change_addr, WPNeg_ipd) TYPE WDataType IS ARRAY (0 TO 31) OF INTEGER RANGE -1 TO MaxData; VARIABLE WData : WDataType:= (OTHERS => 0); VARIABLE oe : boolean := FALSE; VARIABLE AddrLo : NATURAL; VARIABLE AddrHi : NATURAL; VARIABLE Addr : NATURAL; VARIABLE read_cnt : NATURAL; VARIABLE read_addr : NATURAL RANGE 0 TO AddrRANGE; VARIABLE data_out : std_logic_vector(7 downto 0); VARIABLE old_bit : std_logic_vector(7 downto 0); VARIABLE new_bit : std_logic_vector(7 downto 0); VARIABLE old_int : INTEGER RANGE -1 to MaxData; VARIABLE new_int : INTEGER RANGE -1 to MaxData; VARIABLE wr_cnt : NATURAL RANGE 0 TO 31; VARIABLE blck : NATURAL RANGE 0 TO BlockNum; VARIABLE BP : std_logic_vector(1 downto 0) := "00"; BEGIN ----------------------------------------------------------------------- -- Functionality Section ----------------------------------------------------------------------- oe := rising_edge(read_out); IF Instruct'EVENT THEN read_cnt := 0; END IF; IF rising_edge(change_addr) THEN read_addr := Address; END IF; CASE current_state IS WHEN IDLE => IF falling_edge(write) THEN read_cnt := 0; IF Instruct = WREN THEN WEN := '1'; ELSIF Instruct = WRDI THEN WEN := '0'; ELSIF Instruct = WRSR AND WEN = '1' AND not(WPEN = '1' AND WPNeg_ipd = '0') THEN -- can not execute if HPM is entered -- or if WEN bit is zero WSTART <= '1', '0' AFTER 1 ns; RDY := '1'; ELSIF Instruct = PP AND WEN = '1' THEN blck := Address / 16#400#; IF Block_Prot(blck) = '0' THEN WSTART <= '1', '0' AFTER 1 ns; RDY := '1'; Addr := Address; wr_cnt := Byte_number; FOR I IN wr_cnt DOWNTO 0 LOOP IF Viol /= '0' THEN WData(i) := -1; ELSE WData(i) := WByte(i); END IF; END LOOP; END IF; END IF; ELSIF oe THEN IF Instruct = RDSR THEN --Read Status Register SO_zd <= Status_reg(7-read_cnt); read_cnt := read_cnt + 1; IF read_cnt = 8 THEN read_cnt := 0; END IF; ELSIF Instruct = READ THEN --Read Memory array data_out := to_slv(Mem(read_addr),8); SO_zd <= data_out(7-read_cnt); read_cnt := read_cnt + 1; IF read_cnt = 8 THEN read_cnt := 0; IF read_addr = AddrRANGE THEN read_addr := 0; ELSE read_addr := read_addr + 1; END IF; END IF; END IF; END IF; WHEN WRITE_SR => IF oe AND Instruct = RDSR THEN SO_zd <= '1'; END IF; IF WDONE = '1' THEN RDY := '0'; WEN := '0'; WPEN := Status_reg_in(0);--MSB first BP1 := Status_reg_in(4); BP0 := Status_reg_in(5); Status_reg(6 downto 4) := "000"; BP := BP1 & BP0; CASE BP IS WHEN "00" => Block_Prot := (others => '0'); WHEN "01" => Block_Prot(3) := '1'; Block_Prot(2 downto 0) := "000"; WHEN "10" => Block_Prot(3 downto 2):= "11"; Block_Prot(1 downto 0) := "00"; WHEN others => Block_Prot := (others => '1'); END CASE; END IF; WHEN PAGE_PG => IF oe AND Instruct = RDSR THEN SO_zd <= '1'; END IF; ADDRHILO_PG(AddrLo, AddrHi, Addr); IF (Addr + wr_cnt) > AddrHi THEN wr_cnt := AddrHi - Addr; END IF; FOR I IN Addr TO Addr + wr_cnt LOOP Mem (i) := -1; END LOOP; IF WDONE = '1' THEN RDY := '0'; WEN := '0'; FOR I IN Addr TO Addr + wr_cnt LOOP Mem(i) := WData(i - Addr); END LOOP; END IF; END CASE; --Output Disable Control IF (CSNeg_ipd = '1') THEN SO_zd <= 'Z'; END IF;END PROCESS Functional; HOLD_FRAME_ON_SO_ZD : PROCESS( SO_zd, HOLDNeg_ipd) BEGIN IF (HOLDNeg_ipd = '0') THEN SO_z <= 'Z'; ELSE SO_z <= SO_zd; END IF; END PROCESS HOLD_FRAME_ON_SO_ZD; --------------------------------------------------------------------------- ---- File Read Section - Preload Control --------------------------------------------------------------------------- MemPreload : PROCESS -- text file input variables FILE mem_file : text is mem_file_name; VARIABLE ind : NATURAL := 0; VARIABLE buf : line; BEGIN --------------------------------------------------------------------------- --s25320a memory preload file format ----------------------------------- --------------------------------------------------------------------------- -- / - comment -- @aaaaaa - <aaa> stands for address -- dd - <dd> is byte to be written at Mem(aaa++) -- (aaa is incremented at every load) -- only first 1-7 columns are loaded. NO empty lines !!!!!!!!!!!!!!!! --------------------------------------------------------------------------- -- memory preload IF (mem_file_name /= "none" AND UserPreload) THEN ind := 0; Mem := (OTHERS => MaxData); WHILE (not ENDFILE (mem_file)) LOOP READLINE (mem_file, buf); IF buf(1) = '/' THEN NEXT; ELSIF buf(1) = '@' THEN ind := h(buf(2 to 4)); --address IF ind > AddrRANGE THEN ASSERT false REPORT "Given preload address is out of" & "memory address range" SEVERITY warning; END IF; ELSE IF ind <= AddrRANGE THEN Mem(ind) := h(buf(1 to 2)); END IF; IF ind < AddrRANGE THEN ind := ind + 1; END IF; END IF; END LOOP; END IF; WAIT; END PROCESS MemPreload; SO_OUT: PROCESS(SO_z) VARIABLE SO_GlitchData : VitalGlitchDataType; BEGIN VitalPathDelay01Z ( OutSignal => SO, OutSignalName => "SO", OutTemp => SO_z, GlitchData => SO_GlitchData, XOn => XOn, MsgOn => MsgOn, Paths => ( 0 => (InputChangeTime => SCK_ipd'LAST_EVENT, PathDelay => VitalExtendtofillDelay(tpd_SCK_SO), PathCondition => SO_z /= 'Z'), 1 => (InputChangeTime => CSNeg_ipd'LAST_EVENT, PathDelay => tpd_CSNeg_SO, PathCondition => CSNeg_ipd = '1'), 2 => (InputChangeTime => HOLDNeg_ipd'LAST_EVENT, PathDelay => tpd_HOLDNeg_SO, PathCondition => TRUE) ) ); END PROCESS SO_OUT; END BLOCK behavior;END vhdl_behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -