[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[oc] Bit set operations on Risc5X



Wondered if anyone else had fallen over this one :

> Hi Mike,
>
> I have a problem with the mciro-core
> I use a program similar like the following instructions:
>
>       BSF 0x07,7;
>       BSF 0x07,2;
>       BSF 0x07,1;
>       BSF 0x07,0;
>
> First I want to set bit7 on portc, then bit2, then bit1 and at least bit0
>
> In the simulation I see that after the first instruction portc is 0x80,
what
> I expect, after the second instruction portc is 0x40, I expect it to be
> 0x84 after the third portc is 0x02 I expect 0x86 and so one.
>
> It seems that BSF sets the corresponding bit and clears all others.
>
> Can you help me ??
>
<SNIP>

I believe this behaviour is correct, and is an unfortunate result of mapping
the output and input registers of an IO port to the same address, and having
separate in and out busses in the core rather than an IO bus.
The BSF instruction is a read,modify,write operation - so it reads from the
address, in this case the input port of portc, set's the desired bit and
then writes it to the output port.
If the IO port is an output, I suspect you have wired the input pins to
'0' - hence BSF will only set one bit and clear all the rest. To fix it, you
need to use the code in the top level risc5x_xil.vhd which wires the input
pins to the output pins (after a tristate buffer).

You will also need to modify cpu.vhd, process port_in to remove the input
register.

Cheers,
Mike.

--in cpu.vhd :

port_in : process(CLK,RESET,PORTA_IN,PORTB_IN,PORTC_IN)
    begin
    -- the input registers don't exist in the real device,
    -- so if you read an output we have introduced a clock delay.
      if (RESET = '1') then
        porta_din <= (others => '0');
        portb_din <= (others => '0');
        portc_din <= (others => '0');
      elsif CLK'event and (CLK = '1') then -- comment this out for
combinatorial ip
      --else                               -- or comment this for
registeredip
        porta_din <= PORTA_IN;
        portb_din <= PORTB_IN;
        portc_din <= PORTC_IN;
      end if;
  end process;


-- in risc5x.vhd

drive_ports_out_comb :
process(porta_out,porta_oe_l,portb_out,portb_oe_l,portc_out,portc_oe_l)
  begin
    for i in 0 to 7 loop
      if (porta_oe_l(i) = '0') then
        IO_PORTA_IO(i) <= porta_out(i);
      else
        IO_PORTA_IO(i) <= 'Z';
      end if;

      if (portb_oe_l(i) = '0') then
        IO_PORTB_IO(i) <= portb_out(i);
      else
        IO_PORTB_IO(i) <= 'Z';
      end if;

      if (portc_oe_l(i) = '0') then
        IO_PORTC_IO(i) <= portc_out(i);
      else
        IO_PORTC_IO(i) <= 'Z';
      end if;
    end loop;
  end process;

drive_ports_in_comb : process(IO_PORTA_IO,IO_PORTB_IO,IO_PORTC_IO)
  begin
    porta_in <= IO_PORTA_IO;
    portb_in <= IO_PORTB_IO;
    portc_in <= IO_PORTC_IO;
  end process;



--
To unsubscribe from cores mailing list please visit http://www.opencores.org/mailinglists.shtml