请求协助:将Basys2 FPGA上的4位栈扩展为8位栈及74LS194逻辑调试
Hey there! Let's walk through fixing your current stack implementation and expanding it to 8-bit, plus sorting out the 74LS194 logic that's causing headaches. First, I'll break down how your existing 4-bit stack works, then cover two common expansion scenarios, and finally debug the shift register component.
First: Fix Critical Bugs in Your 4-Bit Stack Code
Before expanding, let's patch obvious issues that will break compilation or functionality:
- Duplicate Instance Label: Your last 74LS194 instance uses
R1(same as the third one) — rename it toR0to avoid ISE errors. - Missing
signalKeyword: You declaredQ_3,vector_d_3, etc., but forgot to prefix them withsignal— this will throw compilation errors. - Incorrect Port Mapping: For stack behavior, each shift register's left input (
L) should connect to the next deeper stack level's output, not its ownQ(3).
Here's the cleaned-up core of your 4-bit stack:
architecture logic of stack is component unidade_74LS194 is port( d: in std_Logic_Vector ( 3 DOWNTO 0 ); q: out std_Logic_Vector ( 3 DOWNTO 0 ); s: in std_Logic_Vector ( 1 DOWNTO 0 ); L: in std_Logic; R: in std_Logic; clk: in std_Logic; clr: in std_Logic); end component; -- Add signal keyword to all internal signals signal Q_3, vector_d_3: STD_LOGIC_VECTOR(3 downto 0); signal Q_2, vector_d_2: STD_LOGIC_VECTOR(3 downto 0); signal Q_1, vector_d_1: STD_LOGIC_VECTOR(3 downto 0); signal Q_0, vector_d_0: STD_LOGIC_VECTOR(3 downto 0); begin -- Simplify vector assignments (instead of individual bits) vector_d_3 <= A(3) & Q_3(2 downto 0); R3: unidade_74LS194 port map( d => vector_d_3, q => Q_3, s => S_aux, L => Q_2(3), R => A(3), clk => clk_2, clr => clr_2 ); Q_aux(3) <= Q_3(3); -- Stack top output for this bit vector_d_2 <= A(2) & Q_2(2 downto 0); R2: unidade_74LS194 port map( d => vector_d_2, q => Q_2, s => S_aux, L => Q_1(3), R => A(2), clk => clk_2, clr => clr_2 ); Q_aux(2) <= Q_2(3); vector_d_1 <= A(1) & Q_1(2 downto 0); R1: unidade_74LS194 port map( d => vector_d_1, q => Q_1, s => S_aux, L => Q_0(3), R => A(1), clk => clk_2, clr => clr_2 ); Q_aux(1) <= Q_1(3); vector_d_0 <= A(0) & Q_0(2 downto 0); R0: unidade_74LS194 port map( -- Fixed duplicate label d => vector_d_0, q => Q_0, s => S_aux, L => '0', R => A(0), clk => clk_2, clr => clr_2 ); Q_aux(0) <= Q_0(3); end logic;
Expanding to an 8-Bit Stack: Two Scenarios
You didn't specify if you need 8-bit data width (handling larger values) or 8-level stack depth (storing more entries) — here's how to do both:
Scenario 1: 8-Bit Data Width (Keep 4-Level Depth)
If your soda machine needs to process 8-bit values (like extended price codes or state flags):
- Update the
stackentity to use 8-bit vectors forAandQ_aux:entity stack is port ( A: in std_Logic_vector(7 downto 0); S_aux: in std_Logic_vector(1 downto 0); Q_aux: out std_Logic_vector(7 downto 0); clk_2: in std_Logic; clr_2: in std_Logic ); end entity stack; - Add 4 more internal signal pairs (
Q_7/vector_d_7toQ_4/vector_d_4) in the architecture. - Copy-paste the 74LS194 instance logic for bits 7 through 4, matching the structure of bits 3 through 0.
Scenario 2: 8-Level Depth (Keep 4-Bit Width)
If you need to store more stack entries (like multiple user inputs):
Chain two 4-bit 74LS194s per data bit to create an 8-level shift register. For example, here's how to modify bit 3:
signal Q_3a, vector_d_3a: STD_LOGIC_VECTOR(3 downto 0); signal Q_3b, vector_d_3b: STD_LOGIC_VECTOR(3 downto 0); -- First 4 levels of the stack vector_d_3a <= A(3) & Q_3a(2 downto 0); R3a: unidade_74LS194 port map( d => vector_d_3a, q => Q_3a, s => S_aux, L => Q_3b(3), R => A(3), clk => clk_2, clr => clr_2 ); -- Second 4 levels (extend depth to 8) vector_d_3b <= Q_3a(0) & Q_3b(2 downto 0); R3b: unidade_74LS194 port map( d => vector_d_3b, q => Q_3b, s => S_aux, L => '0', R => Q_3a(0), clk => clk_2, clr => clr_2 ); Q_aux(3) <= Q_3a(3); -- Stack top remains the first register's output
Repeat this chaining for bits 2, 1, and 0 to get a full 8-level deep stack.
Debugging the 74LS194 Component
Your shift register implementation has three key issues breaking push/pop logic:
- Wrong Clock Edge: You're triggering on the falling edge (
clk = '0' and clk'event), but most FPGA designs use rising edges. Switch toclk'event and clk = '1'unless your system explicitly requires falling edges. - Signal Assignment Order: Setting
flw <= "0000"at the start of the process overrides your clock-edge logic (VHDL signal assignments are delayed). Remove this line and only initializeflwin the reset branch. - Incorrect Shift Logic: The
logic_patternprocedure didn't match the 74LS194's standard functionality. Here's the corrected component:
architecture logic of unidade_74LS194 is signal flw: std_Logic_Vector ( 3 DOWNTO 0 ); procedure logic_pattern ( signal curr_val, shift_in, shift_out, load_val: in std_Logic; signal s: in std_Logic_Vector ( 1 DOWNTO 0 ); signal o: out std_Logic ) is begin case s is when "00" => o <= curr_val; -- Hold current value when "01" => o <= shift_in; -- Shift right (R → Q0 → Q1 → Q2 → Q3) when "10" => o <= shift_out; -- Shift left (L → Q3 → Q2 → Q1 → Q0) when "11" => o <= load_val; -- Parallel load D → Q when others => o <= '0'; end case; end procedure; begin main: PROCESS ( clk, clr ) -- Only clock and reset in sensitivity list begin if ( clr = '0' ) then flw <= "0000"; elsif ( clk'event and clk = '1' ) then -- Rising edge trigger logic_pattern(flw(0), R, flw(1), d(0), s, flw(0)); logic_pattern(flw(1), flw(0), flw(2), d(1), s, flw(1)); logic_pattern(flw(2), flw(1), flw(3), d(2), s, flw(2)); logic_pattern(flw(3), flw(2), L, d(3), s, flw(3)); end if; end process; q <= flw; end architecture logic;
Quick Debug Tips for ISE WebPack
- Simulate First: Create a testbench to simulate push/pop operations before programming the FPGA. Verify that stack entries shift correctly and reset works as expected.
- Check Pin Constraints: Don't forget to add a UCF file mapping your stack ports to Basys2's physical pins (e.g.,
clk_2to the on-board clock,clr_2to a push button).
内容的提问来源于stack exchange,提问作者guib

