05-09-2011 02:45 AM
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?
05-09-2011 11:06 AM
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
05-09-2011 11:24 AM
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...