//////////////////////////////////////////////////////////////////////////////// // /// LSU EE 4755 Fall 2017 Homework 4 // /// Assignment http://www.ece.lsu.edu/koppel/v/2017/hw04.pdf /// Instructions: // // (1) Find the undergraduate workstation laboratory, room 126 EE // Building. // // (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: // http://www.ece.lsu.edu/koppel/v/proc.html // // (5) Copy this assignment, local path name // /home/faculty/koppel/pub/ee4755/hw/2017/hw04 // to a directory ~/hw04 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 // http://standards.ieee.org/getieee/1800/download/1800-2012.pdf // Introductory Treatment (Warning: Does not include SystemVerilog) // Brown & Vranesic, Fundamentals of Digital Logic with Verilog, 3rd Ed. // // Account Setup and Emacs (Text Editor) Instructions // http://www.ece.lsu.edu/koppel/v/proc.html // To learn Emacs look for Emacs tutorial. `default_nettype none ////////////////////////////////////////////////////////////////////////////// /// Problem 1 // /// Modify maxrun so that it keeps track of the current and maximum runs. // See http://www.ece.lsu.edu/koppel/v/2017/hw04.pdf // // [ ] Make sure that the testbench does not report errors. // [ ] Module must be synthesizable. // [ ] Code must be reasonably efficient. module maxrun #( int w = 2, int c = 4 ) ( output uwire [w-1:0] len, output logic [c-1:0] mr_char, input uwire clk, reset, mr, input uwire [c-1:0] in_char ); endmodule ////////////////////////////////////////////////////////////////////////////// /// Testbench Code // // The code below instantiates some of the modules above, // provides test inputs, and verifies the outputs. // // The testbench may be modified to facilitate your solution. Of // course, the removal of tests which your module fails is not a // method of fixing a broken module. (One might modify the testbench // so that the first tests it performs are those which make it easier // to determine what the problem is, for example, test inputs that // are all 0's or all 1's.) // cadence translate_off program reactivate (output uwire clk_reactive, output int cycle_reactive, input uwire clk, input var int cycle); assign clk_reactive = clk; assign cycle_reactive = cycle; endprogram module testbench; localparam int char_wid = 8; localparam int count_wid = 10; localparam int test_num_chars = 100; localparam int cycle_limit = test_num_chars + 20; localparam int nmuts = 1; localparam int char_mask = ( 1 << char_wid ) - 1; uwire [count_wid-1:0] len[nmuts]; uwire [char_wid-1:0] mr_char[nmuts]; logic [char_wid-1:0] char, shadow_last_char; logic mr; logic clock, reset; bit done; int cycle; logic clk_reactive; int cycle_reactive; reactivate ra(clk_reactive,cycle_reactive,clock,cycle); initial begin clock = 0; cycle = 0; fork forever #10 cycle += clock++; wait( done ); wait( cycle >= cycle_limit ) $write("*** Cycle limit exceeded, ending.\n"); join_any; $finish(); end maxrun #(count_wid,char_wid) mr1 (len[0],mr_char[0],clock,reset,mr,char); initial begin automatic int n_err_cr_len = 0, n_err_mr_len = 0, n_err_mr_char = 0; int shadow_mr_len, shadow_mr_char, shadow_cr_len; bit is_err_cr_len, is_err_mr_len, is_err_mr_char; done = 0; reset = 0; char = 0; mr = 0; @( posedge clk_reactive ); for ( int i=0; i<test_num_chars; i++ ) begin automatic bit do_reset = i == 0 || {$random} % 10 == 0; automatic bit do_new_char = {$random} % 3 == 0; logic [count_wid-1:0] mr_len, cr_len; @( negedge clock ); shadow_last_char = char; if ( do_new_char ) char = {$random} & char_mask; reset = do_reset; if ( !do_reset && char === shadow_last_char ) shadow_cr_len++; else shadow_cr_len = 1; if ( do_reset ) shadow_mr_len = 0; if ( shadow_cr_len > shadow_mr_len ) begin shadow_mr_len = shadow_cr_len; shadow_mr_char = char; end @( posedge clk_reactive ); repeat ( 2 ) begin if ( mr ) mr_len = len[0]; else cr_len = len[0]; mr = !mr; #0; #0; end is_err_cr_len = shadow_cr_len !== cr_len; is_err_mr_len = shadow_mr_len !== mr_len; is_err_mr_char = shadow_mr_char !== mr_char[0]; $write ("%5d %1s c=%2x cr_len %3d %s mr_len %3d %s mr_c %2x %s\n", i, do_reset ? "r" : " ", char, cr_len, is_err_cr_len ? $sformatf("!= %3d", shadow_cr_len) : "ok ", mr_len, is_err_mr_len ? $sformatf("!= %3d", shadow_mr_len) : "ok ", mr_char[0], is_err_mr_char ? $sformatf("!= %2x", shadow_mr_char) : "ok " ); if ( shadow_cr_len !== cr_len ) n_err_cr_len++; if ( shadow_mr_len !== mr_len ) n_err_mr_len++; if ( shadow_mr_char !== mr_char[0] ) n_err_mr_char++; end $write("Done with %0d tests, %0d %0d %0d errors found.\n", test_num_chars, n_err_cr_len, n_err_mr_len, n_err_mr_char); done = 1; end endmodule // cadence translate_on