📄 uart1.vhd
字号:
);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 "/data/job/20061127/2047501/examples/vhdl/niosII_cycloneII_2c35/standard/std_2C35_sim/uart1_input_data_stream.dat";-- synthesis translate_off-- convert functions deadlifted from e_rom.pmFUNCTION 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_vectorfunction 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; -- synthesis translate_on begin--synthesis 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; d8_pre <= d7_pre; d9_pre <= d8_pre; new_rom <= d9_pre; end if; end if; end process; safe <= safe_wire; safe_wire <= to_std_logic( address < mutex(1) ); process (clk, reset_n) begin if reset_n = '0' then safe_delay <= '0'; elsif clk'event and clk = '1' then -- balance ' for emacs quoting safe_delay <= safe_wire; end if; end process; process (clk, reset_n) variable poll_count : integer := POLL_RATE; -- STD_LOGIC_VECTOR (31:0); variable status : file_open_status; -- status for fopen variable mutex_string : LINE; -- temp space for read/write data variable stream_string : LINE; -- temp space for read data variable init_done : BOOLEAN; -- only used if non-interactive variable interactive : BOOLEAN := FALSE; begin if reset_n /= '1' then address <= "00000000000"; mem_array(0) <= X"00"; mutex(0) <= X"00000000"; mutex(1) <= X"00000000"; pre <= '0'; init_done := FALSE; elsif clk'event and clk = '1' then -- balance ' for emacs quoting pre <= '0'; if incr_addr = '1' and safe_wire = '1' then address <= address + "00000000001"; end if; -- blast mutex via textio after falling edge of safe if mutex(0) /= X"00000000" and safe_wire = '0' and safe_delay = '1' then if interactive then -- bash mutex file_open (status, mutex_handle, "/data/job/20061127/2047501/examples/vhdl/niosII_cycloneII_2c35/standard/std_2C35_sim/uart1_input_data_mutex.dat", WRITE_MODE); write (mutex_string, string'("0")); -- balance ' for emacs quoting writeline (mutex_handle, mutex_string); file_close (mutex_handle); mutex(0) <= X"00000000"; else -- non-nteractive does not bash mutex: it stops poll counter init_done := TRUE; end if; end if; if poll_count < POLL_RATE then -- wait if not init_done then -- stop counting if init_done is TRUE poll_count := poll_count + 1; end if; else -- do the real work poll_count := 0; -- get mutex via textio ... mutex(0) <= get_mutex_val ("/data/job/20061127/2047501/examples/vhdl/niosII_cycloneII_2c35/standard/std_2C35_sim/uart1_input_data_mutex.dat"); if mutex(0) /= X"00000000" and safe_wire = '0' then -- read stream into array after previous stream is complete mutex (1) <= mutex (0); -- save mutex value for address compare -- get mem_array via textio ... mem_array <= readmemh("/data/job/20061127/2047501/examples/vhdl/niosII_cycloneII_2c35/standard/std_2C35_sim/uart1_input_data_stream.dat"); -- prep address and pre-pulse to alert world to new contents address <= "00000000000"; pre <= '1'; end if; -- poll_count end if; -- clock end if; -- reset end process; --synthesis translate_onend europa;-- turn off superfluous VHDL processor warnings -- altera message_level Level1 -- altera message_off 10034 10035 10036 10037 10230 10240 10030 library altera;use altera.altera_europa_support_lib.all;library ieee;use ieee.std_logic_1164.all;use ieee.std_logic_arith.all;use ieee.std_logic_unsigned.all;entity uart1_rx_stimulus_source is port ( -- inputs: signal baud_divisor : IN STD_LOGIC_VECTOR (9 DOWNTO 0); signal clk : IN STD_LOGIC; signal clk_en : IN STD_LOGIC; signal reset_n : IN STD_LOGIC; signal rx_char_ready : IN STD_LOGIC; signal rxd : IN STD_LOGIC; -- outputs: signal source_rxd : OUT STD_LOGIC );end entity uart1_rx_stimulus_source;architecture europa of uart1_rx_stimulus_source is--synthesis translate_offcomponent uart1_tx is port ( -- inputs: signal baud_divisor : IN STD_LOGIC_VECTOR (9 DOWNTO 0); signal begintransfer : IN STD_LOGIC; signal clk : IN STD_LOGIC; signal clk_en : IN STD_LOGIC; signal do_force_break : IN STD_LOGIC; signal reset_n : IN STD_LOGIC; signal status_wr_strobe : IN STD_LOGIC; signal tx_data : IN STD_LOGIC_VECTOR (7 DOWNTO 0); signal tx_wr_strobe : IN STD_LOGIC; -- outputs: signal tx_overrun : OUT STD_LOGIC; signal tx_ready : OUT STD_LOGIC; signal tx_shift_empty : OUT STD_LOGIC; signal txd : OUT STD_LOGIC );end component uart1_tx;component 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 component uart1_rx_stimulus_source_character_source_rom_module;--synthesis translate_on signal d1_stim_data : STD_LOGIC_VECTOR (7 DOWNTO 0); signal delayed_unxrx_char_readyxx0 : STD_LOGIC; signal do_send_stim_data : STD_LOGIC; signal internal_source_rxd : STD_LOGIC; signal module_input1 : STD_LOGIC; signal module_input2 : STD_LOGIC; signal module_input3 : STD_LOGIC; signal new_rom_pulse : STD_LOGIC; signal pickup_pulse : STD_LOGIC; signal safe : STD_LOGIC; signal unused_empty : STD_LOGIC; signal unused_overrun : STD_LOGIC; signal unused_ready : STD_LOGIC;--synthesis translate_off signal stim_data : STD_LOGIC_VECTOR (7 DOWNTO 0);--synthesis translate_onbegin --vhdl renameroo for output signals source_rxd <= internal_source_rxd;--synthesis translate_off --stimulus_transmitter, which is an e_instance stimulus_transmitter : uart1_tx port map(
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -