1 / 38

Introduction to FPGA Development

Introduction to FPGA Development. Justin Thiel Two Sigma Investments. Mapping Operations to HW. always @( posedge clk ) begin r_x <= x; if (x) r_y <= r_x ; end. Flip Flop. Flip Flop. r_y. x. r_x. clk. What is Inside an FPGA?. What is Inside an FPGA?. a + b = c.

Download Presentation

Introduction to FPGA Development

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Introduction to FPGA Development Justin ThielTwo Sigma Investments

  2. Mapping Operations to HW always @(posedgeclk) begin r_x <= x; if (x) r_y <= r_x; end Flip Flop Flip Flop r_y x r_x clk

  3. What is Inside an FPGA?

  4. What is Inside an FPGA? a + b = c LUT Inputs (Address) LUT Outputs (Data)

  5. What is Inside an FPGA?

  6. module ttl74163 #( parameter WIDTH = 4 ) ( input clk, input rst_n, input [WIDTH-1:0] i_load_cnt, input i_load_n, input i_cnt_en, input i_cnt_en_w_carry_out, output [WIDTH-1:0] o_cnt, output o_carry_out ); // Some sweet logic here ... endmodule

  7. Exercise 1 74163 Binary Counter Simulation

  8. Verilog Primer

  9. Verilog Numerical Types Format: [WIDTH]’[BASE][VALUE] 2’d0 -> 2 bit decimal 0 2’b0 -> 2 bit binary 0 4’he -> 4 bit hexadecimal 14 4’o7 -> 4 bit octal 7 • Arbitary bit widths are allowed • Hex (h), Binary (b), Decimal (d), and octal (o) bases are handled • Same numeric form is used for everything (no floats, doubles, etc..) • For “signed” integers logic tends to use 2s complement format

  10. Verilog Operators Bitwise: OR: 3’b010 | 3’b100 -> 3’h110 AND: 3’b100 & 3’b111 -> 3’b100 XOR: 3’b101 ^ 3’b110 -> 3’b011 NOT: ~3’b101 -> 3’b010 Arithmetic: Addition : 3’b010 + 3’b100 -> 3’b110 Subtraction: 3’b100 – 3’b001 -> 3’b011 Comparators: Greater Than: (3’b100 > 3’b011) -> 1’b1 Equality : (3’b100 == 3’b010) -> 1’b0 Inequality : (3’b100 != 3’b000) -> 1’b1

  11. Verilog Concepts wire w_rst; assignw_rst= ~rst_n; • wires are used to define “stateless” signals • They can only be assigned to by a (single) assign statement • The value of a wire changes whenever the inputs to it’s assign statement transition clk w_rst rst_n rst_n w_rst

  12. Verilog Concepts regr_en_a; always@(posedgeclk) begin r_en_a<=i_en_a; end • regs are used to define “stateful” signals. • They should only be assigned to within a (single) always block • The value of a regchanges only when its always block evaluates Flip Flop r_en_a i_en_a clk i_en_a r_en_a clk

  13. Verilog Concepts regr_en_a; regr_en_b; always@(posedgeclk) begin r_en_a <= i_en_a; r_en_b <= r_en_a; end • All statements in an always block evaluate in parallel. Flip Flop Flip Flop i_en_a r_en_a r_en_b clk i_en_a r_en_a r_en_b clk clk

  14. Verilog Concepts regr_en_a; regr_en_b; always@(posedgeclk) begin r_en_a <= i_en_a; end always@(posedgeclk) begin r_en_b <= r_en_a; end • All always blocks execute in parallel. Flip Flop Flip Flop i_en_a r_en_a r_en_b clk i_en_a r_en_a r_en_b clk clk

  15. Verilog Concepts regr_rst; always@(*) begin r_rst <= ~rst_n; End ..Same as... always@(rst_n) begin r_rst <= ~rst_n; end • always blocks are not required to be clocked • Making a block sensitive to ‘*’ causes it to evaluate whenever a right-hand side value changes clk r_rst rst_n rst_n r_rst

  16. Dealing with Bits // 1 bit wire Wire w_rst; // 4 bit register reg [3:0] r_cnt; // 1024 bit wire wire [1023:0] x; // 4x 32b registers reg [31:0] r_data [3:0]; // 4x4x 32b registers reg [31:0] r_data2d [3:0][3:0]; • Brackets ‘[]’ are used to denote multi-bit fields

  17. Dealing with Bits wire [3:0] x; wire y; wire [1:0] z; // Set y to Bit 0 of x assign y = x[0]; // Set z to Bits 1:0 of x assign z = x[1:0]; • Brackets ‘[…]’ are also used to bit slice vectors. • Use ‘:’ to specify a range. x[1] x[0] y z[0] z[1]

  18. Dealing with Bits wire [3:0] x [1:0]; wire [3:0] y; wire [3:0] z; // Pulling Array Entries assign x[0] = y; assign x[1] = z; • Brackets ‘[…]’ are also used to index into arrays z y x[0] x[1]

  19. Dealing with Bits wire [1:0] x; wire y; wire z; // Set x[1] to y, x[0] to z of y and z assign x = {y,z}; • Use curly braces ‘{…}’ to concatenate bit vectors z y x[1] x[0]

  20. Module Declaration and Port Maps module ttl74163 #( parameter WIDTH = 4 ) ( // Clock and Reset Pins input clk, input rst_n, // Inputs input [WIDTH-1:0] i_load_cnt, input i_load_n, ... // Outputs output [WIDTH-1:0] o_cnt, output o_carry_out ); • Alldesignsstart with a module declaration

  21. Module Declaration and Port Maps module ttl74163 #( parameter WIDTH = 4 ) ( // Clock and Reset Pins input clk, input rst_n, // Inputs input [WIDTH-1:0] i_load_cnt, input i_load_n, ... // Outputs output [WIDTH-1:0] o_cnt, output o_carry_out ); • parameters can be used to create logic which is configurable at compile (synthesis) time • They must be enclosed within a “#( … )” block

  22. Module Declaration and Port Maps module ttl74163 #( parameter WIDTH = 4 ) ( // Clock and Reset Pins input clk, input rst_n, // Inputs input [WIDTH-1:0] i_load_cnt, input i_load_n, ... // Outputs output [WIDTH-1:0] o_cnt, output o_carry_out ); • Inputs denote signals which are driven outside the module • Outputs denote signals which are driven by the module • These signals form the portmap and are enclosed in a “(…)” block i_load_cnt ttl74163 o_cnt i_load_n o_carry_out

  23. Module Instantiation parameter MY_WIDTH = 4; wire [MY_WIDTH-1:0] w_load_cnt; wire w_load_n; wire [MY_WIDTH-1:0] w_cnt; wire w_carry_out; ttl74163 #( .WIDTH (MY_WIDTH) ) my_ttl_counter ( .clk (clk), .rst_n (rst_n), .i_load_cnt (w_load_cnt), .i_load_n (w_load_n), ... .o_cnt (w_cnt), .o_carry_out (w_carry_out)); • Inputs and Outputs should be connected to wires/regs. • Each instance represents a unique copy of the logic defined in the module • agiven module is a unique copy of the logic w_load_cnt my_ttl_counter w_cnt w_load_n w_carry_out

  24. Verilog Constructs reg [3:0] r_cnt; wire [3:0] w_cnt; always@(posedgeclk) begin // Clear if (rst) r_cnt<= '0; else r_cnt<= w_cnt; end • Simpleif..elseblocks synthesize as a 2-to-1-mux • This construct can only be used in an always block. Flip Flop 4’d0 1 r_cnt w_cnt 0 rst clk

  25. Verilog Constructs regr_set; always@(posedgeclk) begin r_set <= (rst) ? 0 : i_set; end ... wire w_set; assign w_set = (rst) ? 0 : i_set; • Ternaryoperators (?) also imply a 2-to-1 mux • Can be used in always blocks or assign statements. Flip Flop 1’b0 1 w_set r_set i_set 0 rst clk

  26. Verilog Constructs reg[1:0] r_cnt; wire w_a, w_b; always@(posedgeclk) begin case ({w_a, w_b}): 2’b01: r_cnt <= 2’d1; 2’b10: r_cnt <= 2’d1; 2’b00: r_cnt <= 2’d0; 2’b11: r_cnt <= 2’d2; default: r_cnt <= 2’d0; endcase end • case statements will (generally) imply an n-to-1 mux • This construct can only be used in an always block. • default case is a failsafe, provide for best results 2’b00 Flip Flop 2’b01 r_cnt 2’b10 2’b11 {w_a, w_b} clk

  27. Verilog Constructs reg[1:0] r_cnt; wire w_en; always@(posedgeclk) begin if (w_en) r_cnt <= r_cnt + 1; else r_cnt <= r_cnt; end • Arithmeticoperations synthesize into physical representations thereof 2x Flip Flops 0 r_cnt 2’d1 2 bit Adder 1 clk w_en

  28. Verilog Constructs // Full Adder Example module full_adder( input i_a, input i_b, input i_cin, output o_sum, output o_cout ); wire w_tmp; assign w_tmp = (i_a ^ i_b); assign o_sum = (w_tmp ^ i_cin); assign o_cout= (i_a & i_b) | (i_cin & w_tmp); endmodule; • You can also build arithmetic operators yourself…

  29. Verilog Constructs reg[3:0] r_cnt; always@(posedgeclk) begin // Clear if (w_rst) r_cnt<= '0; // Load value else if (w_load) r_cnt<= i_cnt; // Count else if (w_cnt_en) r_cnt<= r_cnt + 1; else r_cnt<= r_cnt; end • if..else if...else blocks imply priority just as they do in a C/C++. • In this case, w_rst takes priority, followed by w_load and so on…

  30. Verilog Constructs else if (w_cnt_en) r_cnt <= r_cnt + 1; else r_cnt <= r_cnt; end always@(posedgeclk) begin if (w_rst) r_cnt<= '0; else if (w_load) r_cnt <= i_cnt; ... 4’d1 4bit Full Adder 0 0 4x Flip Flops 0 1 r_cnt i_cnt 4’d0 1 1 w_cnt_en w_load clk w_rst

  31. Syntactic Sugar wire [3:0] x; wire [3:0] y; wire [3:0] z; assign x = ‘0; assign y = ‘1; assign z = (x == ‘1) ? x : y; • ‘0 = “all bits set to zero” • ‘1 = “all bits set to one”

  32. Summary • Use wires for purely combinatorial logic and regs for anything stateful • Areg does not always imply a flip flop • SimpleIf…Else and Ternary statements synthesize into 2-to-1 muxes • Chains of If…Else If…Else blocks can lead to long timing paths • Acase statement will yield an n-to-1 mux when coded properly

  33. Questions

  34. Exercise 2 Binary Counter Modification

  35. Exercise 2 - Hint clk i_en o_cnt 0 14 15 … 1 2 14 13 … 1 0 1 … clk Wrong r_cnt_dn o_cnt 0 14 15 … 1 2 0 15 14 13 12 11 … clk Correct r_cnt_dn o_cnt 0 1 2 14 15 … 14 13 … 1 0 1 …

  36. Exercise 3 FPGA build flow

More Related