Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- module line_drawer(x1, y1, x2, y2, VGA_SYNC, VGA_CLK,
- data_reg, reset, color, command,
- available,
- my_id,
- id_req,
- xAddr, yAddr,
- write_clk,
- is_write_finished
- );
- input wire signed [10:0] x1, y1, x2, y2;
- input wire VGA_SYNC, VGA_CLK;
- output reg [15:0] data_reg; //memory data register for SRAM
- input wire reset;
- input wire [15:0] color;
- input wire [1:0] command;
- output wire available;
- input wire [3:0] my_id, id_req;
- output reg write_clk;
- input wire is_write_finished;
- output reg [9:0] xAddr;
- output reg [8:0] yAddr;
- //state machine
- reg [2:0] state, next_state;
- // absolute values of dx, dy, e
- wire signed [10:0] absdx, absdy;
- assign absdx = (x2>x1) ? (x2-x1) : (x1-x2);
- assign absdy = (y2>y1) ? (y2-y1) : (y1-y2);
- // initial value of e should be negative
- wire signed [10:0] nege;
- assign nege = ((absdy - absdx) < 0) ? (absdy-absdx) : (absdx-absdy);
- // whether or not x is the DA
- wire xDA;
- assign xDA = (absdx > absdy);
- // signs of dx and dy (0 = positive, 1 = negative)
- wire dxsign, dysign;
- assign dxsign = ((x2-x1) < 0);
- assign dysign = ((y2-y1) < 0);
- // value to increment e by
- wire signed [10:0] einc;
- assign einc = (xDA) ? (absdy) : (absdx);
- // value to decrement e by
- wire signed [10:0] edec;
- assign edec = (xDA) ? (absdx) : (absdy);
- // value to increment i and j by
- wire signed [10:0] iinc, jinc;
- assign iinc = (xDA) ? (dxsign ? (-1) : (1)) : (dysign ? (-1): (1));
- assign jinc = (xDA) ? (dysign ? (-1) : (1)) : (dxsign ? (-1): (1));
- // finish indicates when line is finished drawing
- wire finish, xfinish, yfinish;
- // if x-increment is negative, stop when i is less than x2, etc.
- assign xfinish = (dxsign) ? (i < x2) : (i > x2);
- // if y-increment is negative, stop when i is less than x2, etc.
- assign yfinish = (dysign) ? (i < y2) : (i > y2);
- // if DA is x, check x for done drawing, else check y
- assign finish = (xDA) ? (xfinish) : (yfinish);
- reg available_reg;
- assign available = available_reg;
- // for Bresenham's Algorithm
- reg signed [10:0] dy, dx, e, j, i;
- //state names
- parameter
- setup = 3'd0, // initialize Bresenham's algorithm
- draw_line = 3'd1, // draw the line
- ignore = 3'd3,
- halt = 3'd2,
- write_state = 3'd4; // wait for next drawline command
- always @ (posedge VGA_CLK)
- begin
- if (reset) //synch reset assumes KEY0 is held down 1/60 second
- begin
- data_reg <= 16'b0; //write all zeros (black)
- state <= halt;
- available_reg <= 1'b0;
- write_clk <= 1'b0;
- next_state <= write_state;
- end
- //modify display during sync
- else if (VGA_SYNC)
- begin
- case(state)
- write_state: begin
- if(is_write_finished) begin
- state <= next_state;
- write_clk <= 1'b0;
- end
- end
- //setup line drawing
- setup:
- begin
- available_reg <= 1'b0; //indicate that module is in use
- dy <= absdy;
- dx <= absdx;
- e <= nege;
- // i always gets increments
- // j gets incremented when e>0
- if (xDA)
- begin
- i <= x1;
- j <= y1;
- end
- else
- begin
- i <= y1;
- j <= x1;
- end
- state <= draw_line;
- end
- //draw the line
- draw_line:
- begin
- if (finish)
- begin
- state <= halt;
- //we <= 1'b1;
- end
- else
- begin
- //we <= 1'b0;
- // if x is DA, i is x, y is j
- if (xDA)
- begin
- data_reg <= color;
- xAddr <= i[9:0];
- yAddr <= j[8:0];
- next_state <= draw_line;
- write_clk <= 1'b1;
- state <= write_state;
- end
- // if y is DA, j is x, y is i
- else
- begin
- data_reg <= color;
- xAddr <= j[9:0];
- yAddr <= i[8:0];
- next_state <= draw_line;
- write_clk <= 1'b1;
- state <= write_state;
- end
- if (e >= 0)
- begin
- j <= j + jinc;
- e <= e - edec + einc;
- i <= i + iinc;
- end
- else
- begin
- i <= i + iinc;
- e <= e + einc;
- end
- end
- end
- ignore: begin
- available_reg <= 1'b1;
- if(~command[1]) begin
- state <= halt;
- end
- end
- //wait for next draw line command
- halt:
- begin
- if (command[1] && (my_id == id_req))
- begin
- state <= setup;
- available_reg <= 1'b0;
- end
- //we <= 1'b1;
- if(~command[1])available_reg <= 1'b1; //indicate that module is free for use
- end
- default:
- begin
- available_reg <= 1'b0;
- end
- endcase
- end
- else
- begin
- end
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement