Another test mode which:
- Displays real baudrate (BCD format) on the LEDs
- Also provides character loop-back just like mode 3
Anvyl switches SW5..3 select the baudrate from 600 (000) to 57600 (111). Note that the number displayed is not exactly the typical standard rate. The reason is that the frequency is actually measured on the board. First, the FPGA 50MHz board frequency is divided by two prescale factors, one leads to freq_4096 that can be divided by powers of 2 down to 1 Hz, and the other based on the selected divide value to get baudrate_x8 frequency:
prescale: process(CLK, baudrate_x8, freq4096, switch_uart_rate) begin if (rising_edge(CLK)) then if (prescale_baud = 0) then baudrate_x8 <= not baudrate_x8; prescale_baud <= prescale_value(to_integer(unsigned(switch_uart_rate))); else prescale_baud <= prescale_baud - 1; end if; if (prescale_power = 0) then freq4096 <= not freq4096; prescale_power <= (clk_board / (2 * 4096)); else prescale_power <= prescale_power - 1; end if; end if; end process;
Eventually these two are used to feed into a counter that counts in BCD (more precisely, it has a 32-bit adder inside that can add in BCD or binary):
counter: freqcounter Port map ( reset => RESET, clk => freq_2048(11), freq => baudrate_x1, bcd => '1', add => X"00000001", cin => '1', cout => open, value => baudrate_debug );
The counter assumes that the "clk" signal is 50% duty cycle, as it has 2 counters which work on opposite sides of the clk level. Counts accumulated on "high" side are displayed on "low" side and vice versa, with the net result that each 1s the count ("freq" signal) is refreshed. Because 50MHz cannot be divided by some integer to create exact baudrate, they are off by less than <1% which is of course well within timing tolerances.
This way the crucial UART frequency generation, LED debug display etc. are tested.