cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Visitor
Visitor
2,586 Views
Registered: ‎05-09-2011

Why are the assignments made byte by byte in the slave model example?

Hi,

 

I'm having a problem using the sw accesible registers example... anybody knows why the assignment is made inside a loop using bytes slices in the example?

 

------------------------------------------
  -- Example code to read/write user logic slave model s/w accessible registers
  -- 
  -- Note:
  -- The example code presented here is to show you one way of reading/writing
  -- software accessible registers implemented in the user logic slave model.
  -- Each bit of the Bus2IP_WrCE/Bus2IP_RdCE signals is configured to correspond
  -- to one software accessible register by the top level template. For example,
  -- if you have four 32 bit software accessible registers in the user logic,
  -- you are basically operating on the following memory mapped registers:
  -- 
  --    Bus2IP_WrCE/Bus2IP_RdCE   Memory Mapped Register
  --                     "1000"   C_BASEADDR + 0x0
  --                     "0100"   C_BASEADDR + 0x4
  --                     "0010"   C_BASEADDR + 0x8
  --                     "0001"   C_BASEADDR + 0xC
  -- 
  ------------------------------------------
  slv_reg_write_sel <= Bus2IP_WrCE(0 to 4);
  slv_reg_read_sel  <= Bus2IP_RdCE(0 to 4);
  slv_write_ack     <= Bus2IP_WrCE(0) or Bus2IP_WrCE(1) or Bus2IP_WrCE(2) or Bus2IP_WrCE(3) or Bus2IP_WrCE(4);
  slv_read_ack      <= Bus2IP_RdCE(0) or Bus2IP_RdCE(1) or Bus2IP_RdCE(2) or Bus2IP_RdCE(3) or Bus2IP_RdCE(4);

  -- implement slave model software accessible register(s)
  SLAVE_REG_WRITE_PROC : process( Bus2IP_Clk ) is
  begin

    if Bus2IP_Clk'event and Bus2IP_Clk = '1' then
      if Bus2IP_Reset = '1' then
        slv_reg0 <= (others => '0');
        slv_reg1 <= (others => '0');
  --      slv_reg2 <= (others => '0');
  --      slv_reg3 <= (others => '0');
  --      slv_reg4 <= (others => '0');		-- output registers. Don't allow writting.
      else
        case slv_reg_write_sel is
          when "10000" =>
            for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
              if ( Bus2IP_BE(byte_index) = '1' ) then
					 
						slv_reg0(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
						
                
				  end if;
            end loop;
          when "01000" =>
            for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
              if ( Bus2IP_BE(byte_index) = '1' ) then
                slv_reg1(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
              end if;
            end loop;
--          when "00100" =>
--            for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
--              if ( Bus2IP_BE(byte_index) = '1' ) then
--                slv_reg2(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
--              end if;
--            end loop;
--          when "00010" =>
--            for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
--              if ( Bus2IP_BE(byte_index) = '1' ) then
--                slv_reg3(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
--              end if;
--            end loop;
--          when "00001" =>
--            for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
--              if ( Bus2IP_BE(byte_index) = '1' ) then
--                slv_reg4(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
--              end if;
--            end loop;
          when others => null;
        end case;
      end if;
    end if;

 

My problem is that if I assign a 32 bits slice to a slave register it doesn't seem to work, but if I do the same by using a 32 single bit assignments by using a loop it works as expected:

 

sign1 is a std_logic_vector (63 downto 0 ) signal.

 

This way doesn't work:

OUTPUT_DECODE: process (state)
   begin
      
      if state = st2_sendirq then
         
		slv_reg2 <= sign1(63 downto 32);
    		slv_reg3 <= sign1(31 downto 0);
		slv_reg4 <= sign2(31 downto 0);
		int_rqst <= '1';
      else
			
		slv_reg2 <= X"FFFFFFFF";
    		slv_reg3 <= X"FFFFFFFF";
		slv_reg4 <= X"FFFFFFFF";
                int_rqst <= '0';
      end if;
   end process;

But if I assign the bits one by one inside a loop it works as expected:

 

OUTPUT_DECODE: process (state)
   begin
      
      if state = st2_sendirq then
         
		for bit_index in 0 to 31 loop
slv_reg2(bit_index) <= sign1(63 - bit_index);
end loop;
 slv_reg3 <= sign1(31 downto 0); slv_reg4 <= sign2(31 downto 0); int_rqst <= '1'; else slv_reg2 <= X"FFFFFFFF"; slv_reg3 <= X"FFFFFFFF"; slv_reg4 <= X"FFFFFFFF"; int_rqst <= '0'; end if; end process;

 

Anybody knows why this happens?

0 Kudos
Reply
2 Replies
Professor
Professor
2,575 Views
Registered: ‎08-14-2007

for byte_index in 0 to (C_SLV_DWIDTH/8)-1 loop
  if ( Bus2IP_BE(byte_index) = '1' ) then
    slv_reg1(byte_index*8 to byte_index*8+7) <= Bus2IP_Data(byte_index*8 to byte_index*8+7);
  end if;
end loop;

 

If you look at the highlighted section above, this is the bye enable that allows writing to

less than the full width of the register.  You could do it without a loop, but it makes it

harder to parameterize the bus width that way.

 

As to why your code works with a loop and not the other way...

 

How are the left and right sides of this assignment defined?

 

slv_reg2(bit_index) <= sign1(63 - bit_index);

 

If both look like std_logic_vector (YY downto XX), then you're inverting the bit order

in the loop (and not in the direct assignment.  If one is std_logic_vector (YY downto XX)

and another is std_logic_vector (XX to YY) then both the loop and the single assignment

should be equivalent.

 

-- Gabor

-- Gabor
0 Kudos
Reply
Visitor
Visitor
2,572 Views
Registered: ‎05-09-2011

I see!..Now I understand the byte slices logic... Thank you!

 

But what confuses me is that the loop and the single assignment should be equivalent in my code as you say, and they aren't. Just with that small change, one version works as expected ant the other doesn't... I'm really confused...

 

slv_reg2 is std_logic_vector(0 to 31)

sign1 is std_logic_vector (63 downto 0)

 

to make it more interesting, the assignment works in the other two slave_reg, when the slice is 31 downto 0...

 

0 Kudos
Reply