1 / 17

COMP211 Computer Logic Design Lecture 5. Hardware Description Language #5

COMP211 Computer Logic Design Lecture 5. Hardware Description Language #5. Prof. Taeweon Suh Computer Science Education Korea University. Parameterized Modules. So far, all of our modules have had fixed-width inputs and outputs HDLs permit variable bit widths using parameterized modules

sissy
Download Presentation

COMP211 Computer Logic Design Lecture 5. Hardware Description Language #5

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. COMP211Computer Logic DesignLecture 5. Hardware Description Language #5 Prof. Taeweon Suh Computer Science Education Korea University

  2. Parameterized Modules • So far, all of our modules have had fixed-width inputs and outputs • HDLs permit variable bit widths using parameterized modules • Verilog allows a #(parameter …) statement before the inputs and outputs to define parameters

  3. Parameterized Module Example module mux2 #(parameter width = 8) // name and default value (input [width-1:0] d0, d1, input s, output [width-1:0] y); assign y = s ? d1 : d0; endmodule 2:1 mux: Instance with 8-bit bus width (uses default): mux2 mux1(d0, d1, s, out); Instance with 12-bit bus width: mux2 #(12) lowmux(d0, d1, s, out);

  4. Another Parameterized Module Example module decoder #(parameter N = 3) (input [N-1:0] a, output reg [2**N-1:0] y); always @(*) begin y = 0; y[a] = 1; end endmodule N: 2N Decoder

  5. generateStatement • HDLs also provide generatestatements to produce a variable amount of hardware depending on the value of a parameter • generate supports for for loops and if statements to determine how many of what types of hardware to produce • Use generate statement with caution: it is easy to produce a large amount of hardware unintentionally

  6. generate Example module andN #(parameter width = 8) (input [width-1:0] a, output y); genvar i; wire [width-1:1] x; generate for (i=1; i<width; i=i+1) begin: forloop if (i == 1) assign x[1] = a[0] & a[1]; else assign x[i] = a[i] & x[i-1]; end endgenerate assign y = x[width-1]; endmodule • This example can be more easily described by “assign y = &a” though!

  7. Testbench and TestVector Testbench • HDL code written to test another HDL module, the device under test (dut), also called the unit under test (uut) • Testbench contains statements to apply input to the DUT and ideally to check the correct outputs are produced Testvectors • Inputs to DUT and desired output patterns from DUT Types of testbenches: • Simple testbench • Self-checking testbench • Self-checking testbench with testvectors

  8. Simple Testbench Revisit • Signals in “initial” statement should be declared as “reg” module sillyfunction(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & c; endmodule testvectors `timescale 1ns/1ps module testbench1(); reg a, b, c; wire y; // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs one at a time initial begin a = 0; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; a = 1; b = 0; c = 0; #10; c = 1; #10; b = 1; c = 0; #10; c = 1; #10; end endmodule

  9. Self-checking Testbench Revisit a = 1; b = 0; c = 0; #10; if (y !== 1) $display("100 failed."); c = 1; #10; if (y !== 1) $display("101 failed."); b = 1; c = 0; #10; if (y !== 0) $display("110 failed."); c = 1; #10; if (y !== 0) $display("111 failed."); end endmodule testvectors module testbench2(); reg a, b, c; wire y; // instantiate device under test sillyfunction dut(a, b, c, y); // apply inputs one at a time // checking results initial begin a = 0; b = 0; c = 0; #10; if (y !== 1) $display("000 failed."); c = 1; #10; if (y !== 0) $display("001 failed."); b = 1; c = 0; #10; if (y !== 0) $display("010 failed."); c = 1; #10; if (y !== 0) $display("011 failed.");

  10. Testbench with Testvectors Writing code for each test vector is tedious, especially for modules that require a large number of vectors A better approach is to place the test vectors in a separate file Then, testbench reads the file, places input to DUT and compares the DUT’s outputs with expected outputs • Generate clock for assigning inputs, reading outputs • Read testvectors file into array • Assign inputs and expected outputs to signals • Compare outputs to expected outputs and report errors if there is discrepancy

  11. Testbench with Testvectors Testbench clock is used to assign inputs (on the rising edge) and compare outputs with expected outputs (on the falling edge). The testbench clock may also be used as the clock source for synchronous sequential circuits.

  12. Testvectors File module sillyfunction(input a, b, c, output y); assign y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & c; endmodule File: example.tv – contains vectors of abc_yexpected 000_1 001_0 010_0 011_0 100_1 101_1 110_0 111_0

  13. Testbench: 1. Generate Clock module testbench3(); regclk, reset; reg a, b, c, yexpected; wire y; reg [31:0] vectornum, errors; reg [3:0] testvectors[10000:0]; // array of testvectors // instantiate device under test sillyfunctiondut(a, b, c, y); // generate clock always begin clk = 1; #5; clk = 0; #5; end

  14. 2. Read Testvectors into Array3. Assign inputs and Expected Outputs // at start of test, load vectors // and pulse reset initial begin $readmemb("example.tv", testvectors); vectornum = 0; errors = 0; reset = 1; #27; reset = 0; end // Note: $readmemh reads testvector files written in // hexadecimal // apply test vectors on rising edge of clk always @(posedge clk) begin #1; {a, b, c, yexpected} = testvectors[vectornum]; end

  15. 4. Compare Outputs with Expected Outputs // check results on falling edge of clk always @(negedge clk) if (~reset) begin // skip during reset if (y !== yexpected) begin $display("Error: inputs = %b“, {a, b, c}); $display(" outputs = %b (%b expected)“, y, yexpected); errors = errors + 1; end // increment array index and read next testvector vectornum = vectornum + 1; if (testvectors[vectornum] === 4'bx) begin $display("%d tests completed with %d errors“, vectornum, errors); $finish; end end Endmodule // Note: “===“ and “!==“ can compare values that are x or z.

  16. HDL Summary HDLs are extremely important tools for modern digital designers • Once you have learned Verilog or VHDL, you will be able to specify digital systems much faster than drawing schematics • Debug cycle is also often much faster because modifications require code changes instead of tedious schematic rewriting • However, the debug cycle can be much longer with HDLs if you don’t have a good idea of the hardware your code implies

  17. HDL Summary The most important thing to remember when you are writing HDL code is that you are describing real hardware! (not writing a computer program) • The most common beginner’s mistake is to write HDL code without thinking about the hardware you intend to produce • If you don’t know what hardware you are implying, you are almost certain not to get what you want • So, probably sketch a block diagram of your system • Identifying which portions are combinational logic, sequential logic, FSMs and so on, so forth… • Then write HDL code for each portion

More Related