📄 pc104_spi.vhd
字号:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_signed.all;
entity spi_top is
port( clk, wr_n, rd_n, misoi : in std_logic;
irq, mosio, scko : out std_logic
addr : in std_logic_vector(9 downto 0);
data : inout std_logic_vector(7 downto 0);
rdy : in std_logic_vector(2 downto 0);
slv_sel : out std_logic_vector(2 downto 0));
end spi_top;
architecture spi of spi_top is
begin
data <= shift_reg when addr=SPIFT_ADDR and rd_n='0' else
stat_reg when addr=SPISR_ADDR and rd_n='0' else
"ZZZZZZZZ";
mosio <= shift_dataout when open_drain ='0' else 'Z';
sr_proc : process(clk)
begin
if(clk'event and clk='1')then
if(spi_go='1')then shift_reg<=data_reg;
elsif(shift_clk='1')then
shift_reg <= shift_reg(6 downto 0) & shift_datain;
end if;
end if;
end process;
neg_proc : process(clk)
begin
if (clk'event and clk='1') then
if (shift_clk_negedge='1') then
shift_negative_edge <= shift_negative_edge_nxt;
elsif (spi_go='1') then
shift_negative_edge <= shift_reg(7);
end if;
end if;
end process;
shift_negative_edge_nxt <= shift_reg(7) when phase='1' else misoi;
shift_dataout <= shift_negative_edge when phase='1' else shift_reg(7);
shift_datain <= shift_negative_edge when phase='0' else misoi;
tr_proc : process(clk)
begin
if (clk'event and clk='1') then
if (tx_start='1') then tx_run <= '1';
elsif (tx_end='1') then tx_run <= '0';
end if;
end if;
end process;
bc_proc : process(clk)
begin
if (clk'event and clk='1') then
if (tx_start='1') then bit_ctr <= bit_counter;
elsif (shift_clk='1') then bit_ctr <= bit_ctr-1;
end if;
end if;
end process;
tx_end <= '1' when bit_ctr=001 and shift_clk='1' and tx_run='1' else '0';
tx_start <= '1' when spi_go='1' else '0';
elr_proc : process(clk)
begin
if (clk'event and clk='1') then
if (tx_end ='1')then irq_flag <='1';
elsif (tx_run='1')then irq_flag <='0';
end if;
end if;
end process;
dvd_proc : process(clk)
begin
if (clk'event and clk='1') then
if (not (tx_run='1' ) or tx_end='1') then
dvd_ctr <= "00000", dvd2 <= '0';
else
if (dvd_ctr=00000) then dvd_ctr <= clock_div;
if(tx_start_r1 ='0')then dvd2 <= not dvd2;
end if;
else dvd_ctr <= dvd_ctr-1;
end if;
end if;
end if;
end process;
dvd_zero <= '1' when dvd_ctr=00000 else '0';
shift_clk <= dvd_zero and dvd2 and tx_run and not tx_start_r1;
shift_clk_negedge <= dvd_zero and not dvd2 and tx_run;
scko <= dvd2 xor polck;
wr_data : process(wr_n,tx_run)
begin
if(tx_run='1')then spi_go<='0';
elsif (wr_n'event and wr_n='1' ) then
if( addr=spift_addr) then
data_reg <= data, spi_go <='1';
end if;
end if;
end process;
wr_ctl : process(wr_n)
begin
if (wr_n'event and wr_n='1') then
if addr=spic_addr then ctl_reg <= data;
end if;
end if;
end process;
slv_sel(2 downto 0)<= ctl_reg(2 downto 0);
irq_en <= ctl_reg(7), open_drain <= ctl_reg(6);
phase <= ctl_reg(5), polck <= ctl_reg(4);
irq <= irq_flag and ctl_reg(7);
stat_proc:process(rdy,irq_flag)
begin
stat_reg <= irq_flag & "0000" & rdy(2 downto 0);
end process;
end spi;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -