Estoy tratando de diseñar un bucle simple de sistema de comunicación entre la PC y el FPGA virtex 5, para esto conecté un módulo BRAM con uart, estoy usando VHDL como el lenguaje de descripción del hardware, la memoria utilizada es un simple de 16 bytes. doble puerto BRAM 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 nuevo a él, 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 puedo escribir solo 15 bytes en una 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é para propósitos 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 al escribir dina en addra = 0
Yestaimagenmuestralosresultadosdelasimulacióndelalecturadedoutbdesdeaddrb=0
¿Puede decirme por qué leo el valor 0 en addressb = 0 aunque el primer valor recibido sea diferente de 0?