📄 transmitter.vhd
字号:
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use work.Wireless_USB_pack.all;
entity TRANSMITTER is
port (
CLK : in std_logic; -- 24MHz clock input
RESET : in std_logic; -- Master reset pin (1 = resets logic)
WR : in std_logic; -- Controller writes parallel DATA byte (active high)
PARALLEL_DATA_IN : in std_logic_vector(7 downto 0); -- DATA input from controller
SERIAL_DATA_OUT : out std_logic; -- serial data to RF_Modem transmitter
TRANSMITTER_EMPTY : out std_logic; -- When '1' logic is ready to accept data for transmittion
CRC_READY_TO_TX : in std_logic; -- when going high transmitter reads crc result
CRC_WRITE_EN : out std_logic; -- when high informs crc block that TX_block is ready to accept crc result
CRC_IN : in std_logic_vector(15 downto 0) ); -- reflects crc16 result
end TRANSMITTER;
architecture TRANSMITTER of TRANSMITTER is
type state_type is (TX_BUFFER, PULSE, INTERVAL);
signal state : state_type;
signal buffer_vect : std_logic_vector (7 downto 0);
signal data_reg_vect : std_logic_vector (8 downto 0);
signal interval_generator: integer range (BIT_INTERVAL-1) downto 0;
signal shift_count : integer range 9 downto 0;
signal pulse_count : integer range PULSE_CLOCK_COUNT downto 0;
signal crc_count : integer range 3 downto 0;
signal tx_empty1 : std_logic ;
begin
TRANSMITTER_EMPTY <= tx_empty1;
process (CLK, RESET)
begin
-- Someone pressed the reset?
if (RESET = '1') then
data_reg_vect <= (others => '0');
state <= TX_BUFFER;
shift_count <= 0;
pulse_count <= 0;
serial_data_out <= '0';
tx_empty1 <= '1';
buffer_vect <= (others => '0');
crc_count <= 0;
crc_write_en <= '1';
interval_generator <= 0;
-- Synchronous design
elsif rising_edge(CLK) then
-- generate 24 clocks timer thet equal to 1usec (bit period)
if (interval_generator = (BIT_INTERVAL-1)) then
interval_generator <= 0;
else
interval_generator <= (interval_generator + 1);
end if;
-- Write parallel data byte to transmit buffer
if (wr = '1') then
buffer_vect <= parallel_data_in ;
tx_empty1 <= '0';
end if;
-- when the controller finished writing his data , the crc result is ready for transmission
-- the transmitter reads the low crc result when TX_Empty=1 then transmit it , after that reads
-- the high crc result transmit it too, and sets crc_write_en for one CLK period to tell the crc block
-- that the result is no longer needed, the counter is used to count the read operation
if (crc_ready_to_tx = '1' and tx_empty1 = '1') then
crc_count <= (crc_count + 1) mod 4;
case crc_count is
when 0 =>
buffer_vect <= crc_in ( 7 downto 0);
tx_empty1 <= '0';
when 1 =>
buffer_vect <= crc_in ( 15 downto 8);
tx_empty1 <= '0';
when 2 =>
crc_write_en <= '0';
when 3 =>
crc_write_en <= '1';
end case;
end if;
-- Transmitter state machine
case state is
-- load the main shift register if it's full or else do idle
when TX_BUFFER =>
if ((tx_empty1 = '0') and (wr= '0')) then
data_reg_vect(8 downto 1) <= buffer_vect;
data_reg_vect(0) <= START_BIT;
tx_empty1 <= '1';
shift_count <= 0;
pulse_count <= 0;
state <= PULSE;
end if;
interval_generator <= 0;
serial_data_out <= '0';
-- push next bit out and count how many we did already
when PULSE =>
serial_data_out <= data_reg_vect(0);
pulse_count <= (pulse_count + 1);
if pulse_count = (PULSE_CLOCK_COUNT-1) then
state <= INTERVAL;
pulse_count <= 0;
if shift_count = 9 then
shift_count <= 0;
else
shift_count <= (shift_count + 1);
end if;
end if;
-- generate sufficient interval between data bits
when INTERVAL =>
-- since we are pausing then we are pushing '0'...
serial_data_out <= '0';
if interval_generator=(BIT_INTERVAL-1) then
data_reg_vect(7 downto 0) <= data_reg_vect(8 downto 1);
state <= PULSE;
end if;
-- allow return to TX_BUFFER load state one clock cycle
-- earlier since it takes a cycle to load the next byte to the
-- shift register and we don't want an extra interval cycle
if ((interval_generator=(BIT_INTERVAL-2)) and (shift_count = 9)) then
state <= TX_BUFFER;
end if;
end case;
end if;
end process;
end TRANSMITTER;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -