John Galt
John Galt

Reputation: 3

VHDL Demultiplexer output to switch signal between port

Please go easy on me, I'm new to this... :) I have a signal in which I would like to toggle the output between one of two available output ports TX_ADDR and TX_DATA based on the value of a count CNT. The idea is to pipe some value first 32 bit value I get serially to an address bus, then to the data bus, then the address, then data...And so on. And I basically keep that routine going ad infinitum.

If I have something like:

   process(sCNT)
   begin
   if(sCNT = false) then
       TX_ADDR <= sTXD;
       sCNT    <= true;
   else
       TX_DATA <= sTXD;
       sCNT    <= false;
   end if;
   end process;

...it doesn't seem to work. Basically the idea is that sCNT ('s' indicates a signal) needs to be toggled once another process receives 32 bits of data serially. The next 32 bits basically trigger that again, and then again the output is toggled to either TX_ADDR or TX_DATA depending on the state of sCNT.

Thank you!

John

EDIT: here's the full updated and "working" code. I didn't see where I could paste this much code into a comment so I thought I'd share it up here:

process(CLK, RST)
 begin
    if (RST = '1') then
      sRXD       <= x"00000000";
      sINDEX     <= 31;
      sTXD       <= x"00000000";
      sSCLK_old  <= '0';
      sSCLK_l    <= '0';
      sCS_old    <= '0';
      sCS_l      <= '0';
      DONE       <= '0';
      sMOSI_l    <= '0';

    elsif( rising_edge(CLK) ) then

      sSCLK_l       <= SCLK;
      sSCLK_old     <= sSCLK_l;
      sCS_l         <= CS;
      sCS_old       <= sCS_l;
      DONE          <= '0';
      sMOSI_l       <= MOSI;

      if(TX_EN = '1') then
          sTXD <= TX_DATA;
      end if;

      if (sCS_old = '1' and sCS_l = '0') then
          sINDEX <= 31;
      end if;

      if( sCS_l = '0' ) then
         if(sSCLK_old = '0' and sSCLK_l = '1') then
            sRXD <= sRXD(30 downto 0) & sMOSI_l;
            if(sINDEX = 0) then
               sINDEX <= 31;
            else
               sINDEX <= sINDEX-1;
            end if;
         elsif(sSCLK_old = '1' and sSCLK_l = '0') then
            if( sINDEX = 31 ) then
               DONE <= '1';
            end if;
            sTXD <= sTXD(30 downto 0) & '1';
         end if;
      end if;


     if(sCNT = false) then
         RX_ADDR <= sRXD;
         sCNT    <= true;
     else
         RX_DATA <= sRXD;
         sCNT    <= false;
     end if;
   end if;
   end process;

   MISO    <= sTXD(31);
end arch;

Upvotes: 0

Views: 947

Answers (1)

HeyYO
HeyYO

Reputation: 2073

You should use a clock for driving your process.

process(clk)
begin

    if rising_edge(clk) then

        if sCNT = false then
            TX_ADDR <= sTXD;
            sCNT <= true;
        else
            TX_DATA <= sTXD;
            sCNT <= false;
        end if;

    end if;

end process

The clk here should be the clock of your serially coming data. The way you do it, it's 'like' your process in an infinite loop. You change 'sCNT' and you expect it to update itself immediately?? But when you use a clock it will update itselft only on a new data (which is synchronized to clk).

Upvotes: 3

Related Questions