📄 flashvhd.vhd
字号:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
entity flashvhd is
port(
glrn :in std_logic;--复位信号
fosc :in std_logic;--时钟信号
mode :in std_logic;--进入写模式使能信号
erase :in std_logic;--擦除使能信号
rb :in std_logic;--flash空闲/忙指示信号
request :in std_logic;--usb通讯请求信号
fifod :in std_logic_vector(7 downto 0);--fifo外部端口数据
flashd :in std_logic_vector(7 downto 0);--flash数据输出
addra :in std_logic_vector(10 downto 0);--fifo写指针
cle :out std_logic;--command latch enable(命令锁存使能信号)
ce :out std_logic;--chip enable(flash芯片使能信号)
we :out std_logic;--write enable(写使能信号)
ale :out std_logic;--address latch enable(地址锁存使能信号)
re :out std_logic;--read enable flash读使能信号
wp :out std_logic;--write protect(写保护使能信号)
bclk :out std_logic;--usb read clock
rdfifo :out std_logic;--读fifo信号
data :out std_logic_vector(7 downto 0);--falsh数据输入
usbd :out std_logic_Vector(7 downto 0);--外部usb数据读取通道
addrb :out std_logic_Vector(10 downto 0)--flash读取fifo指针
);
end flashvhd;
architecture Behavioral of flashvhd is
signal f_ale :std_logic;--ale signal
signal f_cle :std_logic;--cle signal
signal f_we :std_logic;--we signal
signal f_re :std_logic;--re signal
signal f_bclk :std_logic;--use read clock
signal clk_delay :std_logic_vector(3 downto 0);--usb数据读取时间
signal f_rb :std_logic;--flash的读信号
signal f_rdfifo :std_logic;--read fifo signal
signal f_addra :std_logic_vector(10 downto 0);--fifo 写指针
signal f_addrb :std_logic_vector(10 downto 0);--fifo 读指针
signal offset :std_logic_vector(10 downto 0);--fifo full/empty flag
signal f_rbcount :std_logic_vector(3 downto 0);--等待rb消抖的延迟时间
signal f_countbyte :std_logic_vector(10 downto 0);--one page bytes count
signal f_data :std_logic_Vector(7 downto 0);--data to the flash IO
signal f_countp :std_logic_vector(5 downto 0);--one block pages count
signal f_countb :std_logic_vector(9 downto 0);--one flash blocks count
signal rb_delay :std_logic_vector(3 downto 0);-- programe time delay(register to memorizer)
signal f_erase :std_logic;--erase signal
signal erase_count :std_logic_vector(11 downto 0);--erase block count
signal f_finish :std_logic;-- erase finish flag
signal f_rd :std_logic;--read signal
signal rd_count :std_logic_vector(4 downto 0);
signal d_request :std_logic;
signal f_request :std_logic;
signal request_count:std_logic_vector(2 downto 0);
signal f_usbd :std_logic_vector(7 downto 0);
type wr is(
wr0,wr1,wr2,wr3,wr4,wr5,wr6,wr7,wr8,wr9,wr10,wr11,
wr12,wr13,wr14,wr15,wr16,wr17,wr18,wr19,wr20,wr21,
wr22,wr23,wr24,wr25,wr26,wr27,wr28,wr29,wr30
);
signal w_state :wr;
type er is(
er0,er1,er2,er3,er4,er5,er6,er7,er8,er9,er10,er11,
er12,er13,er14,er15,er16,er17
);
signal e_state :er;
type rd is(
rd0,rd1,rd2,rd3,rd4,rd5,rd6,rd7,rd8,rd9,rd10,rd11,
rd12,rd13,rd14,rd15,rd16,rd17,rd18,rd19,rd20,rd21,
rd22,rd23,rd24,rd25,rd26,rd27,rd28
);
signal r_state :rd;
begin
wp <='1';--write protection disable
cle <=f_cle;
ale <=f_ale;
we <=f_we;
re <=f_re;
data <=f_data;
rdfifo <=f_rdfifo;
f_addra <=addra;
------------------------main process//write and read and erase flash---------------------
main:process(fosc,glrn,mode)
begin
if glrn='0' then
f_ale <='0';
f_cle <='0';
f_we <='0';
f_re <='0';
f_rdfifo <='0';
ce <='1';--'1' disable,'0' enable
f_addrb <="00000000000";--2k fifo address
f_countbyte <="00000000000";--2k byte
f_countp <="000000";--64 page
f_countb <="0000000000";--2k block
clk_delay <="0000";
f_finish <='0';
w_state <=wr0;
e_state <=er0;
r_state <=rd0;
elsif fosc'event and fosc='1' then
if mode='1' then --once start='0',can sample
ce<='0';
case w_state is
when wr0=>
f_cle<='1';
f_data<="10000000";--write 0x80H command
w_state<=wr1;
when wr1=>
f_we<='0';
w_state<=wr2;
when wr2=>
f_we<='1';
w_state<=wr3;
when wr3=> --write address f_ale always enable f_cle disable
f_ale<='1';
f_cle<='0';
f_data<="00000000";--write 0x00H address
w_state<=wr4;
when wr4=>
f_we<='0';
w_state<=wr5;
when wr5=>
f_we<='1';
w_state<=wr6;
when wr6=>
f_we<='0';
w_state<=wr7;
when wr7=>
f_we<='1';
w_state<=wr8;
when wr8=> --col address
f_data(5 downto 0)<=f_countp;
f_data(7 downto 6)<=f_countb(1 downto 0);
w_state<=wr9;
when wr9=>
f_we<='0';
w_state<=wr10;
when wr10=>
f_we<='1';
w_state<=wr11;
when wr11=> --row address
f_data<=f_countb(9 downto 2);
w_state<=wr12;
when wr12=>
f_we<='0';
w_state<=wr13;
when wr13=>
f_we<='1';
w_state<=wr14;
when wr14=> -- address write finish
f_ale<='0'; -- disable ale
w_state<=wr15;
when wr15=> --wait until the fifo is not empty
if offset="00000000000" then
w_state<=wr15;
else
f_rdfifo<='0';
w_state<=wr29;
end if;
when wr29=>
f_rdfifo<='1';--rising time read the fifio data
w_state<=wr30;
when wr30=>
f_data<=fifod;
w_state<=wr16;
when wr16=>
f_addrb<=f_addrb+1;
f_we<='0';
w_state<=wr17;
when wr17=>
f_we<='1';
f_countbyte<=f_countbyte+1;
w_state<=wr18;
when wr18=> -- one page is full then change the page address,else go on writing
if f_countbyte="00000000000" then
w_state<=wr19;
else
w_state<=wr15;
end if;
when wr19=>
f_cle<='1'; -- enable cle ready to write the command
f_data<="00010000"; --write 0x10H command to programe the whole page to the memorizer
w_state<=wr20;
when wr20=>
f_we<='0';
w_state<=wr21;
when wr21=>
f_we<='1';
w_state<=wr22;
when wr22=>
f_cle<='0';
rb_delay<="1111";
w_state<=wr23;
when wr23=> -- wait for 16*fosc clock cycle to programe the whole page data
rb_delay<=rb_delay-1;
w_state<=wr24;
when wr24=>
if rb_delay="0000" then
w_state<=wr25;
else
w_state<=wr23;
end if;
when wr25=>
if f_rb='1' then --f_rb programe ready signal,'1'ready,'0'busy
w_state<=wr26;
else
w_state<=wr25;
end if;
when wr26=>
f_countp<=f_countp+1;
w_state<=wr27;
when wr27=>
if f_countp="000000" then
f_countb<=f_countb+1;
end if;
w_state<=wr28;
when wr28=>
if f_countb="1111111111" then
w_state<=wr28;
else
w_state<=wr0;
end if;
when others=>
w_state<=wr0;
end case;
------------------------------erase part-------------------------------------------------
elsif f_erase='0' then
ce<='0';
case e_state is
when er0=>
f_cle<='0';
f_data<="01100000"; --write 0x60H command
e_state<=er1;
when er1=>
f_we<='0';
e_state<=er2;
when er2=>
f_we<='1';
e_state<=er3;
when er3=>
f_cle<='0';
f_ale<='1';
f_data(5 downto 0)<="000000";
f_data(7 downto 6)<=f_countb(1 downto 0);
e_state<=er4;
when er4=>
f_we<='0';
e_state<=er5;
when er5=>
f_we<='1';
e_state<=er6;
when er6=>
f_data<=f_countb(9 downto 2);
e_state<=er7;
when er7=>
f_we<='0';
e_state<=er8;
when er8=>
f_we<= '1';
e_state<=er9;
when er9=>
f_ale<='0';
f_cle<='1';
f_data<="11010000"; --write 0xd0H command
e_state<=er10;
when er10=>
f_we<='0';
e_state<=er11;
when er11=>
f_we<='1';
e_state<=er12;
when er12=>
f_cle<='0';
rb_delay<="1111";
e_state<=er13;
when er13=>
rb_delay<=rb_delay-1;
e_state<=er14;
when er14=>
if rb_delay="0000" then
e_state<=er15;
else
e_state<=er13;
end if;
when er15=>
if f_rb='1' then
e_state<=er16;
else
e_state<=er15;
end if;
when er16=>
f_countb<=f_countb+1;
e_state<=er17;
when er17=>
if f_countb="0000000000" then
f_finish<='1';
end if;
e_state<=er0;
when others=>
e_state<=er0;
end case;
-------------------------------------read part------------------------------------------
elsif f_rd='0' then
ce<='0';
case r_state is
when rd0=>
f_cle<='1';
f_data<="00000000"; --write 0x00H command
r_state<=rd1;
when rd1=>
f_we<='0';
r_state<=rd2;
when rd2=>
f_we<='1';
r_state<=rd3;
when rd3=>
f_cle<='0';
f_ale<='1';
f_data<="00000000"; --write 0x00H address
r_state<=rd4;
when rd4=>
f_we<='0';
r_state<=rd5;
when rd5=>
f_we<='1';
r_state<=rd6;
when rd6=>
f_we<='0';
r_state<=rd7;
when rd7=>
f_we<='1';
r_state<=rd8;
when rd8=> -- row address
f_data(5 downto 0)<=f_countp;
f_data(7 downto 6)<=f_countb(1 downto 0);
r_state<=rd9;
when rd9=>
f_we<='0';
r_state<=rd10;
when rd10=>
f_we<='1';
r_state<=rd11;
when rd11=>
f_data<=f_countb(9 downto 2);
r_state<=rd12;
when rd12=>
f_we<='0';
r_state<=rd13;
when rd13=>
f_we<='1';
r_state<=rd14;
when rd14=>
f_ale<='0';
f_cle<='1';
f_data<="00110000"; --write 0x30H command
r_state<=rd15;
when rd15=>
f_we<='0';
r_state<=rd16;
when rd16=>
f_we<='1';
r_state<=rd17;
when rd17=>
f_cle<='0';
rb_delay<="1111";
r_state<=rd18;
when rd18=>
rb_delay<=rb_delay-1;
r_state<=rd19;
when rd19=>
if rb_delay="0000" then
r_state<=rd20;
else
r_state<=rd18;
end if;
when rd20=>
if f_rb='1' then
r_state<=rd21;
else
r_state<=rd20;
end if;
when rd21=>
if f_request='1' then
r_state<=rd21;
else
f_re<='0';
r_state<=rd22;
end if;
when rd22=>
f_re<='1';
f_usbd<=flashd;
r_state<=rd23;
when rd23=>
clk_delay<=clk_delay+1;
r_state<=rd24;
when rd24=>
if clk_delay="0000" then
r_state<=rd25;
else
r_state<=rd23;
end if;
when rd25=>
f_countbyte<=f_countbyte+1;
r_state<=rd26;
when rd26=>
if f_countbyte="00000000000" then
r_state<=rd27;
else
r_state<=rd21;
end if;
when rd27=>
f_countp<=f_countp+1;
r_state<=rd28;
when rd28=>
if f_countp="000000" then
f_countb<=f_countb+1;
end if;
r_state<=rd0;
when others=>
r_state<=rd0;
end case;
end if;
end if;
end process main;
-------------------------------------xiao dou with erase signal---------------------------
p1:process(glrn,fosc,mode)
begin
if glrn='0' or mode='1' then
f_erase<='1';
erase_count<="000000000000"; --2k*fosc
elsif fosc 'event and fosc='1' then
if f_finish='1' then
f_erase<='1';
erase_count<="000000000000";
elsif erase='0' and erase_count(11)='0' then
f_erase<='1';
erase_count<=erase_count+1;
elsif erase='0' and erase_count(11)='1' then -- keep the value of the erase_count
f_erase<='0'; --enter erase mode
elsif erase='1' then
erase_count<="000000000000";-- when erase is high then xiaodou again
end if;
end if;
end process p1;
-----------------------------------produce enter read mode--------------------------------
p2:process(glrn,fosc,mode)
begin
if glrn='0' or mode='1' then
f_rd<='1';
rd_count<="00000";
elsif fosc'event and fosc='1' then
if d_request='0' and rd_count(4)='0' then
f_rd<='1';
rd_count<=rd_count+1;
elsif d_request='0' and rd_count(4)='1' then
f_rd<='0'; --enter read mode
end if;
end if;
end process p2;
----------------------------------xiao dou with request signal-----------------------------
p3:process(glrn,fosc,mode)
begin
if glrn='0' or mode='1' then
request_count<="000";
f_request<='1';
elsif fosc'event and fosc='1' then
if d_request='0' and request_count(2)='0' and f_request='1' then
f_request<='1';
request_count<=request_count+1;
elsif d_request='0' and request_count(2)='1'and f_request='1' then
f_request<='0';
request_count<="000";
elsif d_request='1' and request_count(2)='0'and f_request='0' then
f_request<='0';
request_count<=request_count+1;
elsif d_request='1' and request_count(2)='1'and f_request='0' then
f_request<='1';
request_count<="000";
else
request_count<="000";
end if;
end if;
end process p3;
-----------------------------------xiao dou with rb signal------------------------------
p4:process(glrn,fosc)
begin
if glrn='0' then
f_rbcount<="0000";
f_rb<='1';
elsif fosc'event and fosc='1' then
if rb='0' and f_rbcount(3)='0' and f_rb='1' then
f_rb<='1';
f_rbcount<=f_rbcount+1;
elsif rb='0' and f_rbcount(3)='1'and f_rb='1' then
f_rb<='0';
f_rbcount<="0000";
elsif rb='1' and f_rbcount(3)='0'and f_rb='0' then
f_rb<='0';
f_rbcount<=f_rbcount+1;
elsif rb='1' and f_rbcount(3)='1'and f_rb='0' then
f_rb<='1';
f_rbcount<="0000";
else
f_rbcount<="0000";
end if;
end if;
end process p4;
----------------------------------active clk send-----------------------------------------
----------------------------------usb read clock------------------------------------------
p5:process(glrn,fosc)
begin
if glrn='0' then
f_bclk<='1';
elsif fosc'event and fosc='1' then
if(clk_delay>=5) or (clk_Delay<=12) then
f_bclk<='0'; --f_bclk=20MHz/32=625KHz
else
f_bclk<='1';
end if;
end if;
end process p5;
---------------------------------address compare-----------------------------------------
offset<="00000000000"when(f_addra=f_addrb)
else(f_addra-f_addrb)when(f_addra>f_addrb)
else(2047+f_addra-f_addrb);
d_request<=request;
addrb<=f_addrb;
usbd<=f_usbd;
bclk<=f_bclk;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -