📄 lpt.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;
-- 5. Pin signals and register bits--<= in DB25 Cent Name of Reg--=> out pin pin Signal Bit Function Notes------ ---- ---- -------- --- -------------------------------=> 1 1 -Strobe C0- Set Low pulse >0.5 us to send--=> 2 2 Data 0 D0 Set to least significant data--=> 3 3 Data 1 D1 ...--=> 4 4 Data 2 D2 ...--=> 5 5 Data 3 D3 ...--=> 6 6 Data 4 D4 ...--=> 7 7 Data 5 D5 ...--=> 8 8 Data 6 D6 ...--=> 9 9 Data 7 D7 Set to most significant data--<= 10 10 -Ack S6+ IRQ Low Pulse ~ 5 uS, after accept--<= 11 11 +Busy S7- High for Busy/Offline/Error--<= 12 12 +PaperEnd S5+ High for out of paper--<= 13 13 +SelectIn S4+ High for printer selected--=> 14 14 -AutoFd C1- Set Low to autofeed one line--<= 15 32 -Error S3+ Low for Error/Offline/PaperEnd--=> 16 31 -Init C2+ Set Low pulse > 50uS to init--=> 17 36 -Select C3- Set Low to select printer--== 18-25 19-30, Ground-- 33,17,16-- Printer port registers--Register Name Address--Data Register Base + 0x00--Status Register Base + 0x01--Control Register Base + 0x02--Data Register Bit Definitions--Bit Function Low High--7(MSB) D7 0 1 GPC7--6 D6 0 1 GPC6--5 D5 0 1 GPC5--4 D4 0 1 GPC4--3 D3 0 1 GPC3--2 D2 0 1 GPC2--1 D1 0 1 GPC1--0(LSB) D0 0 1 GPC0--Status Register Bit Definitions--Bit Function Low High--7(MSB) Busy Busy Not Busy WBUSY GPC9--6 Acknowledge Nack Ack nACK GPG3--5 Paper Status No Paper Paper WPE GPC10--4 Selection Status Not Selected Selected --3 Error Status No Error Error nERR GPC11--2 Not Used - ---1 Not Used - ---0(LSB) Not Used - -----Control Register Bit Definitions--Bit Function Low High--7(MSB) Not Used - ---6 Not Used - ---5 Not Used - ---4 Interrupt Control Interrupts Interrupts-- Disabled Enabled--3 Select Selected Not Selected--2 Initialize False True--1 Auto Feed True False--0(LSB) Strobe(Active-Low) True False _WSTB GPC8
-- VHDL: open-drain output dout <= 'Z' when din='1' else '0';
entity top is
Port ( clk,rst : in std_logic;
-- CPU interface
addr : in std_logic_vector(11 downto 1);
data : inout std_logic_vector(7 downto 0);
ion : inout std_logic_vector(5 downto 0);
ncs,nwe,noe : in std_logic;
-- LPT interface
wpd : out std_logic_vector(7 downto 0);
nerr,nack,wbusy,wpe : in std_logic;
wstb : out std_logic;
-- FPGA configure interface
dclk,data0,ncfg : out std_logic;
nstatus,cfg_done : in std_logic;
-- password interface
pwd_do : out std_logic;
pwd_clk,pwd_di,pwd_rst : in std_logic
);
end top;
architecture Behavioral of top is
signal count:std_logic_vector(4 downto 0);
signal word:std_logic_vector(18 downto 0);
signal fpga_data ,buf:std_logic_vector(7 downto 0);
signal twpd : std_logic_vector(7 downto 0);
signal twstb : std_logic;
signal freq : std_logic_vector(4 downto 0);
signal t_dclk,l_dclk : std_logic;
signal start_data,end_data : std_logic;
signal data_cnt,dclk_low : std_logic_vector(3 downto 0);
begin
cpu:process(clk,rst)
begin
if rst = '0' then
data(7 downto 0) <= (others => 'Z');
twpd(7 downto 0) <= (others => '0');
wstb <= '0';
start_data <= '0';
elsif rising_edge(clk) then
if end_data = '1' then
start_data <= '0';
end if;
if ncs = '0' and noe = '0' then
case addr(11 downto 1) is
when "00000000000" => -- 0x000 read fpga_data
data <= fpga_data;
when "00000000001" => -- 0x000 read LPT data port
data <= twpd;
when "00000000010" => -- 0x000 read LPT status port XC9572XL tolerant 5V
data <= wbusy & nack & wpe & "0" & nerr & "000";
when "00000000011" => -- 0x000 read LPT control port
data <= "0000000" & twstb;
when "00000000100" => -- 0x000 read io port
data <= "00" & ion;
when "00000000101" => -- 0x000 read fpga configure status
data <= "000000" & nstatus & cfg_done;
when others =>
data <= (others => '0');
end case;
elsif ncs = '0' and nwe = '0' then
case addr(11 downto 1) is
when "00000000000"=> -- 0x000 fpga_data
fpga_data <= data;
start_data <= '1';
when "00000000001" => -- 0x000 write LPT data port
-- wpd <= data;
-- for open-drain output
if data(0) = '1' then wpd(0) <= 'Z'; else wpd(0) <= '0'; end if;
if data(1) = '1' then wpd(1) <= 'Z'; else wpd(1) <= '0'; end if;
if data(2) = '1' then wpd(2) <= 'Z'; else wpd(2) <= '0'; end if;
if data(3) = '1' then wpd(3) <= 'Z'; else wpd(3) <= '0'; end if;
if data(4) = '1' then wpd(4) <= 'Z'; else wpd(4) <= '0'; end if;
if data(5) = '1' then wpd(5) <= 'Z'; else wpd(5) <= '0'; end if;
if data(6) = '1' then wpd(6) <= 'Z'; else wpd(6) <= '0'; end if;
if data(7) = '1' then wpd(7) <= 'Z'; else wpd(7) <= '0'; end if;
when "00000000010" => -- 0x000 write LPT status port
null;
when "00000000011" => -- 0x000 write LPT control port
-- wstb <= data(0);
twstb <= data(0);
-- for open-drain output
if data(0) = '1' then wstb <= 'Z'; else wstb <= '0'; end if;
when "00000000100" => -- 0x000 write io port
ion <= data(5 downto 0);
when "00000000101" => -- 0x000 set configure pin to 1
-- if data(2) = '1' then
-- dclk <= '1';
-- end if;
-- if data(1) = '1' then
-- data0 <= '1';
-- end if;
if data(1) = '1' then
ncfg <= '1';
end if;
when "00000000110" => -- 0x000 set configure pin to 0
-- if data(2) = '1' then
-- dclk <= '0';
-- end if;
-- if data(1) = '1' then
-- data0 <= '0';
-- end if;
if data(1) = '1' then
ncfg <= '0';
end if;
when others =>
data <= (others => '0');
end case;
else
data <= (others => 'Z');
end if;
end if;
end process;
devider:process(rst,clk)
begin
if rst = '0' then
freq <= (others => '0');
elsif rising_edge(clk) then
freq <= freq + 1;
if freq = 12 then
freq <= (others => '0');
end if;
end if;
end process;
shift:process(rst,clk)
begin
if rst = '0' then
dclk <= '0';
data0 <= '0';
t_dclk <= '0';
l_dclk <= '0';
end_data <= '0';
data_cnt <= "0000";
dclk_low <= "0000";
elsif rising_edge(clk) then
if start_data = '1' then
if freq = 11 then
t_dclk <= not t_dclk;
end if;
l_dclk <= t_dclk;
dclk <= t_dclk;
if l_dclk = '0' and t_dclk = '1' then
data0 <= fpga_data(0);
fpga_data <= fpga_data(0) & fpga_data(7 downto 1);
data_cnt <= data_cnt + 1;
end if;
if t_dclk = '1' then
dclk_low <= "0000";
else
dclk_low <= dclk_low + 1;
end if;
if dclk_low = 9 and data_cnt = 8 then
end_data <= '1';
end if;
else
data_cnt <= "0000";
end if;
if end_data = '1' then
end_data <= '0';
end if;
end if;
end process;
end Behavioral;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -