📄 uart1.vhd
字号:
baud_rate_counter_is_zero <= to_std_logic(((std_logic_vector'("00000000000000000000000") & (baud_rate_counter)) = std_logic_vector'("00000000000000000000000000000000")));
process (clk, reset_n)
begin
if reset_n = '0' then
baud_clk_en <= std_logic'('0');
elsif clk'event and clk = '1' then
if std_logic'(clk_en) = '1' then
baud_clk_en <= baud_rate_counter_is_zero;
end if;
end if;
end process;
do_shift <= (baud_clk_en AND (NOT shift_done)) AND (NOT do_load_shifter);
process (clk, reset_n)
begin
if reset_n = '0' then
pre_txd <= std_logic'('1');
elsif clk'event and clk = '1' then
if std_logic'(NOT shift_done) = '1' then
pre_txd <= tx_shift_reg_out;
end if;
end if;
end process;
process (clk, reset_n)
begin
if reset_n = '0' then
txd <= std_logic'('1');
elsif clk'event and clk = '1' then
if std_logic'(clk_en) = '1' then
txd <= pre_txd AND NOT do_force_break;
end if;
end if;
end process;
--_reg, which is an e_register
process (clk, reset_n)
begin
if reset_n = '0' then
unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out <= std_logic_vector'("0000000000");
elsif clk'event and clk = '1' then
if std_logic'(clk_en) = '1' then
unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out <= unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_in;
end if;
end if;
end process;
unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_in <= A_WE_StdLogicVector((std_logic'((do_load_shifter)) = '1'), tx_load_val, A_WE_StdLogicVector((std_logic'((do_shift)) = '1'), Std_Logic_Vector'(A_ToStdLogicVector(std_logic'('0')) & unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out(9 DOWNTO 1)), unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out));
tx_shift_register_contents <= unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out;
tx_shift_reg_out <= unxshiftxtx_shift_register_contentsxtx_shift_reg_outxx5_out(0);
--vhdl renameroo for output signals
tx_ready <= internal_tx_ready;
end europa;
library altera_vhdl_support;
use altera_vhdl_support.altera_vhdl_support_lib.all;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
library std;
use std.textio.all;
entity uart1_rx_stimulus_source_character_source_rom_module is
generic (
POLL_RATE : integer := 100
);
port (
-- inputs:
signal clk : IN STD_LOGIC;
signal incr_addr : IN STD_LOGIC;
signal reset_n : IN STD_LOGIC;
-- outputs:
signal new_rom : OUT STD_LOGIC;
signal q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0);
signal safe : OUT STD_LOGIC
);
end entity uart1_rx_stimulus_source_character_source_rom_module;
architecture europa of uart1_rx_stimulus_source_character_source_rom_module is
signal address : STD_LOGIC_VECTOR (10 DOWNTO 0);
signal d1_pre : STD_LOGIC;
signal d2_pre : STD_LOGIC;
signal d3_pre : STD_LOGIC;
signal d4_pre : STD_LOGIC;
signal d5_pre : STD_LOGIC;
signal d6_pre : STD_LOGIC;
signal d7_pre : STD_LOGIC;
signal d8_pre : STD_LOGIC;
signal d9_pre : STD_LOGIC;
TYPE mem_type is ARRAY( 1023 DOWNTO 0) of STD_LOGIC_VECTOR(7 DOWNTO 0);
signal mem_array : mem_type;
TYPE mem_type1 is ARRAY( 1 DOWNTO 0) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal mutex : mem_type1;
signal pre : STD_LOGIC;
signal safe_wire : STD_LOGIC; -- deal with bogus VHDL type casting
signal safe_delay : STD_LOGIC;
FILE mutex_handle : TEXT ; -- open this for read and write manually.
-- stream can be opened simply for read...
FILE stream_handle : TEXT open READ_MODE is "c:/pabst/test_scratch/test/full_featured/full_1c20_sim/uart1_input_data_stream.dat";
-- exemplar translate_off
-- convert functions deadlifted from e_rom.pm
FUNCTION convert_string_to_number(string_to_convert : STRING;
final_char_index : NATURAL := 0)
RETURN NATURAL IS
VARIABLE result: NATURAL := 0;
VARIABLE current_index : NATURAL := 1;
VARIABLE the_char : CHARACTER;
BEGIN
IF final_char_index = 0 THEN
result := 0;
ELSE
WHILE current_index <= final_char_index LOOP
the_char := string_to_convert(current_index);
IF '0' <= the_char AND the_char <= '9' THEN
result := result * 16 + character'pos(the_char) - character'pos('0');
ELSIF 'A' <= the_char AND the_char <= 'F' THEN
result := result * 16 + character'pos(the_char) - character'pos('A') + 10;
ELSIF 'a' <= the_char AND the_char <= 'f' THEN
result := result * 16 + character'pos(the_char) - character'pos('a') + 10;
ELSE
report "convert_string_to_number: Ack, a formatting error!";
END IF;
current_index := current_index + 1;
END LOOP;
END IF;
RETURN result;
END convert_string_to_number;
FUNCTION convert_string_to_std_logic(value : STRING; num_chars : INTEGER; mem_width_chars : INTEGER)
RETURN STD_LOGIC_VECTOR is
VARIABLE num_bits: integer := mem_width_chars * 4;
VARIABLE result: std_logic_vector(num_bits-1 downto 0);
VARIABLE curr_char : integer;
VARIABLE min_width : integer := mem_width_chars;
VARIABLE num_nibbles : integer := 0;
BEGIN
result := (others => '0');
num_nibbles := mem_width_chars;
IF (mem_width_chars > num_chars) THEN
num_nibbles := num_chars;
END IF;
FOR I IN 1 TO num_nibbles LOOP
curr_char := num_nibbles - (I-1);
CASE value(I) IS
WHEN '0' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0000";
WHEN '1' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0001";
WHEN '2' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0010";
WHEN '3' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0011";
WHEN '4' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0100";
WHEN '5' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0101";
WHEN '6' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0110";
WHEN '7' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "0111";
WHEN '8' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1000";
WHEN '9' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1001";
WHEN 'A' | 'a' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1010";
WHEN 'B' | 'b' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1011";
WHEN 'C' | 'c' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1100";
WHEN 'D' | 'd' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1101";
WHEN 'E' | 'e' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1110";
WHEN 'F' | 'f' => result((4*curr_char)-1 DOWNTO 4*(curr_char-1)) := "1111";
WHEN ' ' => EXIT;
WHEN HT => exit;
WHEN others =>
ASSERT False
REPORT "function From_Hex: string """ & value & """ contains non-hex character"
severity Error;
EXIT;
END case;
END loop;
RETURN result;
END convert_string_to_std_logic;
-- purpose: open mutex/discard @address/convert value to std_logic_vector
function get_mutex_val (file_name : string)
return STD_LOGIC_VECTOR is
VARIABLE result : STD_LOGIC_VECTOR (31 downto 0) := X"00000000";
FILE handle : TEXT ;
VARIABLE status : file_open_status; -- status for fopen
VARIABLE data_line : LINE;
VARIABLE the_character_from_data_line : CHARACTER;
VARIABLE converted_number : NATURAL := 0;
VARIABLE found_string_array : STRING(1 TO 128);
VARIABLE string_index : NATURAL := 0;
VARIABLE line_length : NATURAL := 0;
begin -- get_mutex_val
file_open (status, handle, file_name, READ_MODE);
WHILE NOT(endfile(handle)) LOOP
readline(handle, data_line);
line_length := data_line'LENGTH; -- match ' for emacs font-lock
WHILE line_length > 0 LOOP
read(data_line, the_character_from_data_line);
-- check for the @ character indicating a new address wad
-- if found, ignore the line! This is just protection
IF '@' = the_character_from_data_line THEN
exit; -- bail out of this line
end if;
-- process the hex address, character by character ...
IF NOT(' ' = the_character_from_data_line) THEN
string_index := string_index + 1;
found_string_array(string_index) := the_character_from_data_line;
END IF;
line_length := line_length - 1;
end loop; -- read characters
end loop; -- read lines
file_close (handle);
if string_index /= 0 then
result := convert_string_to_std_logic(found_string_array, string_index, 8);
end if;
return result;
end get_mutex_val;
-- purpose: emulate verilogs readmemh function (mostly)
-- in verilog you say: $readmemh ("file", array);
-- in VHDL, we say: array <= readmemh("file"); -- which makes more sense.
function readmemh (file_name : string)
return mem_type is
VARIABLE result : mem_type;
FILE handle : TEXT ;
VARIABLE status : file_open_status; -- status for fopen
VARIABLE data_line : LINE;
VARIABLE b_address : BOOLEAN := FALSE; -- distinguish between addrs and data
VARIABLE the_character_from_data_line : CHARACTER;
VARIABLE converted_number : NATURAL := 0;
VARIABLE found_string_array : STRING(1 TO 128);
VARIABLE string_index : NATURAL := 0;
VARIABLE line_length : NATURAL := 0;
VARIABLE load_address : NATURAL := 0;
VARIABLE mem_index : NATURAL := 0;
begin -- readmemh
file_open (status, handle, file_name, READ_MODE);
WHILE NOT(endfile(handle)) LOOP
readline(handle, data_line);
line_length := data_line'LENGTH; -- match ' for emacs font-lock
b_address := false;
WHILE line_length > 0 LOOP
read(data_line, the_character_from_data_line);
-- check for the @ character indicating a new address wad
-- if found, ignore the line! This is just protection
IF '@' = the_character_from_data_line and not b_address then -- is addr
b_address := true;
end if;
-- process the hex address, character by character ...
IF NOT((' ' = the_character_from_data_line) or
('@' = the_character_from_data_line) or
(lf = the_character_from_data_line) or
(cr = the_character_from_data_line)) THEN
string_index := string_index + 1;
found_string_array(string_index) := the_character_from_data_line;
END IF;
line_length := line_length - 1;
end loop; -- read characters
if b_address then
mem_index := convert_string_to_number(found_string_array, string_index);
b_address := FALSE;
else
result(mem_index) := convert_string_to_std_logic(found_string_array, string_index, 2);
end if;
string_index := 0;
end loop; -- read lines
file_close (handle);
return result;
end readmemh;
-- exemplar translate_on
begin
--exemplar translate_off
q <= mem_array(CONV_INTEGER(UNSIGNED((address))));
process (clk, reset_n)
begin
if reset_n = '0' then
d1_pre <= std_logic'('0');
d2_pre <= std_logic'('0');
d3_pre <= std_logic'('0');
d4_pre <= std_logic'('0');
d5_pre <= std_logic'('0');
d6_pre <= std_logic'('0');
d7_pre <= std_logic'('0');
d8_pre <= std_logic'('0');
d9_pre <= std_logic'('0');
new_rom <= std_logic'('0');
elsif clk'event and clk = '1' then
if (std_logic_vector'("00000000000000000000000000000001")) /= std_logic_vector'("00000000000000000000000000000000") then
d1_pre <= pre;
d2_pre <= d1_pre;
d3_pre <= d2_pre;
d4_pre <= d3_pre;
d5_pre <= d4_pre;
d6_pre <= d5_pre;
d7_pre <= d6_pre;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -