//////////////////////////////////////////////////////////////////////////////// // /// LSU EE 4755 Fall 2020 Homework 2 // /// Assignment https://www.ece.lsu.edu/koppel/v/2020/hw02.pdf /// Instructions: // // (1) Find the undergraduate workstation laboratory, room 2241 Patrick // F. Taylor Hall. Machines to use are in the back. // // (☣) Practice Social Distancing: // - Use hand sanitizer before first touching a keyboard and // after finishing. // - Keep your mask on. // - If you must take off your mask for a short period of time // do so at least 2 meters from the closest person. // - Don't forget that it is often spread by those who don't // know they are infectious. // // (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/2020/hw02 // to a directory ~/hw02 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 nn4x4b, nn1x4b, and nn1x2b to compute same output as nn4x4. /// // // [ ] nn4x4b must instantiate exactly four nn1x4b modules. // [ ] nn1x4b must instantiate exactly two nn1x2b modules. // // [ ] Make sure that the testbench does not report errors. // [ ] Module must be synthesizable. Use command: genus -files syn.tcl // // [ ] Don't assume any particular parameter value. // [ ] Don't add more ports than are needed. // // [ ] Code must be written clearly. module nn4x4 #( int wa = 10, ww = 5 ) ( output uwire [wa-1:0] ao[4], input uwire [wa-1:0] ai[4], input uwire [ww-1:0] wht[4][4] ); /// DO NOT MODIFY THIS MODULE assign ao[0] = ai[0] * wht[0][0] + ai[1] * wht[0][1] + ai[2] * wht[0][2] + ai[3] * wht[0][3]; assign ao[1] = ai[0] * wht[1][0] + ai[1] * wht[1][1] + ai[2] * wht[1][2] + ai[3] * wht[1][3]; assign ao[2] = ai[0] * wht[2][0] + ai[1] * wht[2][1] + ai[2] * wht[2][2] + ai[3] * wht[2][3]; assign ao[3] = ai[0] * wht[3][0] + ai[1] * wht[3][1] + ai[2] * wht[3][2] + ai[3] * wht[3][3]; endmodule module nn4x4b #( int wa = 10, ww = 5 ) ( output uwire [wa-1:0] ao[4], input uwire [wa-1:0] ai[4], input uwire [ww-1:0] wht[4][4] ); /// Instantiate Four nn1x4b Modules Here. // The examples further below are for reference, they should not // be part of the solution. // Example of how to extract a row of a 2-D array. // uwire [ww-1:0] wht_row_0[4] = wht[0]; // // There is no need to use object wht_row_0 declared above, instead // wht[0] can be used in a port connection to one of the nn1x4b // instantiations. // // Example of how to use the row: // uwire [wa-1:0] ao_zero = ai[0] * wht_row_0[0] + ai[1] * wht_row_0[1] + ai[2] * wht_row_0[2] + ai[3] * wht_row_0[3]; // /// Do not use this ao_zero in your solution. Feel free to delete it. endmodule module nn1x4b; // [ ] Declare parameters and ports for one ao and a four-element ai. // Instantiate two nn1x2b modules here. // Other logic may be needed. endmodule module nn1x2b; // [ ] Declare parameters and ports for one ao and a two-element ai. // Write code to compute ao. endmodule ////////////////////////////////////////////////////////////////////////////// /// Testbench Code module nnOxI #( int no = 4, ni = 4, wa = 10, ww = 5 ) ( output logic [wa-1:0] ao[no], input uwire [wa-1:0] ai[ni], input uwire [ww-1:0] wht[no][ni] ); /// DO NOT MODIFY THIS ROUTINE. always_comb for ( int o = 0; o < no; o++ ) begin ao[o] = 0; for ( int i=0; i<ni; i++ ) ao[o] += ai[i] * wht[o][i]; end endmodule // cadence translate_off module testbench; localparam int wa = 16; localparam int ww = 8; localparam int ni = 4; // Number of input neurons. localparam int no = 4; // Number of output neurons. localparam int nmut = 3; localparam int ntests = 10; logic [wa-1:0] ai[ni]; uwire [wa-1:0] ao[nmut][no]; logic [ww-1:0] wht[no][ni]; string mname[] = { "Behav", "Flat", "Hier" }; typedef struct { string name; int no, ni; } Test_Set; Test_Set ts[] = '{ '{ "n12", 1, 2 }, '{ "n14", 1, 4 }, '{ "n44", 4, 4 } }; nnOxI #(no,ni,wa,ww) nn1i(ao[0],ai,wht); nn4x4 #(wa,ww) nn2i(ao[1],ai,wht); nn4x4b #(wa,ww) nn3i(ao[2],ai,wht); initial begin automatic int mut = 2; automatic string test_summary = ""; $write("Testing module %s\n", mname[mut]); foreach ( ts[ti] ) begin automatic Test_Set tinfo = ts[ti]; automatic int n_err = 0; $write("\n** Starting test set %s (%0d outputs, %0d inputs) **\n", tinfo.name, tinfo.no, tinfo.ni ); for ( int tnum=0; tnum < ntests; tnum++ ) begin for ( int io=0; io<no; io++ ) for ( int ii=0; ii<ni; ii++ ) wht[io][ii] = io < tinfo.no && ii < tinfo.ni ? {$random} : 0; for ( int ii=0; ii<ni; ii++ ) ai[ii] = ii < tinfo.ni ? {$random} : 0; #1; for ( int io=0; io<tinfo.no; io++ ) begin if ( ao[0][io] !== ao[mut][io] ) begin n_err++; if ( n_err < 4 ) $write ("Error test # %0d, output %0d: %0d != %0d (correct)\n", tnum, io, ao[mut][io], ao[0][io] ); end end end begin automatic string msg = $sformatf("%0d %s tests on %s: %0d errors found.", ntests, tinfo.name, mname[mut], n_err); $write("Done with %s\n",msg); test_summary = { test_summary, $sformatf("Results of %s\n", msg) }; end end $write("\n** Summary of Results **\n%s", test_summary); end endmodule // cadence translate_on