On 6/16/06, Hamish <[EMAIL PROTECTED]> wrote:
Besides the fact that I have no idea how you'd call it, and that there's no
renderPixel task in it, here's my first attempt at a verilog 'program'. It's
Bresenhams line drawing algorithm. In integer. It assumes that
Inputs are 32 bits unsigned.
It's also untested... I need to deskcheck it & verify no bad logic errors, but
I'm tired, so here it is anyway...
So there's probably errors in there. Foley & Van Dam is good source to verify
the algorithm.
So... Comments... Abuse... Corrections... At least iverilog will compile it
with only the missing renderPixel task...
I haven't checked that your bres algorithm is right, but that's not a
big deal. The point is that you're getting the hang of Verilog.
It turns out that your design will walk over the entire line for any
change in the inputs. Essentially, the simulator would render an
entire line in a single time-step. We do things somewhat like this
for simulation, but it won't synthesize. Of course, you're waiting
for lesson 4, so that's okay. You're doing a lot with what little
I've told you about so far.
****************************************************************
****************************************************************
//
// Draw a line using Bresenhams algorithm...
module bresLine(x0, x1, y0, y1);
input [31:0]x0, x1, y0, y1;
// reg [31:0] diffX=0;
// reg [31:0] diffY=0;
integer diffX=0;
integer diffY=0;
I guess you're using integers so that you have signed numbers. For
math with same-size words (like two addends that are 32-bit), there's
no difference between signed and unsigned. Signed makes a difference
for multiplies and divides, though.
For the most part, I just deal with the unsigned wires and regs and
check the sign bit when I need to. So for a signed greater-than
comparison, you compare the sign bits first, and only when they're the
same do you check the rest of the bits.
reg steep=0;
reg [31:0] startX=0;
reg [31:0] startY=0;
reg [31:0] endX=0;
reg [31:0] endY=0;
integer deltaX;
integer deltaY;
integer error=0;
integer yStep=0;
integer pointX=0;
integer pointY=0;
function [31:0] abs;
input [31:0] value;
integer value;
if(value<0)
begin
abs = 0-value;
There is a unary - operator.
Also, I think it synthesizes to the same logic, but instead of <0, I
would do value[31]. If value were signed, yours would probably more
semantically appropriate. But <0 is always false for unsigned values.
I just noticed that you're overriding the type with "integer value;"
I didn't know you could do that. :)
Anyhow, I tend to check the sign bit with a bit select because I'm
thinking about the physical hardware. In fact, I generally avoid
using integers because they're fixed at 32 bits. I use them for
loops, though, where the integer will not resolve to real hardware.
end
else
begin
abs = value;
end
endfunction
// task renderPixel;
// input [31:0] pointX;
// input [31:0] pointY;
//
//
// endtask;
always @(x0 or x1 or y0 or y1) begin
// Need the diff in x & y
diffX = x1-x0;
diffY = y1-y0;
steep = abs(diffY)>abs(diffX); // Line is steep (>45deg) if dY > dX
// If it's a steep line, swap X & Y so we're drawing a shallow line
if(steep==0)
begin
startX=y0;
startY=x0;
endX=y1;
endY=x1;
end
else
begin
startX=x0;
startY=y0;
endX=x1;
endY=y1;
end
deltaX=endX-startX;
deltaY=abs(endY-startY);
if(startY<endY)
begin
yStep=1;
end else
begin
yStep=-1;
end
pointY=startX;
for(pointX=startX; pointX<endX; pointX=pointX+1)
begin
if(steep)
begin
renderPixel(pointY, pointX);
end
else
begin
renderPixel(pointX, pointY);
end
error=error+deltaY;
if((error<<1) >= deltaX)
begin
pointY=pointY+yStep;
error=error-deltaX;
end
end
end
endmodule
Next, we'll want to turn this into a sequential state machine. :)
_______________________________________________
Open-graphics mailing list
[email protected]
http://lists.duskglow.com/mailman/listinfo/open-graphics
List service provided by Duskglow Consulting, LLC (www.duskglow.com)