//////////////////////////////////////////////////////////////////////////////// // /// LSU EE 4755 Fall 2014 Homework 1 -- SOLUTION // /// Assignment http://www.ece.lsu.edu/koppel/v/2014/hw01.pdf `default_nettype none ////////////////////////////////////////////////////////////////////////////// /// Problem 1 // /// Logical Right Shift Module 1 // // The module below performs a logical right shift of a 16-bit // quantity. // // [x] Fix the module, the testbench should not report errors. // [x] Don't substantially change the way the code works. // [x] Don't try to make the code synthesizable. // [x] Don't use shift (<<) or concatenation operators ({}) .. // .. assign shifted bit-by-bit as the code already does. // cadence translate_off module shift_right1 ( output logic [15:0] shifted, input wire [15:0] unshifted, input wire [3:0] amt ); /// Problem 1 solution goes in this module. localparam int width = 16; always @* begin automatic int limit = width - amt; for ( int i=0; i<limit; i++ ) shifted[i] = unshifted[i+amt]; /// SOLUTION // Just zero the "vacated" bits. // for ( int i=limit; i<width; i++ ) shifted[i] = 0; end endmodule // cadence translate_on ////////////////////////////////////////////////////////////////////////////// /// Problem 2 // /// Logical Right Shift Module 2 // // The module below performs a logical right shift of a 16-bit // quantity. // // [x] Complete module shift_right2, the testbench should not report errors. // Perform Two Possible Shifts: by 0 bits or by fsamt bits. // module shift_right_fixed ( output wire [15:0] shifted, input wire [15:0] unshifted, input wire shift ); // Problem 2: DON'T modify this module. // (Fixed) Shift Amount // parameter int fsamt = 3; // If shift is true shift by fsamt, otherwise don't shift. // assign shifted = shift ? unshifted >> fsamt : unshifted; endmodule module shift_right2 ( output wire [15:0] shifted, input wire [15:0] unshifted, input wire [3:0] amt ); /// Problem 2 solution goes in this module. /// SOLUTION // // Declare wires to interconnect the modules. // uwire [15:0] s8, s4, s2; shift_right_fixed #(8) sm8 ( .shifted(s8), .unshifted(unshifted), .shift(amt[3]) ); /// SOLUTION // // Instantiate three more modules and connect them. // Note: You don't have to use named ports. shift_right_fixed #(4) sm4 (s4, s8, amt[2]); shift_right_fixed #(2) sm2 (s2, s4, amt[1]); shift_right_fixed #(1) sm1 (shifted, s2, amt[0]); endmodule ////////////////////////////////////////////////////////////////////////////// /// Testbench Code // // The code below instantiates shift_right1 and shift_right2, // 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 // considered a correct solution. (The idea is to put in tests 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 module testbench(); uwire logic [15:0] sout1, sout2; logic [15:0] sin; logic [3:0] amt; shift_right1 my_sr1(sout1, sin, amt); shift_right2 my_sr2(sout2, sin, amt); // Width of shifters' input and output. // The parameter is used only by this testbench. // localparam int width = 16; // // To keep things simple the shifter modules themselves are written // with a hardcoded width of 16 bits. That's bad style since // changing the width would be tedious and error prone. The // hardcoded widths are used in this first homework assignment only // to keep things simple. (The shifter modules could have used a // parameter to specify the width or a user-defined type.) // Provide names for the modules for use in error messages. // localparam string name[2] = '{"Prob 1", "Prob 2"}; initial begin // Count of errors for each module. // automatic int err_count[2] = '{0,0}; // // Note: The automatic qualifier is needed so that the initialization // could appear on the same line as the declaration. // Number of test inputs (stimuli). // automatic int test_count = 0; // Provide one test pattern per shift amount. // for ( int i=0; i<width; i++ ) begin int shadow_sout; test_count++; sin = $random; amt = i; shadow_sout = sin >> amt; #1; // Check the output of each Module Under Test. // foreach ( name[ mut ] ) begin automatic logic [15:0] sout = mut == 0 ? sout1 : sout2; if ( shadow_sout !== sout ) begin err_count[mut]++; if ( err_count[mut] < 5 ) $display ("MUT %s wrong result for %h >> %d: %h != %h (correct)\n", name[mut], sin, amt, sout, shadow_sout); end end end $display("Ran %d tests, %d, %d errors found.\n", test_count, err_count[0], err_count[1]); end endmodule // cadence translate_on