130 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
			
		
		
	
	
			130 lines
		
	
	
		
			4.8 KiB
		
	
	
	
		
			VHDL
		
	
	
	
	
	
| LIBRARY std;
 | |
|   USE std.TEXTIO.all;
 | |
| LIBRARY Common_test;
 | |
|   USE Common_test.testUtils.all;
 | |
| 
 | |
| ARCHITECTURE RTL OF uvmRs232Driver IS
 | |
|                                                                    -- parameters
 | |
|   signal baudRate_int: real;
 | |
|   signal baudPeriod, characterPeriod: time;
 | |
|   constant uartDataBitNb: positive := 9;
 | |
|   constant maxStringLength: positive := driverTransaction'length;
 | |
|                                                                    -- Tx signals
 | |
|   signal outString : string(1 to maxStringLength);
 | |
|   signal sendString: std_uLogic := '0';
 | |
|   signal outChar: character;
 | |
|   signal sendChar: std_ulogic := '0';
 | |
|   signal sendParity, parityInit: std_ulogic := '0';
 | |
|                                                                         -- debug
 | |
|   signal outChar_debug: unsigned(uartDataBitNb-1 downto 0);
 | |
| 
 | |
| 
 | |
| BEGIN
 | |
|   ------------------------------------------------------------------------------
 | |
|                                                         -- interpret transaction
 | |
|   interpretTransaction: process
 | |
|     variable myLine : line;
 | |
|     variable commandPart : line;
 | |
|     variable baudRate_nat : natural;
 | |
|     file dataFile : text;
 | |
|     variable dataLine : line;
 | |
|   begin
 | |
|     wait on driverTransaction;
 | |
|     write(myLine, driverTransaction);
 | |
|     rm_side_separators(myLine);
 | |
|     read_first(myLine, commandPart);
 | |
|     if commandPart.all = "uart_baud" then
 | |
|       read(myLine, baudRate_nat);
 | |
|       baudRate_int <= real(baudRate_nat);
 | |
|     elsif commandPart.all = "uart_parity" then
 | |
|       sendParity <= '0';
 | |
|       parityInit <= '0';
 | |
|       if myLine.all = "even" then
 | |
|         sendParity <= '1';
 | |
|       elsif myLine.all = "odd" then
 | |
|         sendParity <= '1';
 | |
|         parityInit <= '1';
 | |
|       end if;
 | |
|     elsif commandPart.all = "uart_send" then
 | |
|       outString <= pad(myLine.all, outString'length);
 | |
|       sendString <= '1', '0' after 1 ns;
 | |
|     elsif commandPart.all = "uart_send_file" then
 | |
|       file_open(dataFile, "$SIMULATION_DIR/" & myLine.all, read_mode);
 | |
|       while not endFile(dataFile) loop
 | |
|         readLine(dataFile, dataLine);
 | |
| --print(dataLine.all);
 | |
|         outString <= pad(dataLine.all, outString'length);
 | |
|         sendString <= '1', '0' after 1 ns;
 | |
|         wait for (dataLine'length+8) * characterPeriod;
 | |
|       end loop;
 | |
|       file_close(dataFile);
 | |
|     end if;
 | |
|     deallocate(myLine);
 | |
|   end process interpretTransaction;
 | |
| 
 | |
|   baudRate <= baudRate_int;
 | |
|   baudPeriod <= 1.0/baudRate_int * 1 sec;
 | |
|   characterPeriod <= 15*baudPeriod;
 | |
| 
 | |
|   --============================================================================
 | |
|                                                       -- send string on RxD line
 | |
|   uartSendString: process
 | |
|     variable outStringRight: natural;
 | |
|   begin
 | |
|                                                              -- wait for command
 | |
|     sendChar <= '0';
 | |
|     wait until rising_edge(sendString);
 | |
|                                                            -- find string length
 | |
|     outStringRight := outString'right;
 | |
|     while outString(outStringRight) = ' ' loop
 | |
|       outStringRight := outStringRight-1;
 | |
|     end loop;
 | |
|                                                               -- send characters
 | |
|     for index in outString'left to outStringRight loop
 | |
|       outChar <= outString(index);
 | |
| --print(sprintf("%2X", character'pos(outChar)));
 | |
|       sendChar <= '1', '0' after 1 ns;
 | |
|       wait for characterPeriod;
 | |
|     end loop;
 | |
|                                                          -- send carriage return
 | |
|     outChar <= cr;
 | |
|     sendChar <= '1', '0' after 1 ns;
 | |
|     wait for characterPeriod;
 | |
| 
 | |
|   end process uartSendString;
 | |
| 
 | |
|   ------------------------------------------------------------------------------
 | |
|                                                    -- send character on RxD line
 | |
|   uartSendChar: process
 | |
|     variable outChar_unsigned: unsigned(uartDataBitNb-1 downto 0);
 | |
|   begin
 | |
|                                                              -- wait for trigger
 | |
|     RxD <= '1';
 | |
|     wait until rising_edge(sendChar);
 | |
|                                                  -- transform char to bit vector
 | |
|     outChar_unsigned := to_unsigned(
 | |
|       character'pos(outChar),
 | |
|       outChar_unsigned'length
 | |
|     );
 | |
|     outChar_unsigned(outChar_unsigned'high) := '1';
 | |
|     if sendParity = '1' then
 | |
|       outChar_unsigned(outChar_unsigned'high) := parityInit;
 | |
|       for index in uartDataBitNb-2 downto 0 loop
 | |
|         outChar_unsigned(outChar_unsigned'high)
 | |
|           := outChar_unsigned(outChar_unsigned'high)
 | |
|           xor outChar_unsigned(index);
 | |
|       end loop;
 | |
|     end if;
 | |
|     outChar_debug <= outChar_unsigned;
 | |
|                                                                -- send start bit
 | |
|     RxD <= '0';
 | |
|     wait for baudPeriod;
 | |
|                                                                -- send data bits
 | |
|     for index in outChar_unsigned'reverse_range loop
 | |
|       RxD <= outChar_unsigned(index);
 | |
|       wait for baudPeriod;
 | |
|     end loop;
 | |
|   end process uartSendChar;
 | |
| 
 | |
| END ARCHITECTURE RTL;
 |