Vhdl 如何在数据块之间以10毫秒的延迟将某些数据发送10次到uart的TX端口

Vhdl 如何在数据块之间以10毫秒的延迟将某些数据发送10次到uart的TX端口,vhdl,uart,Vhdl,Uart,我有一个传感器,它有一个解锁的字节序列,需要发送给它解锁,然后它可以接收其他命令数据。 传感器以115200 bps的波特率接收数据,8个数据位,偶数奇偶校验,2个停止位。 在接收任何命令数据(用于设置参数)之前,它需要以1ms的间隔接收d4(十六进制数,字节)10次。 我以115200的波特率将转换为位11010100并添加奇偶校验的d4发送到uart的TX端口,停止位变为11010100011,但如何在发送的两个d4数据字节之间创建延迟?我写的代码,如果不清楚,请让我知道我会把更多的细节 e

我有一个传感器,它有一个解锁的字节序列,需要发送给它解锁,然后它可以接收其他命令数据。 传感器以115200 bps的波特率接收数据,8个数据位,偶数奇偶校验,2个停止位。 在接收任何命令数据(用于设置参数)之前,它需要以1ms的间隔接收d4(十六进制数,字节)10次。 我以115200的波特率将转换为位11010100并添加奇偶校验的d4发送到uart的TX端口,停止位变为11010100011,但如何在发送的两个d4数据字节之间创建延迟?我写的代码,如果不清楚,请让我知道我会把更多的细节

entity Uart_tx is

port (

  TX : out std_logic;
  clk_in : in std_logic;
  but_div_clk : out std_logic;
  clk_in_2 : in std_logic

);

end Uart_tx;

architecture Behavioral of Uart_tx is

  signal tx_clk : std_logic := '0';
  signal clk_1Khz : std_logic := '0';
  signal q : unsigned(8 downto 0) := (others => '0');
  signal p : unsigned(8 downto 0) := (others => '0');

  type state_type is (idle, start);
  signal state : state_type;

  signal tick_in : std_logic := '0';

  subtype byte is std_logic_Vector(7 downto 0);
  type byte_array is array(natural range <>) of byte;
  signal data_byte_array : byte_array(1 to 8);

  --  signal curr_byte : std_logic_vector(7 downto 0);
  signal byte_index : unsigned(2 downto 0) := "000";


  subtype reg is std_logic_Vector(10 downto 0);
  type reg_array is array(natural range <>) of reg;
  signal TxDataReg_array : reg_array(1 to 8);

  signal cur_Tx_reg : std_logic_vector(10 downto 0); 
  signal current_reg : unsigned(3 downto 0) := "0001";
  signal count : unsigned (4 downto 0) := (others => '0');

  signal count_d : unsigned (4 downto 0) := (others => '0');
  signal sent_d4 : unsigned (3 downto 0) := (others => '0');

  signal send_d4 : std_logic := '1';
  signal D_4 : std_logic_vector(10 downto 0) :="11000101011"; 

