To make your life easier, look at my fifo 3 word and switch to system verilog logic syntax and let the compiler auto-select whether your logic names are regs or wires.
Okaaay.. I'm not familiar with the SystemVerilog syntax (not that it's much different), so I'm hoping I don't introduce more errors as a result.
Please be more defined about what the ' 4'd06 : begin // write pixel with x & y, no colour' means.
Why, what's different?
There's no colour data?
Perhaps you didn't catch my drift.
Does function #6 even write a pixel?
I thought it is a copy IE: read pixel command.
Also:
{destination_base_address[23:1], 1'b0} + ( y * dest_rast_width[15:0] + x )
Can create an odd memory address and the entire line does not reflect the proper read/write address if you are in 16bits per pixel mode, 4 bits per pixel mode, 2 bits per pixel mode, or, 1 bit per pixel mode. It only reflects the proper address when in 8 bit per pixel mode, but with the LSB swinging as if we are addressing 8 bits.
Maybe you should make a temporary logic name in the combinational section like:
dest_base_address_offset = ( (y * dest_rast_width[15:0] + x ) << 1 ) >> CORRECT NUMBER OF BITS base on bits per pixel )
Okay, done that, but I'm unsure about how the 'correct number of bits' relates to bits per pixel. Firstly, how is bits-per-pixel getting into the module? Is it going to be set by the geometry_xy_plotter, or the Z80_bridge, or something else?
Looking inside the geometry unit, in the transmitted commands section, #14 and #15, after the address:
// AUX=14 : Set destination mem address, : 31:24 bitplane mode : 23:0 hold destination base memory addres for write pixel
// AUX=15 : Set source mem address, : 31:24 bitplane mode : 23:0 hold the source base memory address for read source pixel
The 'bitplane mode' will contain the number of bits per pixel.
Remember, the copy pixel and write pixel may have 2 different bitplane modes. This way if you want to print a 2 color font, IE 1 bit per pixel, onto a 16 color graphics screen, IE 4 bits per pixel, the address generator will send both individual values to the pixel writer/reader so it may perform the translation in real time. Without this, you would have to store a 16 color font for your 16 color screen which takes more ram and also wont allow you to chose individual character colors as the font itself would already be colorized.
Also: 4'd14 : dest_base_address[23:0] <= { draw_cmd[23:1], 1'b0 };
Do not shave off the LSB here.
Should I also not be shaving off the LSB for 4'd15 as well, or is the source address being treated differently?
I guess what I was trying to say is that the shaving should only be done right at the last step before output. Technically, since we are calculating a 16 bit offset for the read/write pointer, this should automatically be done by the math if the formula is right.
Aslo:
4'd01 : begin // write pixel with colour, x & y
pixel_cmd[23:0] <= {destination_base_address[23:1], 1'b0} + ( y * dest_rast_width[15:0] + x ); // generate address for the pixel
pixel_cmd[31:24] <= draw_cmd[31:24]; // include colour information
pixel_cmd[35] <= 1'b1; // WRITE command
pixel_cmd[34:32] <= 3'b0; // No transparency, no R/M/W, affected bits unknown
pixel_cmd_rdy <= 1'b1;
Maybe you should combine these 2 lines into a ' pixel_cmd[35:32] <= 4'd## '
Also, you haven't created a difference between the pixel write command # 4'd01 and # 4'd06.
Ah. I've added a bit to the CMD part of pixel_cmd to allow for colour/no-colour (the 36th bit).
Hang on - have I misunderstood the TRANSPARENCY bit? Is that what I should be using for 4'd06?
So far so good.
Next, you will need to decide how to pass the information like which bits in a 16 bit word are to be edited. the grand total of 32 bits for address and color are just enough since we have only 20 bits addressing for maggie. Lets see how you progress.
Okay, well I think I've done that - with the bits saved from dropping the memory address from 24- to 20-bits, I've included 4 bits (unimaginatively called 'BIT' in the code comments for the pixel_cmd format) to identify exactly which bit in the 16-bit word needs modifying.
Where I really need some help is with bit_mode. How does that feed into dest_base_address_offset etc? Is it literally just a bit-shift right as you've indicated in the example for dest_base_address_offset?
Separately, you should also need to tell the pixel writer how many bits are in a pixel as this information is needed as well.
Yes, I've asked about this above. Is this going to feed in from the video generator, or somewhere else?
Ok, about the bit selection, and the missing bit width.
The -
// AUX=14 : Set destination mem address, : 31:24 bitplane mode : 23:0 hold destination base memory addres for write pixel
// AUX=15 : Set source mem address, : 31:24 bitplane mode : 23:0 hold the source base memory address for read source pixel
- bitplane mode tells the address generator how many bits there are in a pixel. The address generator needs to tell the pixel writer that number of bits in a pixel. It also needs to use this information to calculate the right memory address as the X coordinate will now change how much the address increases, but also, depending on the pixel width and where the X coordinate lands, the pixel writer also needs that information as well so it may edit the correct bits within the word. IE, the pixel writer knowing the bits per pixel set by the 'bitplane mode' is half of what it needs. It also needs where inside the 16 bits the X coordinate landed on so it may edit the right parts of the 16 bit word.
This second piece of information in effect is the correct lower 0-3 bits of the X coordinates. Also, your output bus isn't large enough for this added 4 bits, so a total of 36 bits needs another 4 bits of data.
BITS:
20 - (A) address
4 - (B) pixel width bits
4 - (C) sub-pixel location within a 16 bit word
8 - (D) color function
4 - (E) function to perform IE AUX command
----------------------------------------------------------
40 bits total.
Now, since (A&C&D&E) are needed to read and write a pixel while (B) can be sent to the pixel_reader/writer as it's own function, you can cheat and still use a 36bit bus, but, when we add a fifo between the geo_address_generator and the geo_pixel_reader_writer, that will be 1 additional word in the fifo which will occasionally need to be sent. With a 40 bit bus, we eliminate that 1 word in out 3 word cache since the fifo will now be 40bit instead of 36 bit and that info will be sent in parallel with every read or write command.