//////////////////////////////////////////////////////////////////////////////// // /// LSU EE 4755 Fall 2019 Homework 1 // /// Assignment https://www.ece.lsu.edu/koppel/v/2019/hw01.pdf /// Instructions: // // (1) Find the undergraduate workstation laboratory, room 2241 Patrick // F. Taylor Hall. Machines to use are in the back. // // (2) Locate your account. If you did not get an account please // E-mail: koppel@ece.lsu.edu // // (3) Log in to a Linux workstation. // // (4) If you haven't already, follow the account setup instructions here: // https://www.ece.lsu.edu/koppel/v/proc.html // // (5) Copy this assignment, local path name // /home/faculty/koppel/pub/ee4755/hw/2019/hw01 // to a directory ~/hw01 in your class account. (~ is your home // directory.) Use this file for your solution. /// BE SURE THAT YOUR FILE IS CORRECTLY NAMED AND IN THE RIGHT PLACE. // // (6) Find the problems in this file and solve them. // // Your entire solution should be in this file. // // Do not change module names. // // (7) Your solution will automatically be copied from your account by // the TA-bot. /// Additional Resources // // Verilog Documentation // The Verilog Standard // https://ieeexplore.ieee.org/document/8299595/ // Introductory Treatment (Warning: Does not include SystemVerilog) // Brown & Vranesic, Fundamentals of Digital Logic with Verilog, 3rd Ed. // // Account Setup and Emacs (Text Editor) Instructions // https://www.ece.lsu.edu/koppel/v/proc.html // To learn Emacs look for Emacs tutorial. // // Unix Help (Very outdated. Alternatives welcome.) // https://www.ece.lsu.edu/koppel/v/4ltrwrd/ `default_nettype none ////////////////////////////////////////////////////////////////////////////// /// Problem 1 // /// Modify mult16_tree, mult8_tree, and mult4_tree to implement multiplier. /// // // [ ] Make sure that the testbench does not report errors. // [ ] mult16_tree must use exactly two mult8_tree modules, etc. // [ ] Pay attention to port widths. Do not make them larger than needed. // [ ] Module must be synthesizable. Use command: genus -files syn.tcl module mult16_tree #( int wa = 16, int wb = 16, int wp = wa + wb ) ( output uwire [31:0] prod, input uwire [15:0] a, input uwire [15:0] b ); /// Problem 1 solution goes here, and in other modules. // [ ] Instantiate two mult8_tree's. // [ ] Use implicit structural or behavioral code to combine their outputs. endmodule module mult8_tree ( output uwire [0:0] prod, input uwire [0:0] a, input uwire [0:0] b ); // [ ] Pay attention to port widths. Do not make them larger than needed. /// Problem 1 solution goes here, and in other modules. // [ ] Instantiate two mult4_tree's. // [ ] Use implicit structural or behavioral code to combine their outputs. endmodule module mult4_tree ( output uwire [0:0] prod, input uwire [3:0] a, input uwire [15:0] b ); // [ ] Pay attention to port widths. Do not make them larger than needed. /// Problem 1 solution goes here, and in other modules. // [ ] Use implicit structural or behavioral code to combine their outputs. mult2 mlo( /* Finish! */ ); mult2 mhi( /* Finish! */ ); endmodule /// Do not modify the code below this point. module mult2 ( output uwire [17:0] prod, input uwire [1:0] a, input uwire [15:0] b ); /// DO NOT MODIFY THIS ROUTINE. assign prod = a * b; endmodule module mult16_flat #( int wa = 16, int wb = 16, int wp = wa + wb ) ( output uwire [31:0] prod, input uwire [15:0] a, b ); /// DO NOT MODIFY THIS ROUTINE. uwire [17:0] prod00, prod02, prod04, prod06, prod08, prod10, prod12, prod14; mult2 m0( prod00, a[1:0], b); mult2 m2( prod02, a[3:2], b); mult2 m4( prod04, a[5:4], b); mult2 m6( prod06, a[7:6], b); mult2 m8( prod08, a[9:8], b); mult2 m10( prod10, a[11:10], b); mult2 m12( prod12, a[13:12], b); mult2 m14( prod14, a[15:14], b); assign prod = prod00 + ( prod02 << 2 ) + ( prod04 << 4 ) + ( prod06 << 6 ) + ( prod08 << 8 ) + ( prod10 << 10 ) + ( prod12 << 12 ) + ( prod14 << 14 ); endmodule module mult_operator #( int wa = 16, int wb = 16, int wp = wa + wb ) ( output uwire [wp:1] prod, input uwire [wa:1] a, input uwire [wb:1] b ); /// DO NOT MODIFY THIS ROUTINE. assign prod = a * b; endmodule ////////////////////////////////////////////////////////////////////////////// /// Testbench Code // cadence translate_off module testbench; localparam int wid = 16; localparam int num_tests = 1000; localparam int NUM_MULT = 3; localparam int err_limit = 7; logic [wid-1:0] plier, cand; logic [2*wid-1:0] prod[NUM_MULT], shadow_prod; mult_operator mb0(prod[0], plier, cand); mult16_flat mb1(prod[1], plier, cand); mult16_tree mb2(prod[2], plier, cand); string names[] = '{ "mult_operator", "mult16_flat", "mult16_tree" }; int err_cnt[NUM_MULT]; // Array of multiplier/multiplicand values to try out. // After these values are used a random number generator will be used. // int tests[$] = {1,1, 1,2, 1,32, 32, 1}; initial begin $write("\nStarting testbench...\n"); for ( int i=0; i