每次计数器更新(可变整数范围)如何发送一点?

时间:2019-04-15 12:24:01

标签: integer range vhdl counter

我已经用VHDL(简单)为我的I2S收发器编写了代码。我必须知道在每个计数器更新1,2,3之后如何发送(24位)I2S字的24位之一(带有简短语句)。例如:

if cnt = 2 => load bit 1 of left channel
if cnt = 3 => load bit 2
if cnt = 25 => load bit 24 of left channel
if cnt = 26 => load bit 1 of right channel
if cnt = 48 => load bit 24 of right channel

如您所见,我代码中的WS选择左或右通道。在我的测试台中,添加测试字(2 x 24位字)。

它是并行数据输入和串行输出(PISO),因此它必须类似于移位寄存器。

我最近一直在研究VHDL,因为我是VHDL的新手,但是我不知道该怎么做。

在这里您可以看到我的书面代码。也许这是一个愚蠢的问题,但是我已经搜索了整个Internet。预先感谢您回答我的问题。

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity Simple_I2S_transceiver_V1 is
generic  (
    DATAWIDTH: integer := 24     
   );

port  
   (
    RST  : in std_logic;
    SCK  : in std_logic;             -- Serial Clock
    BCLK   : in std_logic;             -- Bit Clock
    WS   : inout std_logic;            -- Word Select or Left/Right channel select
    SD     : out std_logic;             -- Serial Data
    PDL  : in std_logic_vector(DATAWIDTH - 1 downto 0);   -- Parallel Data Left
    PDR  : in std_logic_vector(DATAWIDTH - 1 downto 0);   -- Parallel Data Right
    UPD  : inout std_logic;             -- Update data
    READY  : out std_logic;             -- check if data is ready to send (it depends on "VALID")
    VALID  : out std_logic             -- Check if data is valid (length) 
   );

end Simple_I2S_transceiver_V1;

architecture behavior of Simple_I2S_transceiver_V1 is
signal PDL_BUF : std_logic_vector(DATAWIDTH - 1 downto 0);
signal PDR_BUF : std_logic_vector(DATAWIDTH - 1 downto 0);
begin 

process(BCLK)

 -- Declaration of optional variables 
 variable bitcounter  : integer range 0 to 48;

 begin
  -------------------------------------------------
  -- RESET all     
  -------------------------------------------------

  if RST = '1' then
   WS  <= '0';
   SD  <= '0';
   READY <= '0';
   VALID <= '0';
   UPD   <= '0';
   PDL_BUF <= (OTHERS => '0');                                         -- Clear left channel buffer
   PDR_BUF <= (OTHERS => '0');                 -- Clear right channel buffer
      -------------------------------------------------
  -- Set WS / left/right-channel
      -------------------------------------------------

  elsif (BCLK'event and BCLK = '1') then
   PDL_BUF <= PDL;
   PDR_BUF <= PDR;

   bitcounter := bitcounter + 1;

   if bitcounter = 1 then
    UPD <= '1';
   else 
    UPD <= '0';

   if bitcounter >= 1 and bitcounter <= 24 then  
    WS <= '0';
   else
    WS <= '1';
    UPD <= '0'; 

   if WS = '0' then
    SD <= PDL(23);         <-- Parallel load -> it has to be serial load
   elsif WS = '1' then
    SD <= PDR(23);         <-- The same as PDL

   if bitcounter = 48 then
    bitcounter := 0;

   ----------------------------------------------
     -- transmitt data
   ---------------------------------------------- 
   -- add transmission 

     end if;
       end if;
      end if;
    end if;
   end if;
end process;

end behavior;

1 个答案:

答案 0 :(得分:0)

由于I2S首先是MSB,所以向左移动并使用PDx的MSbit进行SD输出,类似。

用于左声道(发送)

SD <= PDL_BUF (23); -- use most significant bit
PDL_BUF <= PDL_BUF (22 downto 0) & '0'; -- 22nd bit becomes 23 and puts a zero into unused bit 0

类似于右声道。对于接收,您仍然需要向左移动。

对不起,我对I2S知之甚少,但是

  1. 在加载PDL / PDR时要当心,以便在发送时无法修改它们(也许是state machine?)
  2. 同时将数据时钟输出设置为高电平时,在发送数据时要小心,您可能希望在数据时钟的下降沿输出数据,以便在另一侧的上升沿正确锁存数据。您总是可以对时钟进行状态调整-但这会降低数据速率。
  3. 知道何时在发送时在WS 0和1之间切换