On 10/3/06, Nicholas <[EMAIL PROTECTED]> wrote:
> > > // 800 X 600 @ 60Hz with a 40.000MHz pixel clock
> > module sync_const; > > > > I'm going to have a look at your code tomorrow. After putting in param instead of specparam, I finally got it to compile, so this new version actually runs! I used "iverilog testModule.v -o testVideo; ./testVideo" to run it. Be forewarned, however; it takes a really, really long time for the vertical to change (with a bunch of printing, it takes a while per horizontal scan).
It might help to comment out the messages and use GTKWave to view the waveform graphically.
I need to make this synthesizable by removing the initial block, correct?
Yes. We have a reset signal, and the form of the code is: always @(posedge clock or negedge reset) begin if (!reset) begin initial stuff end else begin normal stuff end end
Also, I think my clockx2 is messed up. I am correct in thinking that the data is changed with each clock_2x change of polarity? Besides the clock issues, this *should* work.
No. The 2x clock is used here ONLY for generating the clock signal for the analog output. The DAC wants data at single-data-rate, but we're producing it at double-data-rate. So, we satisfy it by generating a separate clock for it that transitions twice as fast as our internal clock. The data going to the DAC is changed with each clock change of polarity. The data going to the DAC is changed with each rising edge of clock_2x.
// 800 X 600 @ 60Hz with a 40.000MHz pixel clock module sync_const; parameter H_ACTIVE = 800, // pixels H_FRONT_PORCH = 40, // pixels H_SYNCH = 128, // pixels H_BACK_PORCH = 88, // pixels H_TOTAL = 1056, // pixels V_ACTIVE = 600, // lines V_FRONT_PORCH = 1, // lines V_SYNCH = 4, // lines V_BACK_PORCH = 23, // lines V_TOTAL = 628; // lines parameter SYNC_DATA_STATE=0, PORCH_DATA_STATE=1, COLOR_DATA_STATE=0; wire clock; wire clock_2x; wire reset; wire [29:0] vidout; reg [29:0] vid_data; //29:20 R, 19:10 G, 9:0 B reg clk; reg [9:0] vert; //current vertical scanline location reg [11:0] horiz; //current pixel in scanline reg [1:0] hstate; //horizontal and vertical states reg [1:0] vstate; //so it is easier to ref them. assign clock=clk; initial begin vert<=0; horiz<=0; clk<=0; hstate<=0; vstate<=0; end
Just move this initial stuff into the reset section.
always begin #5 clk=~clk; end
Move this into the external test bench. So take the module template I provided already and wrap it with another module (that has no ports), wherein you generate the clock and reset signals. You can have a look at the memory controller's memctl_test.v to see how I do this, but here's roughly what you need to do for those signals. initial begin clock = 0; forever begin clock = !clock; #10; end end initial begin clock_2x = 0; forever begin clock_2x = !clock_2x; #5; end end I do the delays after because I want to control where the two clocks have coincident edges. That is, every rising edge of 2x is coincident with a transition of clock. initial begin reset = 0; #100; reset = 1; end
always @(posedge clk) begin horiz <= horiz + 1; if (horiz>H_TOTAL)
For synthesis, use the == operator. Let's make horiz count from 0 to H_TOTAL-1. Note that the nonblocking assignment there does NOT affect the value of horiz used in the comparison. So do the increment and compare horiz to H_TOTAL-1. If it's equal, then assign 0 to horiz. This way, horiz rolls directly from H_TOTAL-1 back to zero.
begin hstate <= 0; horiz <=0; vert <= vert + 1;
Just to make it easier to read, you can get rid of the else here. These conditions are all mutually exclusive. Taking out the elses won't actually change the logic. On the other hand, if you wanted to reduce and speed up the logic (not that it matters HERE), you could do this: case (horiz) H_TOTAL-1: begin ... end H_SYNCH + H_FRONT_PORCH + H_ACTIVE-1: begin ... end H_FRONT_PORCH + H_ACTIVE-1: begin ... end H_ACTIVE-1: begin ... end endcase These are all == comparisons, and note the -1 in each one. (These sums are all constants, so the synthesizer will not generate useless logic for them.) Do the same for vertical. For the most part, you can do the vertical logic separately, but when you increment vertical in the horizontal section, you need to make it roll over there too. vert needs to stay at V_TOTAL-1 until after the last cycle where horiz==H_TOTAL-1. This is looking really good. Keep hacking at it, and we'll have some great test logic for me to use, and you're saving me heaps of time. Thanks!
end else if (horiz > H_SYNCH + H_FRONT_PORCH + H_ACTIVE) begin hstate <= 3; end else if (horiz > H_FRONT_PORCH + H_ACTIVE) begin hstate <= 2; end else if (horiz > H_ACTIVE) begin hstate <= 1; end //now all the states are correct: //0) Active - White. //1) Front Porch. //2) Sync signal. 0. //3) Back Porch. //Now set up Vert in the same way... if (vert>V_TOTAL) begin hstate <= 0; horiz <=0; vert <=0; vstate <=0; // new frame end else if (vert > V_SYNCH + V_FRONT_PORCH + V_ACTIVE) begin vstate <= 3; end else if (vert > V_FRONT_PORCH + V_ACTIVE) begin vstate <= 2; end else if (vert > V_ACTIVE) begin vstate <= 1; end //now all is ready. //insert here the code to make colors based //on the various values. //example: just sync signals. if (vstate==2) //sync state begin vid_data<=SYNC_DATA_STATE; end if (hstate==2) //sync state begin vid_data<=SYNC_DATA_STATE; end if (hstate==1 || hstate==3) //porch state begin vid_data<=PORCH_DATA_STATE; end if (vstate==1 || vstate==3) //sync state begin vid_data<=PORCH_DATA_STATE; end if (hstate==0 && vstate==0) //draw state begin vid_data<=COLOR_DATA_STATE; end $display("%g time; hstate %d, vstate %d. horiz=%d, vert=%d.\n", $time,hstate,vstate,horiz,vert); end //head0_video_out u0(clock,clock_2x,reset,vidout,,,,,,,); endmodule
_______________________________________________ Open-graphics mailing list Open-graphics@duskglow.com http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)