Midterm April 4, 2015  Name ____________________________________  Student ID __________________


// Checking if the board is alive

module basys3_1
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    
    // Write code that directly connects switches to LEDs
    // so that when switch 0 is up (1), LED 0 is turned on (1),
    // switch 1 is up (1), LED 1 is turned on (1), etc
    







    assign seg = ~ { btnC, btnL, btnL, btnD, btnR, btnR, btnU };
    assign dp  = ~ ( btnC | btnU | btnL | btnR | btnD );
    assign an  = 4'b0;

endmodule

//--------------------------------------------------------------------

// Combinational building block: multiplexor

module mux_2_1
(
    input  [3:0] d0,
    input  [3:0] d1,
    input        sel,
    output [3:0] y
);

    assign y = sel ? d1 : d0;

endmodule

module mux_4_1_imp_1
(
    input  [3:0] d0, d1, d2, d3,
    input  [1:0] sel,
    output [3:0] y
);

    
    // Using code for mux_2_1 as an example,
    // write code for 4:1 mux using "?:" operator
    






endmodule

module mux_4_1_imp_2
(
    input      [3:0] d0, d1, d2, d3,
    input      [1:0] sel,
    output reg [3:0] y
);

    always @*
        case (sel)
        2'b00: y = d0;
        2'b01: y = d1;
        2'b10: y = d2;
        2'b11: y = d3;
        endcase

endmodule

module mux_4_1_imp_3
(
    input  [3:0] d0, d1, d2, d3,
    input  [1:0] sel,
    output [3:0] y
);

    
    // Construct 4:1 mux using three instances of mux_2_1 modules
    







endmodule

module mux_4_1_bits_2
(
    input  [1:0] d0, d1, d2, d3,
    input  [1:0] sel,
    output [1:0] y
);

    assign y = sel [1]
        ? (sel [0] ? d3 : d2)
        : (sel [0] ? d1 : d0);

endmodule

module mux_4_1_imp_4
(
    input  [3:0] d0, d1, d2, d3,
    input  [1:0] sel,
    output [3:0] y
);

    
    // Construct 4:1 mux with 4-bit inputs and output
    // using two instances of mux_4_1 modules with 2-bit inputs and outputs
    

    
    
    
    
    
    
    
    
    

    
    
    
    
    
    
    
    
    

endmodule

module basys3_2
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    mux_4_1_imp_1
    (
        
        // Write code that connects module's inputs and output:
        // d0      - to sw  [ 3: 0]
        // d1      - to sw  [ 7: 4]
        // d2      - to sw  [11: 8]
        // d3      - to sw  [15:12]
        // sel [1] - to btnC
        // sel [0] - to btnR
        // y       - to led [ 3: 0]
        

        
        
        
        
        
        
    ); 
        
    assign seg = ~ 7'b0;
    assign dp  = 1'b1;
    assign an  = 4'b0;

endmodule

//--------------------------------------------------------------------

// Combinational building block: decoder

module decoder_3_8_imp_1
(
    input      [2:0] a,
    output reg [7:0] y
);

    
    Using decoder_3_8_imp_2 and decoder_3_8_imp_3 as references,
    implement the decoder using "case" statement
    

    
    
    
    
    
    
    
    
    
    
    

endmodule

module decoder_3_8_imp_2
(
    input      [2:0] a,
    output reg [7:0] y
);

    always @*
    begin
        y = 0;
        y [a] = 1;
    end

endmodule

module decoder_3_8_imp_3
(
    input  [2:0] a,
    output [7:0] y
);

    assign y = 1 << a;

endmodule

module basys3_3
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    decoder_3_8_imp_1 decoder_3_8_imp_1 (.a (sw [3:0]), .y (led [ 7:0]));
    decoder_3_8_imp_2 decoder_3_8_imp_3 (.a (sw [3:0]), .y (led [15:8]));

    assign seg = ~ 7'b0;
    assign dp  = 1'b1;
    assign an  = 4'b0;

endmodule

//--------------------------------------------------------------------

