⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uart.vhd

📁 這是Originl公司出的8051 VHDL source code.
💻 VHD
📖 第 1 页 / 共 2 页
字号:
    -- assumes that shift happens at the rollovers    if tf1_16'event and tf1_16 = 0 then      case i is        when 0 => txd_wr <= '0';        -- start bit        when 9 => txd_wr <= tb8;        -- 9th bit        when 10 => txd_wr <= '1';       -- stop bit                   ti_set <= '1';        when 11 => to_send := '0';      -- time to stop        when others => txd_wr <= sbuf_dup(i-1);         -- shift the byte out      end case;      i := i+1;    end if;  when others => null;  end case;end if;end process;-- process to receive data from outside-- reception start conditions:-- for mode 0 the condition is ri = '0' and ren = '1'-- for other modes the condition is ren = '1' and falling edge of rxdprocess (sm_r(2 downto 1), cycle_state, rf1_16, p2clk_16, rxd)variable i : integer := 0;              -- iteration countervariable samp1, samp2, samp3, rcvd_bit : std_logic;variable sbuf_dup : byte;               -- internal buffer for sbuf-- indicate whether reception is in sessionvariable rcv_in_session : std_logic := '0';begin-- if sm_r(2 downto 1) is changed, clear the current processif sm_r(2 downto 1)'event then rcv_in_session := '0'; end if;case sm_r(2 downto 1) is  when "00" =>    -- mode 0, 8-bit shift register, Fxtal1/12    -- shift clock is output through txd    -- shift clock is low during s3, s4, s5, high during s6, s1, s2    -- actual data is sampled in through rxd during s5p2  if cycle_state'event and ri = '0' and ren = '1' then    if rcv_in_session = '0' then        -- initiate reception      rcv_in_session := '1';      i := 0;      ri_set <= '0';    -- lower ri_set signal to create an edge later    else                                -- already in reception      case cycle_state is        when s1p1 => if i = 9 then      -- time to stop                        sbuf_rd <= sbuf_dup;                        ri_set <= '1';  -- set ri                        rcv_in_session := '0';                     end if;        when s3p1 => if i /= 0 then txd_rd <= '0'; end if;        -- assume that ri is cleared after s5p2 in the cycle        when s5p2 => if i /= 0 then sbuf_dup(i-1) := rxd; end if;                     i := i + 1;        when s6p1 => if i /= 0 then txd_rd <= '1'; end if;        when others => null;      end case;    end if;  end if;  when "01" =>    -- mode 1, 8-bit UART, baud rate set by timer 1    -- we can change this falling edge detection into sampling    if falling_edge(rxd) and (ren = '1') and (rcv_in_session = '0') then      rcv_in_session := '1';      rf1_16_reset <= '1';      -- reset the counter immediately      i := 0;      rb8_set <= '0';      rb8_reset <= '0';      ri_set <= '0';    end if;    if rf1_16'event and (rcv_in_session = '1') then      case rf1_16 is      when 7 => samp1 := rxd;           -- first sample      when 8 => samp2 := rxd;           -- second sample      when 9 =>        samp3 := rxd;           -- third sample        -- take the value which appears at least twice, for noise rejection        if samp1 = samp2 or samp2 = samp3 then rcvd_bit := samp2;        else rcvd_bit := samp1;        end if;        if i = 0 then                   -- start bit          if rcvd_bit /= '0' then       -- false start bit, start over            rcv_in_session := '0';            rf1_16_reset <= '0';          end if;        elsif i = 9 then                -- stop bit          -- two conditions to meet for successful reception completion          if ri = '0' and (sm_r(0) = '0' or rcvd_bit = '1') then            sbuf_rd <= sbuf_dup;            -- save rcvd_bit in rb8            if rcvd_bit = '1' then rb8_set <= '1';            else rb8_reset <= '1';            end if;            ri_set <= '1';          end if;          rcv_in_session := '0';          rf1_16_reset <= '0';        else sbuf_dup(i-1) := rcvd_bit; -- data bits        end if;        i := i + 1;      when others => null;      end case;    end if;  when "10" =>    -- mode 2, 9-bit UART, Fxtal1/64 or Fxtal1/32    -- we can change this falling edge detection into sampling    if falling_edge(rxd) and (ren = '1') and (rcv_in_session = '0') then      rcv_in_session := '1';      p2clk_16_reset <= '1';    -- reset the counter      i := 0;      rb8_set <= '0';      rb8_reset <= '0';      ri_set <= '0';    end if;    if p2clk_16'event and (rcv_in_session = '1') then      case p2clk_16 is      when 7 => samp1 := rxd;           -- first sample      when 8 => samp2 := rxd;           -- second sample      when 9 =>        samp3 := rxd;           -- third sample        -- take the value which appears at least twice, for noise rejection        if samp1 = samp2 or samp2 = samp3 then rcvd_bit := samp2;        else rcvd_bit := samp1;        end if;        if i = 0 then                   -- start bit          if rcvd_bit /= '0' then       -- false start bit, start over            rcv_in_session := '0';            p2clk_16_reset <= '0';          end if;        elsif i = 9 then                -- stop bit          -- two conditions to meet for successful reception completion          if ri = '0' and (sm_r(0) = '0' or rcvd_bit = '1') then            sbuf_rd <= sbuf_dup;            -- save rcvd_bit in rb8            if rcvd_bit = '1' then rb8_set <= '1';            else rb8_reset <= '1';            end if;            ri_set <= '1';          end if;          rcv_in_session := '0';          p2clk_16_reset <= '0';        else sbuf_dup(i-1) := rcvd_bit; -- data bits        end if;        i := i + 1;      when others => null;      end case;    end if;  when "11" =>    -- mode 3, 9-bit UART, baud rate set by timer 1    -- we can change this falling edge detection into sampling    if falling_edge(rxd) and (ren = '1') and (rcv_in_session = '0') then      rcv_in_session := '1';      rf1_16_reset <= '1';      -- reset the counter      i := 0;      rb8_set <= '0';      rb8_reset <= '0';      ri_set <= '0';    end if;    if rf1_16'event and (rcv_in_session = '1') then      case rf1_16 is      when 7 => samp1 := rxd;           -- first sample      when 8 => samp2 := rxd;           -- second sample      when 9 =>        samp3 := rxd;           -- third sample        -- take the value which appears at least twice, for noise rejection        if samp1 = samp2 or samp2 = samp3 then rcvd_bit := samp2;        else rcvd_bit := samp1;        end if;        if i = 0 then                   -- start bit          if rcvd_bit /= '0' then       -- false start bit, start over            rcv_in_session := '0';            rf1_16_reset <= '0';          end if;        elsif i = 9 then                -- stop bit          -- two conditions to meet for successful reception completion          if ri = '0' and (sm_r(0) = '0' or rcvd_bit = '1') then            sbuf_rd <= sbuf_dup;            -- save rcvd_bit in rb8            if rcvd_bit = '1' then rb8_set <= '1';            else rb8_reset <= '1';            end if;            ri_set <= '1';          end if;          rcv_in_session := '0';          rf1_16_reset <= '0';        else sbuf_dup(i-1) := rcvd_bit; -- data bits        end if;        i := i + 1;      when others => null;      end case;    end if;  when others => null;end case;end process;-- the rxd signal has got two drivers: outside and transmitter-- in mode 0 both can drive rxd-- in other modes only outside drives rxd-- when transmitter is not driving it outputs 'H'-- process to resolve the txd signal-- it's got two drivers: transmitter and receiver-- in mode 0 both transmitter and receiver can drive txd-- in other modes only transmitter drives txd-- when one is not driving txd, it outputs '1'txd <= txd_wr and txd_rd;-- process to generate the divide-by-16 counter of timer 1 overflow signal-- the clock of this counter is 16 times slower than the timer 1 overflow signal-- we don't know in which cycle_state tf1 will be set-- so have to synchronize it with s1p1process (tf1, cycle_state, tf1_16_reset, rf1_16_reset)variable tf1_flag : bit := '0';variable tf1_half : bit := '0';begin-- rising edge of tf1_16_reset clears the counter-- could be level-triggeredif rising_edge(tf1_16_reset) then tf1_16 <= 0; end if;if rising_edge(rf1_16_reset) then rf1_16 <= 0; end if;--if rising_edge(tf1) then tf1_flag := '1'; end if;--if cycle_state'event and cycle_state = s1p1 and tf1_flag = '1' thenif rising_edge(tf1) then  if smod = '0' then                    -- cut the frequency in half    tf1_half := not tf1_half;  end if;  if not (smod = '0' and tf1_half = '1') then   -- increment the counter    tf1_16 <= (tf1_16 + 1) mod 16;    rf1_16 <= (rf1_16 + 1) mod 16;    --tf1_flag := '0';  end if;end if;end process;-- process to generate the divide-by-16 counter of the phase 2 clock-- phase 2 clock is twice as slow as the xtal1 clockprocess (p2clk, p2clk_16_reset)variable p2clk_half : bit := '0';begin-- rising edge of p2clk_16_reset clears the counter-- could be level-triggeredif rising_edge(p2clk_16_reset) then p2clk_16 <= 0; end if;-- it could be rising edge depending on how it aligns with cycle_stateif falling_edge(p2clk) then  if smod = '0' then            -- cut the frequency in half    p2clk_half := not p2clk_half;  end if;  if not (smod = '0' and p2clk_half = '1') then -- increment the counter    p2clk_16 <= (p2clk_16 + 1) mod 16;  end if;end if;end process;end behave;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -