Ich versuche, eine einfache Schleife des Kommunikationssystems zwischen PC und FPGA Virtex 5 zu entwerfen, zu diesem Zweck habe ich ein BRAM mit einem UART-Modul verbunden, ich verwende VHDL als Hardwarebeschreibungssprache, der verwendete Speicher ist ein einfacher 16-Byte-Dual-Port-BRAM RAM mit einer Breite von 8 Bit; 16 Bytes Daten von einer Terminalsoftware lesen und dann zurückschicken soll, ist das Problem, dass ich die erste Adresse nicht schreiben kann (addra = 0) und das Schreiben ab der zweiten Adresse beginnt, also kann ich nur 15 Bytes schreiben in einem durchlauf, hier ist der code des fsm, der verwendet wird, um das system zu implementieren
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;
Dieser Teil des Codes ist für die Signale, die ich für Simulationszwecke verwendet habe
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
Das folgende Bild zeigt die Simulationsergebnisse des Schreibens von dina in addra = 0
Und dieses Bild zeigt die Simulationsergebnisse des Lesens von doutb von addrb = 0
Können Sie mir bitte sagen, warum ich den Wert 0 auf addressb = 0 lese, obwohl der erste empfangene Wert von 0 abweicht?
Basierend auf Ihrer zweiten Bildschirmaufnahme lesen Sie bei addressb=1 NOT addressb=0.
RdB wird im "Lese"-Zustand hoch gesetzt und addressb wird inkrementiert, aber diese Werte werden erst im folgenden Taktzyklus aus dem Register ausgelesen. Wenn daher der aktualisierte (hohe) RdB vom BRAM gesehen wird, wurde der Ausgang des addressb-Registers bereits auf 1 inkrementiert.
Spannungsspitze
mng
Brian Carlton