// Combinational building block: encoder

module priority_circuit_imp_1
(
    input      [3:0] a,
    output reg [3:0] y
);

    always @*
        if      (a[3]) y <= 4'b1000;
        else if (a[2]) y <= 4'b0100;
        else if (a[1]) y <= 4'b0010;
        else if (a[0]) y <= 4'b0001;
        else           y <= 4'b0000;

endmodule

module priority_circuit_imp_2
(
    input      [3:0] a,
    output reg [3:0] y
);

    always @*
        casex (a)
        4'b1???: y <= 4'b1000;
        4'b01??: y <= 4'b0100;
        4'b001?: y <= 4'b0010;
        4'b0001: y <= 4'b0001;
        default: y <= 4'b0000;
        endcase

endmodule

module priority_encoder_imp_1
(
    input      [3:0] a,
    output reg [1:0] y
);

    always @*
        if      (a[3]) y <= 3;
        else if (a[2]) y <= 2;
        else if (a[1]) y <= 1;
        else if (a[0]) y <= 0;
        else           y <= 0;

endmodule

module priority_encoder_imp_2
(
    input      [3:0] a,
    output reg [3:0] y
);

    always @*
        casex (a)
        4'b1???: y <= 3;
        4'b01??: y <= 2;
        4'b001?: y <= 1;
        4'b0001: y <= 0;
        default: y <= 0;
        endcase

endmodule

