6502.org http://forum.6502.org/ |
|
Concept & Design of 3.3V Parallel 16-bit VGA Boards http://forum.6502.org/viewtopic.php?f=10&t=2247 |
Page 30 of 41 |
Author: | ElEctric_EyE [ Sat Apr 13, 2013 9:38 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
8BIT wrote: Very cool. I read in the WIKI that flipping the x & y coordinated before input then flipping them back on output is used in hardware frequently. That would essential flip DX and DY... I have code for the 1st quadrant... I tried to throw in some comments. When DX >= DY, use the formula on the wiki. When DY>DX, swapping DX and DY for all the calculations works. This code was abit more challenging and there's probably a more efficient way to do it. I'm posting my code in case something happens to my computer. BTW it will plot vertical and horizontal lines without extra checking. Code: module LineGen ( input clk,
output reg [9:0] X = 0, //LSB of RAM address output reg [8:0] Y = 0 //MSB of RAM address ); reg [9:0] x0, x1, dx; //internal module registers reg [8:0] y0, y1, dy; reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative reg steep; //this will be a '1' when dy>dx reg [3:0] state; parameter LOAD = 0, DXDY = 1, CALC1 = 2, CALC2 = 3, PLOT = 4; always @(posedge clk) begin state <= LOAD; case (state) LOAD: //load register values state <= DXDY; //go on to the next state DXDY: //calculate dx & dy and plot initial (x0,y0) coordinates state <= CALC1; //go on to the next state CALC1: //calculate 'D' for dy>dx and dx>=dy state <= CALC2; //go on to next state CALC2: //use 'steep' to determine if dx/dy swapping is necessary state <= PLOT; //go on to next state PLOT: if (steep) begin if (y0 + 1 <= y1) state <= CALC2; else state <= LOAD; end else begin if (x0 + 1 <= x1) state <= CALC2; else state <= LOAD; end endcase end always @(posedge clk) begin case (state) LOAD: //1st clk: load values into (x0,y0) & (x1,y1) begin x0 <= 0; y0 <= 0; x1 <= 10; y1 <= 0; end DXDY: //2nd clk: figure dx & dy, output initial coordinates: (x0,y0) begin dx <= x1 - x0; dy <= y1 - y0; X <= x0; Y <= y0; //plot first coordinate before changing x0 & y0. end CALC1: //3rd clk: based on dx and dy, start swapping dx and dy within the error accumulator if (dx >= dy) begin //if dy>dx, swap dx and dy steep <= 0; D <= (dy*2 - dx); //calculate the initial error value when x is the greater axis end else begin steep <= 1; D <= (dx*2 - dy); //calculate the initial error value when y is the greater axis end CALC2: //4th clk: after error is calculated, perform the x,y advance based on the error accumulator if (steep) begin //if dy>dx, swap dx and dy if ( D[16] == 0 ) begin //test for when error accumulator is negative value x0 <= x0 + 1; //then y0 <= y0 + 1; //go diagonal D <= D + (dx*2 - dy*2); //accumulate the error end else begin y0 <= y0 + 1; //increment on the greater axis D <= D + dx*2; end end else if ( D[16] == 0 ) begin //dx>dy here: test for when error accumulator is negative value x0 <= x0 + 1; //then y0 <= y0 + 1; //go diagonal D <= D + (dy*2 - dx*2); //accumulate the error end else begin x0 <= x0 + 1; //increment on the greater axis D <= D + dy*2; end PLOT: //5th clk: output values begin X <= x0; Y <= y0; end endcase end endmodule |
Author: | ElEctric_EyE [ Sun Apr 14, 2013 10:00 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
There is one thing left I'm in the process of completing and that is the case of an opposite slope, e.g. (0,10) to (10,0) where the dy is negative since the plotting is being done left to right in all instances. Once this is done, all other possible combinations will just require a swapping of start/endpoints. Although I have already tried 2x and gave up. I will re-study what I've done successfully up to this point, make some notes and then maybe start from scratch, althought I have 1 more idea to try tonight involving the current code. |
Author: | ElEctric_EyE [ Mon Apr 15, 2013 12:57 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
Success! 1 case left to consider: -dy, steep. -dy, !steep works.: Code: module LineGen ( input clk,
output reg [9:0] X = 0, //LSB of RAM address output reg [8:0] Y = 0 //MSB of RAM address ); reg [9:0] x0, x1, dx; //internal module registers reg [8:0] y0, y1, dy; reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative reg steep; //1 when dy>dx reg dyneg; //1 when dy is negative reg [2:0] state; parameter LOAD = 0, DXDY = 1, CALC1 = 2, CALC2 = 3, PLOT = 4; always @(posedge clk) begin state <= LOAD; case (state) LOAD: state <= DXDY; DXDY: state <= CALC1; CALC1: state <= CALC2; CALC2: state <= PLOT; PLOT: begin if (!dyneg && steep) begin //e.g. (0,0) to (2,10) if (y0 + 1 <= y1) state <= CALC2; else state <= LOAD; end if (!dyneg && !steep) begin //e.g. (0,0) to (10,10) if (x0 + 1 <= x1) state <= CALC2; else state <= LOAD; end if (dyneg && !steep) begin //e.g. (0,10) to (10,0) if (y1 != y0) state <= CALC2; else state <= LOAD; end end endcase end always @(posedge clk) begin case (state) LOAD: begin x0 <= 0; y0 <= 0; x1 <= 20; y1 <= 20; if (y0 >= y1) dyneg <= 1; else dyneg <= 0; end DXDY: begin dx <= x1 - x0; X <= x0; Y <= y0; if (dyneg) dy <= y0 - y1; else dy <= y1 - y0; end CALC1: if (dx >= dy) begin steep <= 0; D <= (dy*2 - dx); end else begin steep <= 1; D <= (dx*2 - dy); end CALC2: if (steep) begin if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= y0 + 1; D <= D + (dx*2 - dy*2); end else begin y0 <= y0 + 1; D <= D + dx*2; end end else if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + (dy*2 - dx*2); end else begin x0 <= x0 + 1; D <= D + dy*2; end PLOT: begin X <= x0; Y <= y0; end endcase end endmodule |
Author: | ElEctric_EyE [ Mon Apr 15, 2013 11:37 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
I couldn't reliably test for dyneg in the LOAD state, so I had to add 1 more state, which doesn't really slow things down any as the main loop is still CALC2 --> PLOT --> CALC2... Plus a minor correction or two. Hopefully I can get this finished today so I can start working on melding it to the project. I'm optimistic this LineGen module coding is tight because top speed of the module itself has not changed since the beginning stage, @180MHz... So far these coordinates work in ISim: Code: (0,0) to (20,20) (0,20) to (20,0) (0,0) to (20,2) (0,0) to (2,20) Code: module LineGen ( input clk,
output reg [9:0] X = 0, //LSB of RAM address output reg [8:0] Y = 0 //MSB of RAM address ); reg [9:0] x0, x1, dx; //internal module registers reg [8:0] y0, y1, dy; reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative reg steep; //1 when dy>dx reg dyneg; //1 when dy is negative reg [2:0] state; parameter LOAD = 0, SLOPE = 1, DXDY = 2, CALC1 = 3, CALC2 = 4, PLOT = 5; always @(posedge clk) begin state <= LOAD; case (state) LOAD: state <= SLOPE; SLOPE: state <= DXDY; DXDY: state <= CALC1; CALC1: state <= CALC2; CALC2: state <= PLOT; PLOT: begin if (!dyneg && steep) begin //e.g. (0,0) to (2,10) if (y0 != y1) state <= CALC2; else state <= LOAD; end if (!dyneg && !steep) begin //e.g. (0,0) to (10,10) if (x0 != x1) state <= CALC2; else state <= LOAD; end if (dyneg) begin //e.g. (0,10) to (10,0) if (y1 != y0) state <= CALC2; else state <= LOAD; end end endcase end always @(posedge clk) begin case (state) LOAD: begin x0 <= 0; y0 <= 0; x1 <= 2; y1 <= 20; end SLOPE: if (y0 > y1) dyneg <= 1; else dyneg <= 0; DXDY: begin dx <= x1 - x0; X <= x0; Y <= y0; if (dyneg) dy <= y0 - y1; else dy <= y1 - y0; end CALC1: if (dx >= dy) begin steep <= 0; D <= (dy*2 - dx); end else begin steep <= 1; D <= (dx*2 - dy); end CALC2: if (steep) begin if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + (dx*2 - dy*2); end else begin y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + dx*2; end end else if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + (dy*2 - dx*2); end else begin x0 <= x0 + 1; D <= D + dy*2; end PLOT: begin X <= x0; Y <= y0; end endcase end endmodule |
Author: | BitWise [ Mon Apr 15, 2013 12:05 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
Are you drawing the last pixel in the lines you are generating? Its quite common not to plot the last pixel so that vertices are not double drawn when ploting a succession of lines around a polygon, especially if the pixel values are being XOR'd into display memory. |
Author: | ElEctric_EyE [ Tue Apr 16, 2013 1:05 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
BitWise wrote: Are you drawing the last pixel in the lines you are generating? Its quite common not to plot the last pixel so that vertices are not double drawn when ploting a succession of lines around a polygon, especially if the pixel values are being XOR'd into display memory. Hi Bitwise! No to your first question... And, I'll remember that pointer about the vertices because I believe the code is complete and real world testing is about to start. Sorry about the lack of comments, but reading over my last post of the code with comments just seemed pretentious, also it was confusing me because the code was still changing. I guess comments should be saved for last! My code seems to work for any numbers I throw at it, for the Start/End coordinates. Please let me know if anyone sees a problem. Code: module LineGen ( input clk,
output reg [9:0] X = 0, //LSB of RAM address output reg [8:0] Y = 0 //MSB of RAM address ); reg [9:0] x0, x1, dx; //internal module registers reg [8:0] y0, y1, dy; reg [16:0] D; //error accumulator + carry bit. if D[16] = 1, it is negative reg steep; //1 when dy>dx reg dyneg; //1 when dy is negative reg [2:0] state; parameter LOAD = 0, SLOPE = 1, DXDY = 2, CALC1 = 3, CALC2 = 4, PLOT = 5; always @(posedge clk) begin state <= LOAD; case (state) LOAD: state <= SLOPE; SLOPE: state <= DXDY; DXDY: state <= CALC1; CALC1: state <= CALC2; CALC2: state <= PLOT; PLOT: begin if (!dyneg && steep) //e.g. (0,0) to (2,10) if (y0 != y1) state <= CALC2; else state <= LOAD; if (!dyneg && !steep) //e.g. (0,0) to (10,10) if (x0 != x1) state <= CALC2; else state <= LOAD; if (dyneg && !steep) //e.g. (0,10) to (10,0) if (x0 != x1) state <= CALC2; else state <= LOAD; if (dyneg && steep) //e.g. (0,20) to (2,0) if (y0 != y1) state <= CALC2; else state <= LOAD; end endcase end always @(posedge clk) begin case (state) LOAD: begin x0 <= 0; y0 <= 20; x1 <= 2; y1 <= 0; end SLOPE: if (y0 > y1) dyneg <= 1; else dyneg <= 0; DXDY: begin dx <= x1 - x0; X <= x0; Y <= y0; if (dyneg) dy <= y0 - y1; else dy <= y1 - y0; end CALC1: if (dx >= dy) begin steep <= 0; D <= (dy*2 - dx); end else begin steep <= 1; D <= (dx*2 - dy); end CALC2: if (steep) begin if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + (dx*2 - dy*2); end else begin y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + dx*2; end end else if ( D[16] == 0 ) begin x0 <= x0 + 1; y0 <= dyneg ? y0 - 1: y0 + 1; D <= D + (dy*2 - dx*2); end else begin x0 <= x0 + 1; D <= D + dy*2; end PLOT: begin X <= x0; Y <= y0; end endcase end endmodule |
Author: | ElEctric_EyE [ Tue Apr 16, 2013 1:19 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
Some info from the console: Code: NFO:Xst:1767 - HDL ADVISOR - Resource sharing has identified that some arithmetic operations in this design can share the same physical resources for reduced device utilization. For improved clock frequency you may try to disable resource sharing. Code: ========================================================================= Advanced HDL Synthesis Report Macro Statistics # Adders/Subtractors : 11 10-bit adder : 1 10-bit subtractor : 2 11-bit subtractor : 1 12-bit subtractor : 3 17-bit adder : 3 9-bit subtractor : 1 # Counters : 1 10-bit up counter : 1 # Registers : 80 Flip-Flops : 80 # Comparators : 4 10-bit comparator greater : 1 10-bit comparator not equal : 1 9-bit comparator greater : 1 9-bit comparator not equal : 1 # Multiplexers : 16 17-bit 2-to-1 multiplexer : 8 3-bit 2-to-1 multiplexer : 4 32-bit 2-to-1 multiplexer : 1 9-bit 2-to-1 multiplexer : 3 ========================================================================= Code: Asynchronous Control Signals Information:
---------------------------------------- No asynchronous control signals found in this design Timing Summary: --------------- Speed Grade: -3 Minimum period: 5.535ns (Maximum Frequency: 180.665MHz) Minimum input arrival time before clock: No path found Maximum output required time after clock: 3.597ns Maximum combinational path delay: No path found ========================================================================= Process "Synthesize - XST" completed successfully |
Author: | ElEctric_EyE [ Wed Apr 17, 2013 1:01 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
I added in the check for when x0>x1, so now it'll plot any coordinate except when x0=x1=y0=y1. That's untested. I made a video of a test I did similar to the last video, except this one I had to slow down with a large delay between each line. You get to see my dog too, lol. You can tell it doesn't like being filmed. The delay is a 16x countdown from 65535 to 0, so over 1 million cycles. I still have to figure out why the RAM is getting zero's for the pixel value. VIDEO |
Author: | ElEctric_EyE [ Wed Apr 17, 2013 8:59 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
I figured it out, but the fix took just awhile longer. After I found the problem in the SRAM interface module, I had to figure out bus contention between when the cpu was sending data to RAM and the LineGen module was sending addresses with the intended data also coming from the cpu. In the end, it was easiest to make it so all pixel data comes from the B accumulator. I had to rewrite to clearscreen routine which was using the C accumulator for the background. Now it is working apparently flawlessly. At one point I was stretching the RAMWE signal from the LineGen module with another case statement after the PLOT. I now see the value in CASE vs' IF statements. Using CASE one can control what happens in each and every cycle. Luckily the project still running at 100MHz, also without stretching the RAMWE signal. Whew! Now I intend to do the line test by modifying it to clear the last line drawn. I would expect flickering, so then I am going to experiment with page flipping the videoRAM. EDIT: There I go again making bold and grandiose statements. I still have much to learn. |
Author: | ElEctric_EyE [ Fri Apr 19, 2013 1:49 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
So I have this code: Code: always @(posedge clk) begin that I would like to make into a parallel case statement. In a regular case statement each case is tested on the consecutive clocks. A parallel case considers each case at the same time which I need here. I've read all that is needed is a comment that is directed to the synthesizer. Is this true? if (lineCS && cpuAB == 2'b00) x0t <= cpuDO; if (lineCS && cpuAB == 2'b01) y0t <= cpuDO; if (lineCS && cpuAB == 2'b10) x1t <= cpuDO; if (lineCS && cpuAB == 2'b11) y1t <= cpuDO; end I'm trying to convert to case in order to compare resources used and also see the differences in what the console outputs. |
Author: | Arlet [ Fri Apr 19, 2013 5:31 am ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
You don't have to worry about the case statement. Every case is always tested on every clock. The difference between a "parallel" case, and a regular one, is that the parallel case does not have overlapping case expressions. Overlapping case expressions can lead to priority encoding, which can require more logic to implement. Note that you can only have overlapping case expressions if you use casez/casex. |
Author: | ElEctric_EyE [ Fri Apr 19, 2013 6:51 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
Thanks! Shouldn't I be able to do a load and a compare on the same cycle? or do you have any suggestions for improvement? |
Author: | Arlet [ Fri Apr 19, 2013 6:56 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
I'm not sure what load and compare you are talking about... |
Author: | ElEctric_EyE [ Fri Apr 19, 2013 7:24 pm ] |
Post subject: | Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards |
I don't have the newest code posted yet, but for instance shouldn't I be able to do a LOAD and SLOPE from that last version I posted? If I wasn't doing a synchronous always block(always @(posedge clk) and was using a combinatorial always block(always @*), I'm sure it could be done simultaneous. |
Page 30 of 41 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |