[Open-graphics] Some small changes
mark.marshall at csr.com
Tue Nov 2 08:13:50 EDT 2010
First some good news. I've managed to produce images for both FPGA's.
For the XP10 I've used "ispLever Starter FPGA 8.1.00.34.21.10". For the
S3 I used version 12..00 of the xilinx tools (I forget which I
chose, we seem to have every version from 9.1 to 12.3 installed at work?).
We don;t seem to ahve an sipLevel project checked in at the moment?
Shall I try this or does someone else want to have a go?
I've checked in a few minor changes yesterday, and I'll probably do a
few more today. Here's a brief description of what they are and why
I've done them.
I've added support to the HQ assmebler for the "reserve" keyword.
Previously you could reserve a single word of data memory with the
"global" keyword, eg:
global FRAME_COUINT : 0
Would reserve one word called "FRAME_COUNT" and initialise it to 0.
With the "reserve" keyword you can reserve a block of memory and
initialise them all to the same value:
reserve STACK : 16
reserve BUFFER : 24, 0x12345678
This should reserve 16 words for "STACK" that are initalised to zero.
"BUFFER" will have 24 words reserved, and they will all be initialised
If you want to assign a different value to each word then "global" is
more useful. This should get added to the assmebler manual at some
point, but I haven't yet learnt latex.
The assembler used the "strtol" function to read in values. On a 32-bit
machine this means that the values must fit into a "signed long", and
are truncated to [LONG_MIN, LONG_MAX]. This meant that you couldn't
have data words that were >= 0x80000000. My fix is to use a "long long"
and "stroll" - this might not be ultra portable?
Here I've split out all of the common code from the oga1_diag tools.
This should make it much easier to make modifications to each tool. I'm
sorry that this means that the build process is now slightly more
complex, but I think the make file should deal with everything (At some
point, objections were raised about making this code too "obscure", as
it is really useful to be able to build it without mauch infrastructure
or knowledge - I hope I've not hampered that).
The perl script that autogenerated .v files with enum's in them was
wrong - I'd missed of a semicolon. Trivual.
740 + 743
Some wires were in the verilog but never used. Removed to get a few
741 + 744
Put defines of the PCI commands into the oga1_defs header file and use
it in the PCI verilog. This makes things mucah easier to read
(especially for those who do not know there way around the PCI spec yet).
The only other thing I've changed is that there used to be lines like:
wire mem_space_i = cbe_d[3:1] == 'b011 ||
cbe_d == 'b1100 ||
cbe_d[3:1] == 'b111;
Which I have chnaged to this:
wire mem_space_i = (cbe_d == PCI_COMMAND_MEM_READ ||
cbe_d == PCI_COMMAND_MEM_WRITE ||
cbe_d == PCI_COMMAND_MEM_READ_N ||
cbe_d == PCI_COMMAND_MEM_READ_LINE ||
cbe_d == PCI_COMMAND_MEM_WRITE_INV);
As far as I can tell the tools produce the same output, and the second
is much easier to understand. If there really is a good technical
reason for having lines like the first then I'll change them back, but I
couldn't see any.
I've made a fwe modifications to config_space.v. I've used parameters
for the size of the BARS, and passed "low_bit" to cfg_address_decode as
a parameter. This has possibly reduced some logic and has made it
clearer (to both the comppiler and human reader) that this will never
change. I've added the include file and pulled the VID and PID from
there. I've added the "if (write_bytes[n])" statements into the writes
to the "fake_write" registers (which are needed, but we would probably
get away without).
The last change is that I've made the "registers" (BAR0) not
prefetchable any more. These registers really shouldn't be - if the
host does a read from them it expects to get a "fresh" uncached value,
and the same with writes.
I hope no one minds that I've chanked in these changes. I have tested
them all before hand, and they all seem OK. I have a few further
changes in the piepline, they are also small:
A change to how interrupts are dealt with. I will add the PCI defined
disable interrupt bit and the interrupt status bit to config space. I
also plan to modify the way in which the clear_interrupt register will
work. From a lot of experience with interrupts in embeded platforms
this is how it should work:
There is a set number of different interrupt sources, all multiplexed
onto the same interrupt. We have a number of registers that have the
same structure (one bit per source), these registers are called
"int_status", "int_mask" and "int_clear".
If any interrupt source triggers (there's a hotplug event of whatever),
then the corisponding bit in "int_status" gets sets. This always happens.
If "(int_status & int_mask) != 0" then we raise an interrupt to the host.
If a value is written to "int_clear", then the ones in the value written
clear those interrupt sources (and only those). (This is often written
as W1C in hardware specs.)
The host will perform exactly this sequence to ack the interrupts.
temp = int_status;
int_clear = temp;
This scheme produces "race-free" operation. Almost every other scheme
A readable version of HQ_CONTROL
It would be very useful to be able to read HQ control. I would also
like to be able to read the HQ data memory. I will probably add these
together. Reading HQ data memory is very useful for debug and possibly
also useful for adding simple accelerator functions. Reading HQ program
memory is a pain (As the type of memory instance would have to be
changed) and I'm not sure it's that useful.
As always, I'd apperciate any feedback.
Peter Stuge's git mirror is very useful for looking at these changes, if
you don't have the source installed yourself.
More information about the Open-graphics