• Content Count

  • Joined

  • Last visited

Reputation Activity

  1. Like
    CPerez10 reacted to hamster in Simple UART message repeater (not working)   
    I think of std_logic_vector the same way I would think of digits in a number...  the rightmost digit is digit zero. It most likely isn't the best way set things up for this example, but it avoids the need to swap the bit ordering in the ASCII characters.
    Oh, for the button synchronization...  signals take time to get across the chip (speed of light, capacitance and so on), so different parts of the design can see different values for the same signal as it change unless. As you can't control when the user might press the button you have to sample the value of the input signal on the clock edge,  holding that in a register. That registered value is then used drive the rest of your logic.
    There is a slight complication - If the signal from the button changes state *exactly* on the clock edge, the flipflop might not be able to correctly register as a 1 or a 0, but could be in some weird "metastable" state that takes a short while to become either a 1 or a 0. To stop this causing bugs in the operation of the logic deeper in the deign, the output of that fliplfop is then sampled a second time to get a "known good, either 1 or 0" signal, that can get to where it needs to within a clock cycle.
    Hence the design pattern... btn  gets sampled into btn_metastable (which is a bit dodgy if you use it), and then btn_metastable gets sampled into btn_synchronized, which is then used by the rest of the logic.
  2. Like
    CPerez10 reacted to hamster in Simple UART message repeater (not working)   
    Had a hack at it... tested working on BASYS3
    library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.NUMERIC_STD.ALL; entity msg_repeater is Port ( clk : in STD_LOGIC; btn : in STD_LOGIC; tx : out STD_LOGIC; led : out STD_LOGIC_VECTOR (3 DOWNTO 0)); end msg_repeater; architecture Behavioral of msg_repeater is constant char_t : std_logic_vector (7 downto 0) := "01010100"; constant char_e : std_logic_vector (7 downto 0) := "01000101"; constant char_s : std_logic_vector (7 downto 0) := "01010011"; constant char_space : std_logic_vector (7 downto 0) := "00100000"; -- Note message is sent from bit 0 to the highest signal msg : std_logic_vector (49 downto 0) := char_space & "0" & -- Character 4, with start bit "1" & char_t & "0" & -- Character 3, wrapped in start and stop bit "1" & char_s & "0" & -- Character 2, wrapped in start and stop bit "1" & char_e & "0" & -- Character 1, wrapped in start and stop bit "1" & char_t & "0" & -- Character 0, wrapped in start and stop bit "1"; -- Idle symbol and stop bit of the last character signal msg_index : unsigned( 7 downto 0) := (others =>'0'); -- Should we send a message? signal triggered : std_logic := '0'; -- for generating the baud tick rate constant clock_rate : natural := 100000000; constant baud_rate : natural := 9600; signal baud_counter : unsigned(27 downto 0) := (others => '0'); signal baud_tick : std_logic := '0'; -- For the button synchonizer signal btn_synchronized : std_logic := '0'; signal btn_metastable : std_logic := '0'; begin process(clk) begin if rising_edge(clk) then -- Set the serial output bit tx <= msg(to_integer(msg_index)); led <= "0001"; -- Controlling the message index if baud_tick = '1' then if msg_index = 0 then -- We are waiting to be triggered if triggered = '1' then msg_index <= msg_index + 1; end if; elsif msg_index = msg'high then -- We have finished the message msg_index <= (others => '0'); triggered <= '0'; else -- We are sending bits msg_index <= msg_index + 1; end if; end if; -- Generating the baud tick if baud_counter < baud_rate then baud_tick <= '1'; baud_counter <= baud_counter - baud_rate + clock_rate; else baud_tick <= '0'; baud_counter <= baud_counter - baud_rate; end if; -- Seeing if we are triggered if btn_synchronized = '1' then triggered <= '1'; end if; -- Synchronize the button with the clock domain btn_metastable <= btn; btn_synchronized <= btn_metastable; end if; end process; end Behavioral;  
  3. Like
    CPerez10 reacted to xc6lx45 in Simple question regarding Anvyl Spartan 6 clock frequency   
    as a simple (oversimplified?) answer, designing for higher clock speed requires higher effort (possibly "much" higher effort), and the resulting optimizations make the code harder to work with.
    Using the clocking wizard to generate a 500 MHz PLL is easy (try it). But writing logic at those frequencies is a different story (e.g. try to implement a conventional counter that divides down to 1 Hz. Why do all those XYX_CARRY signals show up in the timing report already at synthesis?). You also need to distinguish between what is feasible in plain logic fabric, and what can be done with dedicated "hard-macro" IP blocks such as SERDES.