begin
  -- below are random entry ..actual data will come from slv_reg registers.
  data_byte_array(1) <= "10101010"; -- slv_reg0(7 downto 0);
  data_byte_array(2) <= "10101011"; -- slv_reg0(15 downto 8);
  data_byte_array(3) <= "10101010"; -- slv_reg0(23 downto 16);
  data_byte_array(4) <= "10101011"; -- slv_reg0(31 downto 24);
  data_byte_array(5) <= "10101010"; -- slv_reg1(39 downto 32);
  data_byte_array(6) <= "10101011"; -- slv_reg1(47 downto 40);
  data_byte_array(7) <= "10101010"; -- slv_reg1(55 downto 48);
  data_byte_array(8) <= "10101011"; -- slv_reg1(63 downto 56);
  tick_in <= '1';

  ---------------------------------------Clk_div-----------------------------------------

  process ( clk_in ) is 
  begin 
    if clk_in'event and clk_in = '1' then

      q <= q + 1;

      tx_clk <= q(8);   --- 58.gdfg/2^8 =~ 230Khz baud rate = 115200 

      but_div_clk <= tx_clk;
    end if;
  end process;

  ---------------------------------------Clk_div------------------------------------------


  ---------------------------------------Clk_div------------------------------------------

  process( clk_in_2 ) is 
  begin 

    if clk_in_2'event and clk_in_2 = '1' then

      p <= p + 1;

      clk_1Khz <= p(7);

    end if;
  end process;

  ---------------------------------------------------------------------------------------

  --------------------------------------TX_Process----------------------------------------   

  process( state, tx_clk , tick_in) is 

    variable parity : std_logic := '0';
    variable curr_byte : std_logic_vector(7 downto 0) := (others => '0');
  begin 

    case state is 

      when idle => TX <= '1';
        if tick_in = '1' then 
          state <= start;
        else 
          TX <= '1';
        end if;

      when start => 

        if send_d4 = '1' then 

          if (rising_edge(clk_1Khz)) then 

            case count_d is
              when "00000" => TX <= D_4(0);
              when "00001" => TX <= D_4(1);
              when "00010" => TX <= D_4(2);
              when "00011" => TX <= D_4(3);
              when "00100" => TX <= D_4(4);
              when "00101" => TX <= D_4(5);
              when "00110" => TX <= D_4(6);
              when "00111" => TX <= D_4(7);
              when "01000" => TX <= D_4(8);
              when "01001" => TX <= D_4(9);
              when "01010" => TX <= D_4(10);
              when others => TX <= '1';
            end case;

            count_d <= count_d +1;
            sent_d4 <= sent_d4 + 1;
            if to_integer(count_d) = 11 then
              count_d <= "00000";
            end if;

            if to_integer(sent_d4) = 10 then 
              send_d4 <= '0' ;    
            end if;
          end if;
        else 
          for i in 1 to 8 loop 

            curr_byte := data_byte_array(i);
            parity := '0';
            for j in curr_byte'range loop
              parity := parity xor curr_byte(j);
            end loop;

            if parity = '0' then
              TxDataReg_array(i) <= "110" & curr_byte ;
            else 
              TxDataReg_array(i) <= "111" & curr_byte ;
            end if;
          end loop;
          cur_Tx_reg <= TxDataReg_array(to_integer(byte_index)+1);
          byte_index <= byte_index + 1;   

          if rising_edge(tx_clk) then     
            case count is
              when "00000" => TX <= cur_Tx_reg(0);
              when "00001" => TX <= cur_Tx_reg(1);
              when "00010" => TX <= cur_Tx_reg(2);
              when "00011" => TX <= cur_Tx_reg(3);
              when "00100" => TX <= cur_Tx_reg(4);
              when "00101" => TX <= cur_Tx_reg(5);
              when "00110" => TX <= cur_Tx_reg(6);
              when "00111" => TX <= cur_Tx_reg(7);
              when "01000" => TX <= cur_Tx_reg(8);
              when "01001" => TX <= cur_Tx_reg(9);
              when "01010" => TX <= cur_Tx_reg(10);
              when others => TX <= '1';
            end case;
            count <= count+1;
            if to_integer(count) = 11 then
              count <= "00000";
              state   <= idle;
              --      TX  <= '1';
            end if;
          end if;         

        end if;

      when others => TX <= '1';
    end case;

  end process;

end Behavioral;
实体Uart\u tx为
港口(
TX:输出标准逻辑;
时钟输入:在标准逻辑中;
但是"分区时钟":输出标准逻辑;;
时钟输入2:标准输入逻辑
);
结束Uart_tx;
Uart_tx的架构是
信号发送时钟:标准逻辑:='0';
信号时钟1Khz:标准时钟逻辑:='0';
信号q:无符号(8到0):=(其他=>0');
信号p:无符号(8到0):=(其他=>'0');
类型状态\类型为(空闲、启动);
信号状态:状态_型;
信号勾选输入:标准逻辑:='0';
子类型字节是标准逻辑向量(7到0);
类型byte_array是字节的数组(自然范围);
信号数据字节数组:字节数组(1到8);
--信号电流字节:标准逻辑向量(7到0);
信号字节索引:无符号(2到0):=“000”;
子类型reg是标准逻辑向量(10到0);
类型reg_数组是reg的数组(自然范围);
信号TxDataReg_阵列:reg_阵列(1至8);
信号电流Tx寄存器:标准逻辑矢量(10到0);
信号电流_reg:无符号(3到0):=“0001”;
信号计数:无符号(4到0):=(其他=>“0”);
信号计数d:无符号(4到0):=(其他=>“0”);
发送的信号_d4:未签名(3到0):=(其他=>“0”);
信号发送_d4:std_逻辑:='1';
信号D_4:std_逻辑_向量(10到0):=“11000101011”;
开始
--下面是随机输入。实际数据将来自slv_reg寄存器。

data_byte_array(1)要获得定时延迟,您必须实现一个计数器,用于勾选等于1ms的计算时钟周期数。然后,您需要在FSM中插入激活计数器的状态,并在需要时等待其完成。可以手动计算计数器值,但您可以让工具为您完成这项工作,并避免代码中出现幻数

ieee库;
使用ieee.std_logic_1164.all;
使用ieee.numeric_std.all;
...
恒定时钟频率:实值:=50.0e6;--50兆赫系统时钟
恒定传感器延迟:实值:=1.0e-3;--1毫秒延迟
恒定延迟计数:自然:=整数(时钟频率*传感器延迟);
--这可以通过ceil_log2()函数自动计算
恒定定时器_大小:自然:=16;
信号计时器:无符号(计时器大小-1减至0);
常数延迟_INIT:无符号(计时器范围)
:=to_unsigned(延迟计数,计时器长度);
...
--在需要延迟之前的某个时间初始化计时器
计时器
计时器这可能不会按您预期的方式合成(甚至操作)。您在流程的某些部分异步分配
TX
,在其他部分同步分配,然后通过两个不同的时钟分配。你应该把它清理干净。