6502.org http://forum.6502.org/ |
|
n00b Verilog Questions http://forum.6502.org/viewtopic.php?f=10&t=2666 |
Page 3 of 5 |
Author: | ElEctric_EyE [ Wed Oct 02, 2013 7:40 pm ] |
Post subject: | Re: n00b Verilog Questions |
Instead of thinking of it that way, where 'countflag' is used as the flag to be monitored and delayed, maybe it's better to delay the previous signals that trigger 'countflag'. 'hstart' triggers 'countflag' positive, 'hblank' triggers 'countflag' negative. Would it make sense to delay 'hstart' & 'hblank'? |
Author: | Arlet [ Wed Oct 02, 2013 7:49 pm ] |
Post subject: | Re: n00b Verilog Questions |
I think the most natural solution is to look at incoming hsync/vsync, sync on those, and make new hstart/hblank. |
Author: | ElEctric_EyE [ Tue Oct 08, 2013 10:37 am ] |
Post subject: | Re: n00b Verilog Questions |
I've hit a block... Centering horizontal is not a problem. Delaying HSYNCin by 5 cycles does that well enough. Centering vertical has been a real challenge. Delaying any one signal by the needed 11 cycles results in no visible change in vertical position. Ive tried delaying the VSYNCin, venable and vcount_done signals individually. I thought for sure I had it when I noticed venable controls the down counter and the vertical state machine, but nothing. I don't think I'm too far off the solution am I? |
Author: | Arlet [ Tue Oct 08, 2013 4:09 pm ] |
Post subject: | Re: n00b Verilog Questions |
Instead of looking at delaying signals, I think you should try to sync the state machines. So, the first board is just free running, and determines the timing, and the second and subsequent boards try to sync their state machine. Syncing can be done by halting the state machine in a certain state, and waiting until the incoming signals are at the same point, and then releasing the state machine again. I don't understand why you have 5 and 11 cycles delay. Doesn't the delay depend on when the boards are switched on ? |
Author: | ElEctric_EyE [ Tue Oct 08, 2013 7:03 pm ] |
Post subject: | Re: n00b Verilog Questions |
Thank you for tolerating my struggles, I apologize to everyone else. This is the last thorn... All 4 boards are sync'd, i.e. when I hit reset any any one of them all 4 pixel streams are still sync'd after initial powerup, they are just skewed. Soon I'll post a block diagram of how I have the signals routed, and also post your vga generator I modified. I would like to continue this discussion in the proper thread. |
Author: | ElEctric_EyE [ Thu Oct 24, 2013 12:45 am ] |
Post subject: | Concatenation in Verilog |
Another n00b question regarding Verilog and concatenation of bits using the '{}' operator. Is it {MSb,LSb}? which I would have found more logical, but has always thrown me in a loop. Or {LSb,MSb}? I just need confirmation. Is this really correct thinking? |
Author: | Rob Finch [ Thu Oct 24, 2013 12:59 am ] |
Post subject: | Re: n00b Verilog Questions |
Quote: Is it {MSb,LSb}? which I would have found more logical, It's {MSB...LSB}. MSB on the left, LSBs to the right. I've been following along, and I don't understand why the VSYNC signal would need significant delays. It can't be out more than a few clock cycles. Shouldn't the propagation delay in the VSYNC be about the same as the delay in the HSYNC ? |
Author: | ElEctric_EyE [ Thu Oct 24, 2013 1:16 am ] |
Post subject: | Re: n00b Verilog Questions |
That's what I would have thought as well... Thanks Rob! Let me finish the block diagram... My lack of understanding hinders me, but I still make progress... What I can say is any delays I have put on any of the signals that affect VSYNC do not actually delay pixel output vertically. Which is why I've had to resort to delaying horizontally "a great many cycles" in order to align vertically. For example, in order to delay 2 pixels vertically, I have had to delay the 'hstart' signal by 2x1024 cycles. This has worked but it is not efficient and I am puzzled why delaying a VSYNC signal differs from delaying an HSYNC signal. |
Author: | Arlet [ Thu Oct 24, 2013 5:22 am ] |
Post subject: | Re: n00b Verilog Questions |
For vertical offset, keep in mind that you'd have to delay vsync in steps of a whole line, which is in effect "a great many cycles" if you count the pixels, but is only a small number if you count hlines. But the question remains why you'd need such fixed offsets anyway. |
Author: | ElEctric_EyE [ Fri Oct 25, 2013 1:28 am ] |
Post subject: | Re: n00b Verilog Questions |
Arlet wrote: ...But the question remains why you'd need such fixed offsets anyway. I think it may have to do with how I am attempting to sync the state machines used in your vga module between successive boards. When a positive HSYNCin or VSYNCin is detected, it resets the appropriate counters just like the hcount_ done and vcount_done signals do. Code: ...// adjust down counter. Reload when it's done. always @(posedge clk) if ( HSYNCin | hcount_done ) hcount <= { 1'b0, hload };... Code: ...// adjust down counter. Reload when it's done. always @(posedge clk) if( venable ) begin if ( VSYNCin | vcount_done ) vcount <= { 1'b0, vload };... Also, when HSYNCin or VSYNCin goes active, The state machine is forced to the VIDEO state. Maybe this is wrong? But when I try to sync to any other state, I see no video. Code: ...// when down counter is done, go to next state always @(posedge clk) if( hcount_done ) case( hstate ) VIDEO : hstate <= FRONT; FRONT : hstate <= SYNC; SYNC : hstate <= BACK; BACK : hstate <= VIDEO; endcase else if (HSYNCin) hstate <= VIDEO;... Code: ...// when down counter is done, go to next state
always @(posedge clk) if( venable & vcount_done ) case( vstate ) VIDEO : vstate <= FRONT; FRONT : vstate <= SYNC; SYNC : vstate <= BACK; BACK : vstate <= VIDEO; endcase else if (VSYNCin) vstate <= VIDEO;... |
Author: | ElEctric_EyE [ Wed Nov 06, 2013 7:50 pm ] |
Post subject: | Re: n00b Verilog Questions |
...unrelated to previous questions... For a signal that is common to some modules, is it best to have the logic that derives that signal on the top level? For example, if I need a display enable signal, 3 signals are needed to generate it: hstart, hblank and vblank. I could generate the display enable within it's own module and output it to other modules, or I could generate it on the top_level. What is the accepted method in Verilog? |
Author: | MichaelM [ Wed Nov 06, 2013 8:01 pm ] |
Post subject: | Re: n00b Verilog Questions |
I would place it at the level most appropriate for the functional decomposition of your system. If you have a sub-module whose function is video control, I'd put it in that module, and bring it up to the top module and distribute it from there. However, if you don't have a module whose function is video control, I'd generate the signal in the top module until such time as there's a need to create a video control module. |
Author: | ElEctric_EyE [ Wed Nov 06, 2013 9:17 pm ] |
Post subject: | Re: n00b Verilog Questions |
Michael, thanks for the pointer, what you say makes sense maybe I'm getting tunnel vision. Just FYI, Arlet's original .vga controller outputs hstart, hblank, vstart and vblank. Maybe it's a clue... But let's say for arguments' sake that I modify that video control module to output a display enable signal: Code: //display enable always @(posedge clk) if ( hstart ) countflag <= 1; else if ( hblank | vblank ) countflag <= 0; So it uses 3 signals and no other modules use those signals. But another module, the external RAM interface, uses the vstart signal to start the pixel counter used for the address: Code: // pixel counters for 2MBx18 external SyncRAM reg [9:0] X; reg [9:0] Y; always @(posedge clk) if ( vstart | X == 1023 & Y == 767 ) begin X <= 0; Y <= 0; end else if ( X == 1023 ) begin Y <= Y + 1; X <= 0; end else if ( countflag ) X <= X + 1; If the situation were reversed and 3 signals were used externally, and 1 internal would it be best to have this code present in the top module? What about 2 external and 2 internal? or will the tools just figure this stuff out? So far in my testing I haven't noticed any change but I am chasing down a problem, so I'm 'getting my ducks in a row'. Thanks! |
Author: | Arlet [ Wed Nov 06, 2013 9:21 pm ] |
Post subject: | Re: n00b Verilog Questions |
I would probably make a separate module to fetch bitmaps from memory, and send the pixel data to the video output, so that the external RAM interface would just offer a multi-port generic memory interface, without any dependency on pixels or screen sizes. |
Author: | ElEctric_EyE [ Wed Nov 06, 2013 10:06 pm ] |
Post subject: | Re: n00b Verilog Questions |
Arlet, I think you're right. Everything seems jumbled now. I am dealing with code that I wrote when I first started learning Verilog. I had some early successes, but they weren't necessarily correct. I'm now having a problem generating a simple border using one video board! I hate to realize this, but I may have to start from scratch... But before I do I would like to ask you Verilog experts how to go about making a piece of code sleeker. It is the Line and circle hardware plotter... I put delays in there to make the simulations look correct and in real life it works, but the code is not pretty. What is the simplest structural change I can make to make this more efficient? Thanks for your input all! Code: `timescale 1ns / 1ps
module LineGen ( input clk, input lineCS, input [15:0] cpuDO, input [3:0] cpuAB, input countflag, input [15:0] SRD, output reg RAMWE, output reg LGREADY, output reg [aw:0] X, output reg [aw:0] Y, output reg [15:0] color, output reg [15:0] border ); parameter aw = 10; //2048 //blitter variables reg [15:0] bXlen, bYlen; reg [aw:0] bXc, bYc, bXp, bYp; //linegen variables reg [aw:0] x0, x1, dx, x0t, x1t, y0, y1, dy, y0t, y1t; //internal module registers reg [aw+1:0] D; //error accumulator + carry bit. if D[aw+1] = 1, it is negative reg [0:0] steep, //1 when dy>dx dyneg, //1 when dy is negative dxneg; //1 when dx is negative //circle variables reg [aw:0] xc, yc, rad, x, y = 0; reg [aw+1:0] raderr; reg [4:0] state; parameter WAIT = 0, LOAD = 1, SLOPE = 2, DXDY = 3, CALC1 = 4, CALC2 = 5, PLOT = 6, CALC3 = 7, CALC4 = 8, OCT1 = 9, OCT2 = 10, OCT3 = 11, OCT4 = 12, OCT5 = 13, OCT6 = 14, OCT7 = 15, OCT8 = 16, DEL1 = 17, DEL2 = 18, DEL3 = 19, DEL4 = 20, DEL5= 21, DEL6 = 22, DEL7 = 23, DEL8 = 24; always @(posedge clk) begin if (lineCS && cpuAB == 4'b0000) //variables for line generator x0t <= cpuDO; if (lineCS && cpuAB == 4'b0001) y0t <= cpuDO; if (lineCS && cpuAB == 4'b0010) x1t <= cpuDO; if (lineCS && cpuAB == 4'b0011) y1t <= cpuDO; if (lineCS && cpuAB == 4'b0100) //variables for circle generator xc <= cpuDO; if (lineCS && cpuAB == 4'b0101) yc <= cpuDO; if (lineCS && cpuAB == 4'b0110) rad <= cpuDO; if (lineCS && cpuAB == 4'b0111) //color variable color <= cpuDO; if (lineCS && cpuAB == 4'b1000) //X length of blitter bXlen <= cpuDO; if (lineCS && cpuAB == 4'b1001) //Y length of blitter bYlen <= cpuDO; if (lineCS && cpuAB == 4'b1010) //X start copy bXc <= cpuDO; if (lineCS && cpuAB == 4'b1011) //Y start copy bYc <= cpuDO; if (lineCS && cpuAB == 4'b1100) //X start paste bXp <= cpuDO; if (lineCS && cpuAB == 4'b1101) //Y start paste bYp <= cpuDO; if (lineCS && cpuAB == 4'b1110) //border color border <= cpuDO; end always @(posedge clk) begin state <= WAIT; case (state) WAIT: begin if (lineCS && cpuAB == 3'b011) //draw a line state <= LOAD; else if (lineCS && cpuAB == 3'b110) //draw a circle state <= CALC3; else state <= WAIT; end 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 CALC3: state <= OCT1; CALC4: state <= OCT1; OCT1: if ( x >= y ) state <= DEL1; else state <= WAIT; DEL1: state <= OCT2; OCT2: state <= DEL2; DEL2: state <= OCT3; OCT3: state <= DEL3; DEL3: state <= OCT4; OCT4: state <= DEL4; DEL4: state <= OCT5; OCT5: state <= DEL5; DEL5: state <= OCT6; OCT6: state <= DEL6; DEL6: state <= OCT7; OCT7: state <= DEL7; DEL7: state <= OCT8; OCT8: state <= DEL8; DEL8: state <= CALC4; endcase end always @(posedge clk) begin case (state) WAIT: begin RAMWE <= 0; LGREADY <= 1; if (x0t > x1t) dxneg <= 1; else dxneg <= 0; end LOAD: begin LGREADY <= 0; if (dxneg) begin x0 <= x1t; y0 <= y1t; x1 <= x0t; y1 <= y0t; end else begin x0 <= x0t; y0 <= y0t; x1 <= x1t; y1 <= y1t; end 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: begin RAMWE <= 0; if (dx >= dy) begin steep <= 0; D <= (dy*2 - dx); end else begin steep <= 1; D <= (dx*2 - dy); end end CALC2: begin RAMWE <= 0; if (steep) begin if ( D[10] == 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[10] == 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 CALC3: begin x <= rad; y <= 0; raderr <= 1 - x; LGREADY <= 0; RAMWE <= 0; end CALC4: begin RAMWE <= 0; y <= y + 1; if ( raderr[10] ) raderr <= raderr + (y+1); else begin x <= x - 1; raderr <= raderr + (y-x)+1; end end OCT1: // | begin // | RAMWE <= 1; // ------- X <= xc + (x); // | Oct1 Y <= yc + y; // | end OCT2: begin // | RAMWE <= 1; // | X <= xc + (y); // ------- Y <= yc + (x); // | end // | Oct2 OCT3: // | begin // | RAMWE <= 1; // ------- X <= xc - x; // Oct3 | Y <= yc + y; // | end OCT4: // | begin // | RAMWE <= 1; // ------- X <= xc - (y); // | Y <= yc + (x); // Oct4 | end OCT5: // | begin // Oct5 | RAMWE <= 1; // ------- X <= xc - (x); // | Y <= yc - y; // | end OCT6: // Oct6 | begin // | RAMWE <= 1; // ------- X <= xc - (y); // | Y <= yc - x; // | end OCT7: // | begin // | Oct7 RAMWE <= 1; // ------- X <= xc + (x); // | Y <= yc - y; // | end OCT8: // | Oct8 begin // | RAMWE <= 1; // ------- X <= xc + (y); // | Y <= yc - (x); // | end DEL1: RAMWE <= 1; //DEL2: // RAMWE <= 1; //DEL3: // RAMWE <= 1; //DEL4: // RAMWE <= 1; //DEL5: // RAMWE <= 1; //DEL6: // RAMWE <= 1; //DEL7: // RAMWE <= 1; //DEL8: // RAMWE <= 1; endcase end endmodule |
Page 3 of 5 | All times are UTC |
Powered by phpBB® Forum Software © phpBB Group http://www.phpbb.com/ |