Concept & Design of 3.3V Parallel 16-bit VGA Boards

Topics relating to PALs, CPLDs, FPGAs, and other PLDs used for the support or creation of 65-family processors, both hardware and HDL.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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: Select all

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
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

Success! 1 case left to consider: -dy, steep. -dy, !steep works.:

Code: Select all

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
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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: Select all

(0,0)  to (20,20)
(0,20) to (20,0)
(0,0)  to (20,2)
(0,0)  to (2,20)

Code: Select all

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
User avatar
BitWise
In Memoriam
Posts: 996
Joined: 02 Mar 2004
Location: Berkshire, UK
Contact:

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by BitWise »

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.
Andrew Jacobs
6502 & PIC Stuff - http://www.obelisk.me.uk/
Cross-Platform 6502/65C02/65816 Macro Assembler - http://www.obelisk.me.uk/dev65/
Open Source Projects - https://github.com/andrew-jacobs
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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: Select all

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
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

Some info from the console:

Code: Select all

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: Select all

=========================================================================
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: Select all

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
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

ElEctric_EyE wrote:

Code: Select all

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.
Yesterday I tried disabling the 'resource sharing' as was suggested by the programmer(s) of ISE and max speed shot up to 220+MHz just for the module...
So, with confidence I could maintain 100MHz cpu speed, I applied this setting to my current project in the midst of adding in the LineGen module and was able to keep the cpu and all the other modules 4x speed above the 640x480 25MHz video generator module!

I have successfully drawn 4 lines using my LineGen state machine running @100MHz alongside the .b core. I have it set up so that it immediately starts plotting each time after the cpu has sent the last coordinate, i.e. 'y1'. The software sends x0, y0, x1, finally y1. I put a software delay in after sending the final y1 coordinate as I have not yet added in a DONE state to LineGen and it takes 2 cycles for each pixel to be plotted + another 4 cycles for each line total.

Just as I have tried to route the stack page and zero page pointers off cpu, I tried to do the same with the B accumulator, which I want dedicated to the pixel color. This part is not yet correct as the FPGA is writing '0's to the external SyncRAM instead of the B accumulator value that I can see in ISim correctly as a yellow value 'FFE4' (although it looks blue in the pic). More work is needed, but I am very pleased with the progress, and the Spartan6 product. :D

The 4 line coordinates are (swapping is still needed as not all coordinates functioned correctly):

Code: Select all

(0,0) to (320,240)
(320,240) to (639,0)
(320,240) to (639,479) 
(0,479) to (320,240)
So in the name of the projects' progress I think I should post the LineGen, especially since it will be the last post on this page:

Code: Select all

`timescale 1ns / 1ps

module LineGen ( input clk,
					  input lineCS,
					  input [15:0] cpuDO,
					  input [1:0] cpuAB,
					  output reg RAMWE,
                 output reg [9:0] X,
					  output reg [8:0] Y   
               );
               
reg [9:0] x0, x1, dx, x0t, x1t;   //internal module registers
reg [8:0] y0, y1, dy, y0t, y1t;
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 WAIT = 0, LOAD = 1, SLOPE = 2, DXDY = 3, CALC1 = 4, CALC2 = 5, PLOT = 6;

always @(posedge clk) begin
	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
					
always @(posedge clk) begin
   state <= WAIT;

      case (state)
			WAIT:
				if (lineCS && cpuAB == 2'b11)
						  state <= LOAD;
					else state <= WAIT;
			
			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 <= WAIT;
               
            if (!dyneg && !steep)         //e.g. (0,0) to (10,10)
               if (x0 != x1)
                    state <= CALC2;
               else state <= WAIT;
       
            if (dyneg && !steep)          //e.g. (0,10) to (10,0)
               if (x0 != x1)
                    state <= CALC2;
               else state <= WAIT;

            if (dyneg && steep)            //e.g. (0,20) to (2,0)
               if (y0 != y1)
                    state <= CALC2;
               else state <= WAIT;
         end
			
      endcase
end

always @(posedge clk) begin
   case (state)
		WAIT:
			RAMWE <= 0;
		
		LOAD:
			begin
				x0 <= x0t;
				y0 <= y0t;
				x1 <= x1t;
				y1 <= y1t;					
         end
     
      SLOPE:
         if (y0 > y1)
              dyneg <= 1;
         else dyneg <= 0;
         
      DXDY:               
         begin           
            dx <= x1 - x0;
				RAMWE <= 1;
            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:
			begin
			RAMWE <= 0;
         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
			end
         
      PLOT:   
         begin
				RAMWE <= 1;
            X <= x0;
            Y <= y0;
         end
		
   endcase

end

endmodule
Attachments
640x480 resolution. Daryl's Bresenham circle and 4 lines from LineGen.
640x480 resolution. Daryl's Bresenham circle and 4 lines from LineGen.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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. :roll: I still have much to learn.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

So I have this code:

Code: Select all

always @(posedge clk) begin
	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
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?
I'm trying to convert to case in order to compare resources used and also see the differences in what the console outputs.
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by Arlet »

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.
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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?
User avatar
Arlet
Posts: 2353
Joined: 16 Nov 2010
Location: Gouda, The Netherlands
Contact:

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by Arlet »

I'm not sure what load and compare you are talking about...
ElEctric_EyE
Posts: 3260
Joined: 02 Mar 2009
Location: OH, USA

Re: Concept & Design of 3.3V Parallel 16-bit VGA Boards

Post by ElEctric_EyE »

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.
Post Reply