module parallel_encoder_imp_1
(
    input      [3:0] a,
    output reg [1:0] y
);

    always @*
        if      (a == 4'b1000) y <= 3;
        else if (a == 4'b0100) y <= 2;
        else if (a == 4'b0010) y <= 1;
        else if (a == 4'b0001) y <= 0;
        else                   y <= 0;

endmodule

module parallel_encoder_imp_2
(
    input      [3:0] a,
    output reg [3:0] y
);

    always @*
        casex (a)
        4'b1000: y <= 3;
        4'b0100: y <= 2;
        4'b0010: y <= 1;
        4'b0001: y <= 0;
        default: y <= 0;
        endcase

endmodule


module basys3  // _4
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    priority_circuit_imp_1 priority_circuit_imp_1
        (.a (sw [3:0]), .y (led [ 3: 0]));

    priority_circuit_imp_2 priority_circuit_imp_2
        (.a (sw [3:0]), .y (led [ 7: 4]));

    priority_encoder_imp_1 priority_encoder_imp_1
        (.a (sw [3:0]), .y (led [ 9: 8]));

    priority_encoder_imp_2 priority_encoder_imp_2
        (.a (sw [3:0]), .y (led [11:10]));

    parallel_encoder_imp_1 parallel_encoder_imp_1
        (.a (sw [3:0]), .y (led [13:12]));

    parallel_encoder_imp_2 parallel_encoder_imp_2
        (.a (sw [3:0]), .y (led [15:14]));

    assign seg = ~ 7'b0;
    assign dp  = 1'b1;
    assign an  = 4'b0;

endmodule

//--------------------------------------------------------------------

// Combinational building block: seven-segment driver

module single_digit_display
(
    input      [3:0] digit,
    input            single_digit,
    input            show_dot,

    output reg [6:0] seven_segments,
    output           dot,
    output     [3:0] anodes
);

    always @*
        case (digit)
        'h0: seven_segments = 'b1000000;  // a b c d e f g
        'h1: seven_segments = 'b1111001;
        'h2: seven_segments = 'b0100100;  //   --a--
        'h3: seven_segments = 'b0110000;  //  |     |
        'h4: seven_segments = 'b0011001;  //  f     b
        'h5: seven_segments = 'b0010010;  //  |     |
        'h6: seven_segments = 'b0000010;  //   --g--
        'h7: seven_segments = 'b1111000;  //  |     |
        'h8: seven_segments = 'b0000000;  //  e     c
        'h9: seven_segments = 'b0011000;  //  |     |
        'ha: seven_segments = 'b0001000;  //   --d-- 

        'hb: /* Fill the missing code */;

        'hc: seven_segments = 'b1000110;
        'hd: seven_segments = 'b0100001;
        'he: seven_segments = 'b0000110;
        'hf: seven_segments = 'b0001110;
        endcase

    assign dot    = ~ show_dot;
    assign anodes = single_digit ? 4'b1110 : 4'b0000;

endmodule

//--------------------------------------------------------------------

module basys3_5
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    single_digit_display single_digit_display
    (
        .digit           ( sw [3:0] ),
        .single_digit    ( sw [15]  ),
        .show_dot        ( sw [14]  ),

        .seven_segments  ( seg      ),
        .dot             ( dp       ),
        .anodes          ( an       )
    );

endmodule

//--------------------------------------------------------------------

// Sequential building block: counter

module clock_divider_100_MHz_to_1_49_Hz
(
    input  clock_100_MHz,
    input  resetn,
    output clock_1_49_Hz
);

    // 100 MHz / 2 ** 26 = 1.49 Hz

    reg [25:0] counter;

    always /* Fill the missing code */
    begin
        if (! resetn)
            counter <= 0;
        else
            counter <= counter + 1;
    end

    // Write code connecting bit 25 of the counter to the output


endmodule


module counter
(
    input             clock,
    input             resetn,
    output reg [15:0] count
);

    always @ (posedge clock or negedge resetn)
    begin
        if (! resetn)
            count <= 0;
        else
            count <= count + 1;
    end

endmodule


module basys3_6
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    wire clock;
    wire resetn = ! btnU;

    clock_divider_100_MHz_to_1_49_Hz clock_divider
    (
        .clock_100_MHz (clk),
        .resetn        (resetn),
        .clock_1_49_Hz (clock)
    );

    counter counter
    (
        .clock  ( clock  ),
        .resetn ( resetn ),
        .count  ( led    )
    );

    assign seg = ~ 7'b0;
    assign dp  = 1'b0;
    assign an  = 4'b0;

endmodule

//--------------------------------------------------------------------

// Sequential building block: counter with load and better display

module counter_with_load
(
    input             clock,
    input             resetn,

    input             load,
    input      [15:0] load_data,
    output reg [15:0] count
);

    always @ (posedge clock or negedge resetn)
    begin
        if (! resetn)
            count <= 0;

        
        // Write the code loading input data into the counter if load signal is asserted
        



        else
            count <= count + 1;
    end

endmodule

//--------------------------------------------------------------------

module clock_divider_100_MHz_to_95_4_Hz_and_1_53_KHz
(
    input  clock_100_MHz,
    input  resetn,
    output clock_95_4_Hz,
    output clock_1_53_KHz
);

    // 100 MHz / 2 ** 20 = 95.4 Hz
    // 100 MHz / 2 ** 16 = 1.53 KHz

    reg [29:0] counter;

    always @ (posedge clock_100_MHz)
    begin
        if (! resetn)
            counter <= 0;
        else
            counter <= counter + 1;
    end

    assign clock_95_4_Hz  = counter [19];
    assign clock_1_53_KHz = counter [15];

endmodule

//--------------------------------------------------------------------

module display
(
    input             clock,
    input             resetn,
    input      [15:0] number,

    output reg [ 6:0] seven_segments,
    output reg        dot,
    output reg [ 3:0] anodes
);

    function [6:0] bcd_to_seg (input [3:0] bcd);

        case (bcd)
        'h0: bcd_to_seg = 'b1000000;  // a b c d e f g
        'h1: bcd_to_seg = 'b1111001;
        'h2: bcd_to_seg = 'b0100100;  //   --a--
        'h3: bcd_to_seg = 'b0110000;  //  |     |
        'h4: bcd_to_seg = 'b0011001;  //  f     b
        'h5: bcd_to_seg = 'b0010010;  //  |     |
        'h6: bcd_to_seg = 'b0000010;  //   --g--
        'h7: bcd_to_seg = 'b1111000;  //  |     |
        'h8: bcd_to_seg = 'b0000000;  //  e     c
        'h9: bcd_to_seg = 'b0011000;  //  |     |
        'ha: bcd_to_seg = 'b0001000;  //   --d-- 

        'hb: /* Fill the missing code */;

        'hc: bcd_to_seg = 'b1000110;
        'hd: bcd_to_seg = 'b0100001;
        'he: bcd_to_seg = 'b0000110;
        'hf: bcd_to_seg = 'b0001110;
        endcase

    endfunction

    reg [1:0] i;

    always @ (posedge clock or negedge resetn)
    begin
        if (! resetn)
        begin
            seven_segments <=   bcd_to_seg (0);
            dot            <= ~ 0;
            anodes         <= ~ 'b0001;

            i <= 0;
        end
        else
        begin
            seven_segments <=   bcd_to_seg (number [i * 4 +: 4]);
            dot            <= ~ 0;
            anodes         <= ~ (1 << i);

            i <= i + 1;
        end
    end

endmodule

//--------------------------------------------------------------------

module basys3_7
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    wire clock;
    wire resetn = ! btnU;

    wire clock;
    wire display_clock;

    clock_divider_100_MHz_to_95_4_Hz_and_1_53_KHz clock_divider
    (
        .clock_100_MHz  ( clk           ),
        .resetn         ( resetn        ),
        .clock_95_4_Hz  ( clock         ),
        .clock_1_53_KHz ( display_clock )
    );

    wire [15:0] count;

    
    // Instantiate module counter_with_load connecting load to btnC and load_data to sw
    

    
    
    
    
    
    
    
    

    assign led = count;

    display display
    (
        .clock          ( display_clock  ),
        .resetn         ( resetn         ),
        .number         ( count          ),

        .seven_segments ( seg            ),
        .dot            ( dp             ),
        .anodes         ( an             )
    );

endmodule

//--------------------------------------------------------------------

// Sequential building block: shift register

module shift_register
(
    input             clock,
    input             resetn,
    input             in,
    output            out,
    output reg [15:0] data
);

    always @ (posedge clock or negedge resetn)
    begin
        if (! resetn)
            data <= 16'hABCD;
        else
            
            // Write code that shifts data to the right
            // and pushes in data from the left
            



    end
    
    assign out = data [0];

endmodule

module basys3_8
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    wire clock;
    wire resetn = ! btnU;

    clock_divider_100_MHz_to_1_49_Hz clock_divider
    (
        .clock_100_MHz (clk),
        .resetn        (resetn),
        .clock_1_49_Hz (clock)
    );

    wire out;

    shift_register shift_register
    (
        .clock      ( clock  ),
        .resetn     ( resetn ),
        .in         ( btnC   ),
        .out        ( out    ),
        .data       ( led    )
    );

    assign seg = out ? 7'b1111001 : 7'b1000000;
    assign dp  = 1'b1;
    assign an  = 4'b1110;

endmodule

//--------------------------------------------------------------------

// Sequential building block: shift register with enable


// Write code for a variant of shift_register module
// with an additional "enable" signal
// so that the shifting happens only if "enable" is 1

























module basys3_9
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    wire clock;
    wire resetn = ! btnU;

    clock_divider_100_MHz_to_1_49_Hz clock_divider_100_MHz_to_1_49_Hz
    (
        .clock_100_MHz (clk),
        .resetn        (resetn),
        .clock_1_49_Hz (clock)
    );

    clock_divider_100_MHz_to_95_4_Hz_and_1_53_KHz clock_divider_100_MHz_to_95_4_Hz_and_1_53_KHz
    (
        .clock_100_MHz  ( clk           ),
        .resetn         ( resetn        ),
        .clock_95_4_Hz  (               ),
        .clock_1_53_KHz ( display_clock )
    );

    shift_register_with_enable shift_register_with_enable
    (
        .clock      (   clock  ),
        .resetn     (   resetn ),
        .in         (   btnC   ),
        .enable     ( ~ btnR   ),
        .out        (          ),
        .data       (   led    )
    );

    display display
    (
        .clock          ( display_clock  ),
        .resetn         ( resetn         ),
        .number         ( led            ),

        .seven_segments ( seg            ),
        .dot            ( dp             ),
        .anodes         ( an             )
    );

endmodule

//--------------------------------------------------------------------

// Smiling Snail FSM derived from David Harris & Sarah Harris

module pattern_fsm_moore
(
    input  clock,
    input  resetn,
    input  a,
    output y
);

    parameter [1:0] S0 = 0, S1 = 1, S2 = 2;

    reg [1:0] state, next_state;

    // state register

    
    // Write code for the state register
    // that sets the state to S0 on asynchronous active low reset
    // and sets the state to next_state on positive edge of clock
    



    
    
    
    
    

    // next state logic

    
    // Write proper code for combinational "always" block (1 line)
    



        case (state)

        S0:
            
            // Rewrite "if" statement below
            // using Verilog "?:" operator
            

            if (a)
                next_state = S0;
            else
                next_state = S1;

        S1:
            if (a)
                next_state = S2;
            else
                next_state = S1;

        S2:
            if (a)
                next_state = S0;
            else
                next_state = S1;

        default:

            next_state = S0;

        endcase

    // output logic

    assign y = (state == S2);

endmodule

//--------------------------------------------------------------------

module pattern_fsm_mealy
(
    input  clock,
    input  resetn,
    input  a,
    output y
);

    parameter S0 = 0, S1 = 1;

    reg state, next_state;

    // state register

    
    // Write code for the state register
    // that sets the state to S0 on asynchronous active low reset
    // and sets the state to next_state on positive edge of clock
    








    // next state logic

    
    // Write proper code for combinational "always" block (1 line)
    



        case (state)

        S0:
            
            // Rewrite "if" statement below
            // using Verilog "case" statement
            

            if (a)
                next_state = S0;
            else
                next_state = S1;

        S1:
            if (a)
                next_state = S0;
            else
                next_state = S1;

        default:

            next_state = S0;

        endcase

    // output logic

    assign y = (a & state == S1);

endmodule

//--------------------------------------------------------------------

module basys3_10
(
    input         clk,

    input         btnC,
    input         btnU,
    input         btnL,
    input         btnR,
    input         btnD,

    input  [15:0] sw,

    output [15:0] led,

    output [ 6:0] seg,
    output        dp,
    output [ 3:0] an
);

    wire clock;
    wire resetn = ! btnU;

    clock_divider_100_MHz_to_1_49_Hz clock_divider
    (
        .clock_100_MHz (clk),
        .resetn        (resetn),
        .clock_1_49_Hz (clock)
    );

    wire [15:0] shift_data_out;

    shift_register shift_register
    (
        .clock      ( clock          ),
        .resetn     ( resetn         ),
        .in         ( btnC           ),
        .out        (                ),
        .data       ( shift_data_out )
    );

    wire fsm_in = shift_data_out [8];
    assign led = shift_data_out;

    wire moore_out;

    pattern_fsm_moore pattern_fsm_moore
    (
        .clock  ( clock     ),
        .resetn ( resetn    ),
        .a      ( fsm_in    ),
        .y      ( moore_out )
    );

    wire mealy_out;

    pattern_fsm_mealy pattern_fsm_mealy
    (
        .clock  ( clock     ),
        .resetn ( resetn    ),
        .a      ( fsm_in    ),
        .y      ( mealy_out )
    );

    assign seg [0] = ~  moore_out;
    assign seg [1] = ~  moore_out;
    assign seg [2] = ~  mealy_out;
    assign seg [3] = ~  mealy_out;
    assign seg [4] = ~  mealy_out;
    assign seg [5] = ~  moore_out;
    assign seg [6] = ~ (moore_out | mealy_out);

    assign dp  = 1'b1;
    assign an  = 4'b1110;

endmodule
Examples written by Yuri Panchul with some borrowing from Digital Design and Computer Architecture, Second Edition by David Harris and Sarah Harris, 2012