zoukankan      html  css  js  c++  java
  • uart baud rate generator

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.NUMERIC_STD.all;

    library unisim;
    use unisim.vcomponents.all;

    entity uart_brg is
    port (
    i_clock : in std_logic;
    i_prescale : in unsigned (3 downto 0);
    i_divisor : in unsigned (7 downto 0);
    i_fraction : in unsigned (3 downto 0);
    o_baud_tick : out std_logic;
    o_baud_16x_tick : out std_logic
    );
    end uart_brg;

    architecture a of uart_brg is
    signal uart_brg_cntr : unsigned(7 downto 0) := ( others => '0' );
    signal uart_brg_acc : unsigned(4 downto 0) := ( others => '0' );
    signal value_cmp : unsigned (7 downto 0);
    signal prescale : std_logic;
    signal prescale_r : std_logic := '1';
    signal value_adj : std_logic := '0';
    signal baud_tick : std_logic;
    signal baud_16x_tick : std_logic;

    attribute INIT : string;
    attribute INIT of prescale_srl16e : label is "0000";
    attribute INIT of baud_tick_srl16e : label is "0001";

    begin

    o_baud_16x_tick <= baud_16x_tick; and prescale_r;
    o_baud_tick <= baud_tick and prescale_r;

    prescale_r <= prescale when rising_edge( i_clock );
    prescale_srl16e : SRL16E
    --synthesis translate_off
    generic map (INIT => X"0000")
    --synthesis translate_on
    port map(
    D => prescale_r,
    CE => '1',
    CLK => i_clock,
    A0 => i_prescale(0),
    A1 => i_prescale(1),
    A2 => i_prescale(2),
    A3 => i_prescale(3),
    Q => prescale );


    baud_tick_srl16e : SRL16E
    --synthesis translate_off
    generic map (INIT => X"0001")
    --synthesis translate_on
    port map(
    D => baud_tick,
    CE => baud_16x_tick,
    CLK => i_clock,
    A0 => '1',
    A1 => '1',
    A2 => '1',
    A3 => '1',
    Q => baud_tick );


    value_adj <= uart_brg_acc(4);
    value_cmp <= i_divisor - ("0000000" & value_adj) ;

    process(i_clock)
    begin
    if (rising_edge(i_clock)) then
    if ( prescale_r = '1' ) then
    if ( baud_16x_tick = '1' ) then
    uart_brg_acc <= '0' & uart_brg_acc(3 downto 0) + i_fraction;
    end if;
    end if;
    end if;
    end process;

    process(i_clock)
    begin
    if (rising_edge(i_clock)) then
    if ( prescale_r = '1' ) then
    if ( uart_brg_cntr < value_cmp ) then
    baud_16x_tick <= '0';
    uart_brg_cntr <= uart_brg_cntr + 1;
    else
    baud_16x_tick <= '1';
    uart_brg_cntr <= ( others => '0' );
    end if;
    end if;
    end if;
    end process;

    end a;

    library ieee;
    use ieee.std_logic_1164.all;
    -- Uncomment the following library declaration if using
    -- arithmetic functions with Signed or Unsigned values
    use ieee.numeric_std.all;
    entity uart_brg_tb is
    end uart_brg_tb;
    architecture behavior of uart_brg_tb is
    -- Component Declaration for the Unit Under Test (UUT)
    component uart_brg
    port(
    i_clock : in std_logic;
    i_prescale : in unsigned(3 downto 0);
    i_divisor : in unsigned(7 downto 0);
    i_fraction : in unsigned(3 downto 0);
    o_baud_tick : out std_logic;
    o_baud_16x_tick : out std_logic
    );
    end component;
    --Inputs
    signal i_clock : std_logic := '0';
    signal i_prescale : unsigned(3 downto 0) := "0010";
    signal i_divisor : unsigned(7 downto 0) := "10000000";
    signal i_fraction : unsigned(3 downto 0) := "0010";
    --Outputs
    signal o_baud_tick : std_logic;
    signal o_baud_16x_tick : std_logic;
    -- Clock period definitions
    constant i_clock_period : time := 10 ns;
    signal tx_delta : time := 0 ns;
    signal rx_delta : time := 0 ns;
    signal tx_cntr : unsigned ( 3 downto 0) := ( others => '0' );
    begin
    -- Instantiate the Unit Under Test (UUT)
    uut : uart_brg port map (
    i_clock => i_clock,
    i_prescale => i_prescale,
    i_divisor => i_divisor,
    i_fraction => i_fraction,
    o_baud_tick => o_baud_tick,
    o_baud_16x_tick => o_baud_16x_tick
    );
    -- Clock process definitions
    i_clock_process : process
    begin
    i_clock <= '0';
    wait for i_clock_period/2;
    i_clock <= '1';
    wait for i_clock_period/2;
    end process;
    process
    begin
    wait until rising_edge( o_baud_tick );
    tx_cntr <= tx_cntr + 1;
    if tx_cntr = "1001" then
    tx_cntr <= "0000";
    report time'image( now - tx_delta ) & " TX ";
    tx_delta <= now;
    end if;
    end process;
    process
    begin
    wait until rising_edge( o_baud_16x_tick );
    report time'image( now - rx_delta ) & " RX ";
    rx_delta <= now;
    end process;
    -- Stimulus process
    stim_proc : process
    begin
    -- hold reset state for 100 ns.
    wait for 100 ns;
    wait for i_clock_period*10;
    -- insert stimulus here
    wait;
    end process;
    end;


  • 相关阅读:
    简化日常工作之三:自己写一个CI脚手架
    gearman的安装和配置
    简化日常工作系列之二 ----- 定时采集小说
    简化日常工作系列之一 ---- 自动新建每日记录
    代码简洁之四 统一抽象层次
    php处理金额显示的一些笔记
    代码简洁之三:减少注释 增加代码可读性
    通用性安装redis和基本配置
    写一个Redis封装类
    Exchange2010安装指南
  • 原文地址:https://www.cnblogs.com/shangdawei/p/2498001.html
Copyright © 2011-2022 走看看