Cómo conectar UART con BRAM en xilinx virtex 5

Estoy tratando de diseñar un bucle simple de sistema de comunicación entre PC y FPGA virtex 5, para este propósito conecté una BRAM con un módulo uart, estoy usando VHDL como lenguaje de descripción de hardware, la memoria utilizada es una BRAM de puerto dual simple de 16 bytes ram con un ancho de 8 bits; se supone que debe leer 16 bytes de datos de un software de terminal y luego enviarlos de vuelta, el problema es que no puedo escribir la primera dirección (addra = 0) y la escritura comienza desde la segunda dirección, por lo que solo puedo escribir 15 bytes en una sola pasada, aquí está el código del fsm utilizado para implementar el sistema

proc_next_state: process(clk, reset, state)
begin
  if reset = '1' then
    state <= idle;
  elsif (rising_edge(clk)) then
    case state is
      when idle =>
        wea(0) <= rx_dv ;
        dina <= rx_byte; -- input of BRAM's port A.
        ENB <= '0'; -- Enable signal for port B
        tx_DV <= '0'; -- data valid signal for uart transmitting interface.
        tx_byte <=(others => '0'); -- byte to be loaded to uart transmitting interface
        if rx_dv = '1' then -- data valid signal for uart receiving interface
          state <= writing; -- if rx_dv is asserted move to the writing state
        else
          state <= idle;                              -- keep idle
        end if;

      when writing => 
        if addra = "1111" then -- if the whole block is written move to the reading state
          state <= reading;
        else
          state<= idle;
        end if;
        wea <= (others => '1');
        dina <= rx_byte;
        ENB <= '0';
        tx_DV <= '0';
        addra <= addra + 1;
        tx_byte <= (others => '0');

      when reading =>
        wea <= (others => '0');
        dina <= (others => '0');
        ENB <= '1';
        tx_DV <= '1';
        tx_byte <= doutb;
        if addrb = "1111" then -- if the 16 bytes data are fully read move to state done
          state <= done;
        else
          state <= waiting; 
        end if;
        addrb <= addrb + 1;

      when waiting =>
        wea <= (others => '0');
        dina <= (others => '0');
        ENB <= '0';
        tx_DV <= '0';
        tx_byte <= (others => '0');
        if tx_done = '1' then
          state <= reading; -- read a new byte when tx_done is asserted high
        else
          state <= waiting; -- keep waiting
        end if;

      when others => -- remain in this state for one clock period then move to idle
        wea(0) <= '0';
        dina <= (others => '0');
        ENB <= '0';
        tx_DV <= '0';
        tx_byte <= (others => '0');
        addra <= "0000";
        addrb <= "0000";
        state <= idle; 
    end case;
  end if;
end process;

Esta parte del código es para las señales que utilicé con fines de simulación.

Din <= dina;
Wra <= wea(0);
Rdb <= enb;
i_rx_DV <= rx_DV;
o_tx_done <= tx_done ;
dout <= doutb;
o_rx_byte <= rx_byte;
w_SM_Main <= "000" when state = Idle else
             "001" when state = writing else
             "010" when state = reading else
             "011" when state = waiting else
             "100" when state = done else
             "101"; -- you should not reach this value

La siguiente imagen muestra los resultados de la simulación de escribir dina a addra = 0

ingrese la descripción de la imagen aquí

Y esta imagen muestra los resultados de la simulación de leer doutb de addrb = 0

ingrese la descripción de la imagen aquí

¿Puede decirme por qué estoy leyendo el valor 0 en la dirección b = 0 aunque el primer valor recibido es diferente de 0?

Haga una pregunta específica electronics.stackexchange.com/help/how-to-ask
Si el sim te dice que 0 está en la dirección 0, entonces créelo. Mire los estados en el simulador y vea si se está comportando como esperaba. (No soy un gran admirador de las máquinas de estado de un solo proceso).
No incluya el estado en la lista de sensibilidad de su proceso. Para la lógica sincronizada, debe ser reloj y reinicio (si reinicio asíncrono).

Respuestas (1)

Según su segunda captura de pantalla, está leyendo en addressb=1 NOT addressb=0.

RdB se establece alto en el estado de "lectura" y addressb se incrementa, pero estos valores no se leen del registro hasta el siguiente ciclo de reloj. Por lo tanto, cuando la BRAM ve el RdB (alto) actualizado, la salida del registro addressb ya se ha incrementado a 1.