`timescale 1ns / 1ps ///////////////////////////////////////////////////////////////////////////// // // Accumulates one color component and prevents overflow // ///////////////////////////////////////////////////////////////////////////// module color_component_acc(clk, reset, in, sum); input clk; input reset; input [7:0] in; output [7:0] sum; reg [7:0] b, q; parameter MAX = 8'hFF; wire [7:0] x; wire cout; assign {cout, x} = b + q; assign sum = cout ? MAX : x; always @ (posedge clk) begin b <= in; if (reset) q <= 0; else q <= sum; end endmodule /////////////////////////////////////////////////////////////////////////////// // Accumulates one color component and prevents overflow // ///////////////////////////////////////////////////////////////////////////// module color_acc(clk, reset, color_red, color_green, color_blue, color); input clk; input reset; input [7:0] color_red, color_green, color_blue; output [23:0] color; color_component_acc red_acc (clk, reset, color_red, color[23:16]); color_component_acc green_acc (clk, reset, color_green, color[15:8]); color_component_acc blue_acc (clk, reset, color_blue, color[7:0]); endmodule`timescale 1ns / 1ps //////////////////////////////////////////////////////////////////////////////// // // 6.111 FPGA Labkit -- Debounce/Synchronize module // // // Use your system clock for the clock input to produce a synchronous, // debounced output // ///////////////////////////////////////////////////////////////////////////// module debounce (reset, clock, noisy, clean); parameter DELAY = 270000; // .01 sec with a 27Mhz clock input reset, clock, noisy; output clean; reg [18:0] count; reg new, clean; always @(posedge clock) if (reset) begin count <= 0; new <= noisy; clean <= noisy; end else if (noisy != new) begin new <= noisy; count <= 0; end else if (count == DELAY) clean <= new; else count <= count+1; endmodule`timescale 1ns / 1ps ///////////////////////////////////////////////////////////////////////////// // // Delays input by two clock cycles // ///////////////////////////////////////////////////////////////////////////// module delay3(clk, in, out); input clk, in; output out; reg a, b, out; always @ (posedge clk) begin a <= in; b <= a; out <= b; end endmodule ///////////////////////////////////////////////////////////////////////////// // // Delays input by 5 clock cycles // ///////////////////////////////////////////////////////////////////////////// module delay5(clk, in, out); input clk, in; output out; reg a, b, c, d, out; always @ (posedge clk) begin a <= in; b <= a; c <= b; d <= c; out <= d; end endmodule`timescale 1ns / 1ps /////////////////////////////////////////////////////////////////////////////// Divider Module // Sam Gross and Adam Lerer // // Latency: 7 // Throughput: 1/7 (can be improved) // Speed: ~104 Mhz or 85? // ///////////////////////////////////////////////////////////////////////////// module div18(clk, a_in, b_in, quot, start, done); input clk; input [16:0] a_in; input [16:0] b_in; reg [16:0] a; output reg [17:0] quot; input start; output done; reg [17:0] quot_next; parameter ONE = 18'h20000; // 1.0 parameter FACTOR = 18'h2E9FB; // 1.457 reg [4:0] shift, shift_next; wire [4:0] shift_out; wire [16:0] b_norm; reg signed [17:0] den, den_next; fp_norm normalizer (clk, 1'b1, b_in, b_norm, shift_out); reg [17:0] rcp, next_rcp; // reciprocal of denominator reg [17:0] mult_a, mult_b; wire [17:0] product; wire [35:0] mult_out; wire [34:0] temp; assign temp = mult_out << (shift + 1); reg [2:0] state; //assign quot = next_rcp; assign done = (state == 7); mult_full multiplier (clk, mult_a, mult_b, mult_out); assign product = mult_out[34:17]; always @ * begin den_next = den; next_rcp = rcp; quot_next = quot; mult_a = 18'hz; mult_b = 18'hz; shift_next = shift; case (state) 3'd0: // --------------------- clk = 0 begin den_next = -b_norm; shift_next = shift_out; end 3'd1: // --------------------- clk = 1begin next_rcp = FACTOR + den; mult_a = den; mult_b = next_rcp; end 3'd2: // --------------------- clk = 2 begin mult_a = rcp; mult_b = ONE + product; end 3'd3: // --------------------- clk = 3 begin next_rcp = product << 1; mult_a = den; mult_b = next_rcp; end 3'd4: // --------------------- clk = 4 begin mult_a = rcp; mult_b = ONE + product; end 3'd5: // --------------------- clk = 5, product contains rcp begin mult_a = a; mult_b = product << 1; end 3'd6: // --------------------- clk = 6 compute division begin quot_next = temp[34:17]; end // -------------------------- clk = 7 answer out 3'd7: begin end endcase end always @ (posedge clk) begin if (start) begin rcp <= 0; state <= 0; a <= a_in; end else begin if (state != 3'd7) state <= state + 1; rcp <= next_rcp; end den <= den_next; shift <= shift_next; quot <= quot_next; end endmodule`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // // Normalizes fixed point numbers to between 0.5 and 1 // ////////////////////////////////////////////////////////////////////////////////// module fp_norm(clk, ce, in, out, shift); input clk; input ce; input [16:0] in; output [16:0] out; output [4:0] shift; reg [16:0] num; reg [4:0] shift; always @ (posedge clk) if (ce) num <= in; always @ (num) casez (num[16:1]) 16'b1zzz_zzzz_zzzz_zzzz: shift = 5'd0; 16'b01zz_zzzz_zzzz_zzzz: shift = 5'd1; 16'b001z_zzzz_zzzz_zzzz: shift = 5'd2; 16'b0001_zzzz_zzzz_zzzz: shift = 5'd3; 16'b0000_1zzz_zzzz_zzzz: shift = 5'd4; 16'b0000_01zz_zzzz_zzzz: shift = 5'd5; 16'b0000_001z_zzzz_zzzz: shift = 5'd6; 16'b0000_0001_zzzz_zzzz: shift = 5'd7;
View Full Document