Понемногу изучаю vhdl, и выложу некоторые наработки, если вдруг есть знатоки, вносите коррективы, только рад.
Подключение PSX-контроллера в режиме digital или RED-mode
- Код: Выделить всё • Развернуть
-- PSX_Ctrl.vhd
-- Play Station Controller digital and analog Red Mode
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
Entity PSX_Ctrl is
port(
Clk : in std_logic; -- System Clock 50 MHz
PSX_Data : in std_logic; -- Data from Pad
PSX_cmd : out std_logic; -- Commands to Pad
PSX_ATT : out std_logic; -- Signal Attention to Pad
PSX_Clk : out std_logic; -- Clock to pad
PSX_ACK : in std_logic; -- ACK
PSX_OK : out std_logic; -- Pad connected
PSX_Red : out std_logic; -- Pad in RED Mode
-- Bit0 Bit1 Bit2 Bit3 Bit4 Bit5 Bit6 Bit7
Buttons1 : out std_logic_vector (7 downto 0); -- SLCT JOYR JOYL STRT UP RGHT DOWN LEFT
Buttons2 : out std_logic_vector (7 downto 0); -- L2 R2 L1 R1 /\ O X |_|
Rjoy_X : out std_logic_vector (7 downto 0); -- Right Joy 0x00 = Left 0xFF = Right
Rjoy_Y : out std_logic_vector (7 downto 0); -- Right Joy 0x00 = Up 0xFF = Down
Ljoy_X : out std_logic_vector (7 downto 0); -- Left Joy 0x00 = Left 0xFF = Right
Ljoy_Y : out std_logic_vector (7 downto 0) -- Left Joy 0x00 = Up 0xFF = Down
);
end PSX_Ctrl;
Architecture ARCH of PSX_Ctrl is
constant ClkDiv: integer := 100; -- 250kHz 50000000/250000/2
constant int_div: integer :=5000; -- 50Hz 250000/5000
constant Att_div01: integer :=4;
constant Att_div02: integer :=Att_div01+9;
constant Att_div03: integer :=Att_div02+6;
constant Att_div04: integer :=Att_div03+9;
constant Att_div05: integer :=Att_div04+6;
constant Att_div06: integer :=Att_div05+9;
constant Att_div07: integer :=Att_div06+5;
constant Att_div08: integer :=Att_div07+9;
constant Att_div09: integer :=Att_div08+5;
constant Att_div10: integer :=Att_div09+9;
constant Att_div11: integer :=Att_div10+5;
constant Att_div12: integer :=Att_div11+9;
constant Att_div13: integer :=Att_div12+5;
constant Att_div14: integer :=Att_div13+9;
constant Att_div15: integer :=Att_div14+5;
constant Att_div16: integer :=Att_div15+9;
constant Att_div17: integer :=Att_div16+5;
constant Att_div18: integer :=Att_div17+9;
constant Att_div: integer :=Att_div18+4;
constant Data_init: std_logic_vector (7 downto 0) := "00000001";
constant Data_secd: std_logic_vector (7 downto 0) := "01000010";
signal ClkCount: std_logic_vector (7 downto 0) := (others => '0');
signal intrCount: std_logic_vector (15 downto 0) := (others => '0');
signal ClkTick: std_logic := '0';
signal Clk_en: std_logic :='1';
signal Clk_s: std_logic :='1';
signal ATT_s: std_logic :='1';
signal CMD_s: std_logic :='1';
signal PSX_OK_s: std_logic :='0';
signal PSX_RED_s: std_logic :='0';
signal Att_count: std_logic_vector (7 downto 0) := (others => '0');
signal Data_in : std_logic_vector (7 downto 0) := "00000000";
signal byte_1 : std_logic_vector (7 downto 0) := "00000000";
signal byte_2 : std_logic_vector (7 downto 0) := "00000000";
signal byte_3 : std_logic_vector (7 downto 0) := "00000000";
signal byte_4 : std_logic_vector (7 downto 0) := "00000000";
signal byte_5 : std_logic_vector (7 downto 0) := "00000000";
signal byte_6 : std_logic_vector (7 downto 0) := "00000000";
signal step_byte: integer range 0 to 7 :=0;
signal Dcount: integer range 0 to 7 :=0;
begin
PSX_ATT<=ATT_s;
PSX_Clk<=not(Clk_s and Clktick);
PSX_cmd<=CMD_s;
PSX_OK<=PSX_OK_s;
PSX_RED<=PSX_RED_s;
a: process (Clk)
begin
if Clk='1' and Clk'event then
if ClkCount = ClkDiv then
ClkTick <= Not Clktick;
ClkCount <= (others => '0');
else
ClkCount <= ClkCount + 1;
end if;
end if;
end process;
b: process (clkTick)
begin
if ClkTick='1' and ClkTick'event then
if intrcount <=Att_div then
Att_s <='0';
else
Att_s <='1';
end if;
if intrcount >att_div01 and intrcount <att_div02 then
Clk_s <='1';
Cmd_s <=data_init(Dcount);
Dcount <=Dcount+1;
else
--1
if intrcount >att_div03 and intrcount <att_div04 then
Clk_s <='1';
Cmd_s <=data_secd(Dcount);
Dcount <=Dcount+1;
else
--2
if intrcount >att_div05 and intrcount <att_div06 then
Clk_s <='1';
Cmd_s <='0';
else
--3
if intrcount >att_div07 and intrcount <att_div08 then
Clk_s <='1';
Cmd_s <='0';
else
--4
if intrcount >att_div09 and intrcount <att_div10 then
Clk_s <='1';
Cmd_s <='0';
else
--5
if intrcount >att_div11 and intrcount <att_div12 then
Clk_s <='1';
Cmd_s <='0';
else
--6
if intrcount >att_div13 and intrcount <att_div14 then
Clk_s <='1';
Cmd_s <='0';
else
--7
if intrcount >att_div15 and intrcount <att_div16 then
Clk_s <='1';
Cmd_s <='0';
else
--8
if intrcount >att_div17 and intrcount <att_div18 then
Clk_s <='1';
Cmd_s <='0';
else
Cmd_s <='1';
Clk_s <='0';
end if;
--8
end if;
--7
end if;
--6
end if;
--5
end if;
--4
end if;
--3
end if;
--2
end if;
--1
end if;
if intrcount =int_div then
intrcount <=(others => '0');
else
intrcount <= intrcount+1;
end if;
end if;
end process;
C: process (clkTick)
begin
if ClkTick='1' and ClkTick'event then
--1
if intrcount >att_div03+1 and intrcount <att_div04+1 then
data_in(step_byte)<=PSX_data;
step_byte <=step_byte+1;
else
--2
if intrcount >att_div05+1 and intrcount <att_div06+1 then
step_byte <=step_byte+1;
else
--3
if intrcount >att_div07+1 and intrcount <att_div08+1 then
byte_1(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
--4
if intrcount >att_div09+1 and intrcount <att_div10+1 then
byte_2(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
--5
if intrcount >att_div11+1 and intrcount <att_div12+1 then
byte_3(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
--6
if intrcount >att_div13+1 and intrcount <att_div14+1 then
byte_4(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
--7
if intrcount >att_div15+1 and intrcount <att_div16+1 then
byte_5(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
--8
if intrcount >att_div17+1 and intrcount <att_div17+1 then
byte_6(step_byte)<=not PSX_data;
step_byte <=step_byte+1;
else
step_byte <=0;
Buttons1 <=byte_1;
Buttons2 <=byte_2;
Rjoy_X <=byte_3;
Rjoy_Y <=byte_4;
Ljoy_X <=byte_5;
Ljoy_Y <=byte_6;
if Data_in="01000001" then
PSX_OK_s <='1';
PSX_RED_s <='0';
else
if Data_in="01110011" then
PSX_OK_s <='1';
PSX_RED_s <='1';
else
PSX_OK_s <='0';
PSX_RED_s <='0';
end if;
end if;
end if;
--8
end if;
--7
end if;
--6
end if;
--5
end if;
--4
end if;
--3
end if;
--2
end if;
--1
end if;
end process;
end ARCH;
Сигнал PSX_ACK не используется ввиду особой ненадобности, поэтому можно удалить.
Добавлено спустя 8 минут 40 секунд:
Servo driver
входы
Clk - 50MHz
Enable - включение/выключение выхода
Position - 8 бит значение (128 середина соответственно)
- Код: Выделить всё • Развернуть
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity ServoDriver is
Port (
Clk : in STD_LOGIC; -- 50MHz
Enable: in STD_LOGIC;
Position : in STD_LOGIC_VECTOR (7 downto 0);
Servo : out STD_LOGIC
);
end ServoDriver;
architecture Behavioral of ServoDriver is
constant ClockDiv: integer := 273;
signal ClockTick: std_logic := '0';
signal ClockCount: std_logic_vector (8 downto 0) := (others => '0');
signal PulseCount: std_logic_vector (11 downto 0) := (others => '0');
begin
a: process (Clk)
begin
if Clk='1' and Clk'event then
if ClockCount = ClockDiv-2 then
ClockTick <= '1';
else
ClockTick <= '0';
end if;
if ClockTick='1' then
ClockCount <= (others => '0');
else
ClockCount <= ClockCount + 1;
end if;
end if;
end process;
b: process (Clk)
begin
if Clk='1' and Clk'event then
if ClockTick='1' then
PulseCount <= PulseCount + 1;
end if;
if PulseCount < ("0000" & Position+148) then
Servo <= '1' and Enable;
else
Servo <= '0';
end if;
end if;
end process;
end Behavioral;
Добавлено спустя 4 минуты 55 секунд:
UART
Этот код позаимствовал где-то в открытом доступе.
- Код: Выделить всё • Развернуть
----------------------------------------------------------------------
-- UART
-- Ver. 1.0 - 18.06.2004
-- Initial release
--
--
-----------------------------------------------------------------------
library ieee;
use ieee.Std_Logic_1164.all;
use IEEE.STD_LOGIC_UNSIGNED.all;
entity UART1 is
port (
CLK : in Std_Logic; -- system clk
RST_N : in Std_Logic; -- system reset#
DataIN : in Std_Logic_Vector(7 downto 0); -- Data to transmit
DataOUT : out Std_Logic_Vector(7 downto 0); -- Recieved data
RX_READY : out Std_Logic; -- RX buffer data ready
TX_INT : in Std_Logic; -- Data for TX avaible
TX_RD : out Std_Logic; -- Data for TX RD
RxD : in Std_Logic; -- RX pin
TxD : out Std_Logic -- TX pin
);
end UART1;
-----------------------------------------------------------------------
-- Architecture for UARTv1
-----------------------------------------------------------------------
architecture UARTArc of UART1 is
-- UART signals
signal RxClk, TxClk: Std_Logic;
signal TxBuf: Std_Logic_Vector(7 downto 0); -- transmit buffer
--signal TxBufLoad: Std_Logic;
signal TxBufEmpty: Std_Logic;
signal Start: Std_Logic; -- syncro signal (start bit)
signal RxBuf: Std_Logic_Vector(7 downto 0); -- recieve buffer
signal tmpRxD: Std_Logic; -- RxD buffer register
signal RxReady: Std_Logic;
signal TXRead: Std_Logic;
--signal FrameErr: Std_Logic;
--signal DataErr: Std_Logic;
begin
------------------------------------------------------------------
-- UART implementation
-- parameters:
-- format - 1 start bit, 8 data bit, 1 stop bit
------------------------------------------------------------------
UART_clk: process(CLK, RST_N)
variable CntRX: integer range 0 to 27; -- RX: 115200 BOD Rx (50MHZ_CLK/Speed_BOD/16_Samples)
variable CntTX: integer range 0 to 434; -- TX: 115200 BOD Tx (50MHz_CLK/Speed_BOD)
begin
if RST_N='0' then
RxClk<='0';
TxClk<='0';
CntRX:=0;
CntTX:=0;
else
if CLK'event and CLK='1' then
CntRX:=CntRX+1;
case CntRX is
when 27 =>
RxClk<='1';
CntRX:=0;
when others =>
RxClk<='0';
end case;
CntTX:=CntTX+1;
case CntTX is
when 434 =>
TxClk<='1';
CntTX:=0;
when others =>
TxClk<='0';
end case;
end if;
end if;
end process UART_clk;
UART_Tx: process(CLK, RST_N, TxClk, TxBufEmpty, TX_INT, TXRead)
variable TxBitCnt: integer range 0 to 9;
begin
if RST_N='0' then
TxD<='1';
TxBitCnt:=0;
TxBuf<=(others=>'0');
TxBufEmpty<='1';
TXRead<='0';
else
if (CLK'event and CLK='1') then
if TXRead='1' then
TXRead<='0';
end if;
if (TxBufEmpty='1' and TX_INT='1') then
TXRead<='1';
TxBuf(7 downto 0)<=DataIN(7 downto 0);
TxBufEmpty<='0';
end if;
if (TxClk='1' and TxBufEmpty='0') then
case TxBitCnt is
when 0 =>
TxD<='0'; -- start bit
TxBitCnt:=TxBitCnt+1;
when 1|2|3|4|5|6|7|8 =>
TxD<= TxBuf(0);
TxBuf<='1' & TxBuf(7 downto 1);
TxBitCnt:=TxBitCnt+1;
when 9 =>
TxD<='1'; -- stop bit
TxBuf<='1' & TxBuf(7 downto 1);
TxBitCnt:=0;
TxBufEmpty<='1';
end case;
end if;
end if;
end if;
end process UART_Tx;
UART_Rx: process(CLK, RST_N, RxClk, RxD)
variable RxBitCnt: integer range 0 to 10;
variable RxSampleCnt: integer range 0 to 15;
begin
if RST_N='0' then
RxBitCnt:=0;
RxSampleCnt:=0;
Start<='0';
RxBuf<=(others=>'1');
RxReady<='0';
tmpRxD<='1';
else
if (CLK'event and CLK='1') then
if RxReady='1' then
RxReady<='0';
end if;
if RxClk='1' then
if Start='0' then
if RxD='0' then -- Start bit,
RxSampleCnt:=1;
RxBitCnt:=0;
Start<='1';
end if;
else
case RxSampleCnt is
when 8 => -- reads the RxD line
tmpRxD<=RxD;
RxSampleCnt:=RxSampleCnt+1;
when 15 =>
RxSampleCnt:=0;
case RxBitCnt is
when 0 =>
if tmpRxD='1' then -- start bit failed
Start<='0';
else
RxBitCnt:=RxBitCnt+1;
end if;
RxSampleCnt:=RxSampleCnt+1;
when 1|2|3|4|5|6|7|8 =>
RxBitCnt:=RxBitCnt+1;
RxBuf<= tmpRxD & RxBuf(7 downto 1);
when 9 =>
if tmpRxD='0' then -- stop bit expected
RxReady<='0';
else
RxReady<='1';
end if;
Start<='0';
RxBitCnt:=0;
when others => null;
end case;
when others =>
RxSampleCnt:=RxSampleCnt+1;
end case;
end if;
end if;
end if;
end if;
end process UART_Rx;
DataOUT(7 downto 0)<=RxBuf(7 downto 0);
RX_READY<=RxReady;
TX_RD<=TXRead;
end UARTArc;