Ich kann nicht finden, wie ich mit dem Fehler umgehen soll: "mehrere konstante Laufwerke", der auftritt, wenn ich versuche, dasselbe Netz in einem einzigen Vorgang zu lesen und einzustellen.
Ich muss den "Ausgang" für einige Taktzyklen auf die steigende Flanke des "enable"-Eingangs setzen und dann den "Ausgang" zurücksetzen. Mein Code:
library ieee;
use ieee.std_logic_1164.all;
entity trigger_slave is
generic (
OUT_ON_PERIOD : integer := 10 - 1
);
port (
enable : in std_logic;
clk_1MHz : in std_logic;
OUTPUT : buffer std_logic
);
end trigger_slave;
architecture behavior of trigger_slave is
begin
process (enable)
begin
if (rising_edge(enable)) then
OUTPUT <= '1';
end if;
end process;
process (clk_1MHz)
variable counter : integer range 0 to OUT_ON_PERIOD := 0;
begin
if (rising_edge(clk_1MHz) and OUTPUT = '1') then -- here is the problem!
if (counter = OUT_ON_PERIOD) then
counter := 0;
OUTPUT <= '0';
else
counter := counter + 1;
OUTPUT <= '1';
end if;
end if;
end process;
end behavior;
Bitte helfen Sie mir mit diesem Code. Vielen Dank.
Ich weiß, dass Sie ein Anfänger sind, aber Ihre VHDL liest sich so, als würden Sie versuchen, ein Computerprogramm zu schreiben, und keine digitale Logikschaltung entwerfen.
Informieren Sie sich im Internet über synchrones digitales Logikdesign.
Dann informieren Sie sich danach über VHDL und sehen Sie sich an, wie es die gewünschte Schaltung implementieren kann. Denken Sie daran: Das Schaltungsdesign (egal wie umfassend) steht an erster Stelle, das VHDL-Design an zweiter Stelle.
In der Zwischenzeit ist hier das gewünschte Design. (Ich habe es nicht mit ModelSim kompiliert, daher könnten Tippfehler enthalten sein.)
library ieee;
use ieee.std_logic_1164.all;
entity TRIGGER_SLAVE is
generic(
OUT_ON_PERIOD : integer := 10 - 1
);
port(
CLK : in std_logic;
RST : in std_logic;
ENABLE : in std_logic;
OUTPUT : out std_logic
);
end entity TRIGGER_SLAVE;
architecture behaviour of TRIGGER_SLAVE is
signal delayCtr : natural range 0 to OUT_ON_PERIOD;
signal enableOld1 : std_logic;
begin
pDelay : process(RST, CLK) is
begin
if (RST = '1') then
delayCtr <= 0 ;
enableOld1 <= '0';
OUTPUT <= '0';`
elsif rising_edge(CLK) then
-- Keep old enable level from 1 CLK ago, for edge detection.
enableOld1 <= ENABLE;
-- Reload delay counter on ENABLE rising edge then run it down to zero.
if (ENABLE = '1' and enableOld1 = '0') then
delayCtr <= OUT_ON_PERIOD;
elsif (delayCtr /= 0) then
delayCtr <= delayCtr - 1;
end if;
-- Assert OUTPUT while the delay counter is running.
if (delayCtr /= 0) then
OUTPUT <= '1';
else
OUTPUT <= '0';
end if;
end if;
end process pDelay;
end architecture behaviour;
Sie hatten keinen Reset-Eingang, aber das Design benötigt einen. Abgesehen davon und als allgemeine Richtlinien: Verwenden Sie keine Variablen, verwenden Sie Signale; Verwenden Sie Rising_edge nur mit einer Uhr; Verwenden Sie keine Zustandsmaschinen, es sei denn, Sie müssen es unbedingt tun (einige verwenden sie für alles, eine schlechte Angewohnheit).
Übrigens bestand das Problem in Ihrem Design darin, dass Sie zwei Prozesse hatten, die einen Ausgangsport ansteuerten.
Nur für Signale verwenden rising_edge
, die Uhren sein sollen.
Sie können kein Signal zuweisen oder in zwei verschiedenen Prozessen ausgeben.
Sie haben nicht genau angegeben, was Sie erreichen möchten, aber ich denke, dass Sie keinen Puffer für verwenden müssen (und sollten) OUTPUT
.
Dieser Code sollte wie erwartet funktionieren (wenn ich Sie richtig verstehe):
library ieee;
use ieee.std_logic_1164.all;
entity trigger_slave is
generic (
OUT_ON_PERIOD : integer := 10 - 1
);
port (
clk_1MHz : in std_logic;
resetn : in std_logic;
enable : in std_logic;
output : out std_logic
);
end trigger_slave;
architecture behavior of trigger_slave is
type state_t is (IDLE, COUNTING);
signal machine: state_t;
begin
process (clk_1MHz)
variable counter : integer range 0 to OUT_ON_PERIOD := 0;
begin
if resetn = '0' then
machine <= IDLE;
elsif rising_edge(clk_1MHz) then
case machine is
when IDLE =>
machine <= IDLE;
if enable = '1' then
counter := 0;
machine <= COUNTING;
end if;
when COUNTING =>
machine <= COUNTING;
if (counter = OUT_ON_PERIOD) then
machine <= IDLE;
else
counter := counter + 1;
end if;
when others =>
machine <= IDLE;
end case;
end if;
end process;
output <= '1' when machine = COUNTING else '0';
end behavior;
Staszek
dwEprew
Staszek
enable
ist eine andere Uhr?