Pada pandangan pertama Anda akan mengharapkan kode sumber VHDL di bawah ini berperilaku sebagai register geser. Dalam q itu, seiring waktu akan menjadi
"UUUU0", "UUU00", "UU000", "U0000", "00000", ....
tetapi sebaliknya selalu U
setelah lima (atau lebih) siklus jam berturut-turut.
Kenapa ini?
Kode ini sebenarnya adalah versi yang jauh dari simulasi yang jauh lebih rumit. Tapi itu menunjukkan gejala yang saya lihat.
Ini menunjukkan hasil yang menarik dan tidak terduga ini selama simulasi di bawah ModelSim dan ActiveHDL, saya belum mencoba simulator lain dan akan (kedua untuk penjelasan penyebabnya) ingin tahu apakah orang lain bertindak dengan cara yang sama.
Untuk menjawab pertanyaan ini dengan benar, Anda harus memahami bahwa:
- Saya tahu ini bukan cara terbaik untuk mengimplementasikan register geser
- Saya tahu untuk sintesis RTL ini harus memiliki reset.
- Saya tahu array std_logic adalah std_logic_vector.
- Saya tahu operator agregasi
&
,.
Apa yang saya juga temukan:
- Jika tugas
temp(0)<='0';
dipindahkan dalam proses, itu berfungsi. - Jika loop tidak dibuka (lihat kode komentar), itu berhasil.
Saya akan menegaskan kembali bahwa ini adalah versi yang sangat disederhanakan dari desain yang jauh lebih rumit (untuk CPU pipelined), dikonfigurasi untuk murni menunjukkan hasil simulasi yang tidak terduga. Jenis sinyal yang sebenarnya hanyalah penyederhanaan. Untuk alasan ini, Anda harus mempertimbangkan jawaban Anda dengan kode dalam bentuk apa adanya.
Dugaan saya adalah bahwa pengoptimal mesin simulasi VHDL keliru (atau mungkin sesuai spesifikasi) tidak repot untuk menjalankan ekspresi di dalam loop karena tidak ada sinyal di luar perubahan, meskipun saya dapat membuktikan hal ini dengan menempatkan loop terbuka dalam satu lingkaran.
Jadi saya berharap bahwa jawaban untuk pertanyaan ini lebih berkaitan dengan standar untuk simulasi VHDL dari sintaks VHDL tidak eksplisit dan bagaimana mesin simulasi VHDL melakukan optimisasi mereka, daripada jika diberikan kode contoh adalah cara terbaik untuk melakukan sesuatu atau tidak.
Dan sekarang ke kode saya mensimulasikan:
library ieee;
use ieee.std_logic_1164.all;
entity test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end entity;
architecture example of test_simple is
type t_temp is array(4 downto 0) of std_logic;
signal temp : t_temp;
begin
temp(0) <= '0';
p : process (clk)
begin
if rising_edge(clk) then
for i in 1 to 4 loop
temp(i) <= temp(i - 1);
end loop;
--temp(1) <= temp(0);
--temp(2) <= temp(1);
--temp(3) <= temp(2);
--temp(4) <= temp(3);
end if;
end process p;
q <= temp(4);
end architecture;
Dan bangku tes:
library ieee;
use ieee.std_logic_1164.all;
entity Bench is
end entity;
architecture tb of bench is
component test_simple is
port (
clk : in std_logic;
q : out std_logic
);
end component;
signal clk:std_logic:='0';
signal q:std_logic;
signal rst:std_logic;
constant freq:real:=100.0e3;
begin
clk<=not clk after 0.5 sec / freq;
TB:process
begin
rst<='1';
wait for 10 us;
rst<='0';
wait for 100 us;
wait;
end process;
--Note: rst is not connected
UUT:test_simple port map (clk=>clk,q=>q) ;
end architecture;
temp(0)
karena tidak ada "peristiwa" yang terkait dengan konstanta literal. Menempatkan tugas di dalam process
menciptakan hubungan dengan peristiwa jam yang membuatnya bekerja. Saya ingin tahu apakah menambahkan after
klausa ke tugas akan menjadi solusi potensial.