Extra materials for the combined MIPSfpga and Connected MCU seminar by Imagination Technologies
October-November 2016
An example introductory project: Implement a design of a shift register with enable signal. The design should input a single bit from a key and put in into the shift register. The current state and the output of the shift register should be displayed on LEDs in binary representation. In addition, the current state of the shift register should be displayed on static multi-digit seven-segment display in hexadecimal form.
3.1. Modify the counter design to count in decimal instead of hexadecimal. Not 0, 1, 2, ... 9, A, B, C, D, E, F, 10, 11, ... FFFF - but 0, 1, 2, ... 9, 10, 11, ... 9999, 0, 1, 2, ... Hint: you may need to add decimal digits separately and propagate carry.
3.2. Modify the counter design to count signed two's complement 12-bit number backwards. Output the result in hexadecimal representation with a sign: 000, -001, -002, ... -7FE, -7FF, -800, (overflow), 7FF, 7FE, 7FD, ... 002, 001, 000, -001, -002 ...
3.3. Modify the counter design to count with three different speeds, depending on pressed button.
3.4. Modify the counter design to count either forward (0, 1, 2, ...) or backward (0, FFFF, FFFE, ... , 3, 2, 1, 0, FFFF ...), depending on pressed button.
3.5. Modify the counter design to count either adding 1, or 2, or 3, depending on pressed buttons.
3.6. Modify the counter design to add disable signal that pauses counting. Connect this signal to a button.
3.7. Modify the counter design to count separately in each digit. Not 0000, 0001, 0002, ... FFFE, FFFF, 0000 - but 0000, 1111, 2222, 3333, ... EEEE, FFFF, 0000.
3.8. Modify the counter design to count separately in each two digits - 0000, 0101, 0202, ... FEFE, FFFF, 0000.
3.9. Modify the counter design to count separately in digit 3 and digits 2:0 - 0000, 1001, 2002, ... F00F, 0010, 1011, ... EFFE, FFFF, 0000.
3.10. Modify the counter design to count separately in each digit with different speed: 0000, 1234, 2468, 369C, 48C0, 5AF4, ... In other words one digit 0, 1, 2, ... F, 0; second 0, 2, 4, 6, ... E, 0; third one 0, 3, 6, 9, C, F, 2, 5, 8, B, E, 1, 4, 7, A, D, 0, fourth 0, 4, 8, C, 0, ...
3.11. Implement the design that generates Fibonnacci numbers: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34, ... The next number is found by adding up the two numbers before it.
3.12. Modify the shift register design to make LED lights moving not from left to right, but from right to left. Not 10011000, 01001100, 00100110, 00010011, 00001001, 00000100, ... - but 10011000, 00110000, 01100000, 11000000, ...
3.13. Modify the shift register design to make LED lights moving either from left to right or from right to left - depending on pressed button.
3.14. Modify the shift register design to make LED lights moving with different speed - depending on pressed button.
3.15. Modify the shift register design to make LED lights circularly: 10011000, 01001100, 00100110, 00010011, 10001001, 11000100, 01100010, 00110001, 10011000, ... Use one button as input, and a second button as input enable.
3.16. Modify the shift register design to make LED lights moving circularly and either from left to right or from right to left - depending on pressed button. Use one button as input, second button as input enable, and third button to control the direction of movement.
3.17. Modify the shift register design by splitting it into two independent 4-bit wide shift registers, with inputs coming from two different buttons.
3.18. Modify the shift register design by splitting it into two independent 4-bit wide shift registers, with inputs coming from the same button and with different speeds of shifting. The first should shift with the speed of one bit per clock cycle, the second - with the speed of two bits per clock cycle.
3.19. Modify the shift register design by splitting it into two independent 4-bit wide shift registers, with inputs coming from the same button and with different speeds of shifting. The first should shift with the speed of one bit per clock cycle, the second - with the speed of one bit every other cycle.
3.20. Implement a variant of exercise (18) with circular movements of LED lights. Use one button as input, and a second button as input enable.
3.21. Implement a variant of exercise (19) with circular movements of LED lights. Use one button as input, and a second button as input enable.
3.22. Implement a variant of exercise (18) with LEDs connected to the first shift register moving from left to right and LEDs connected to another one - from right to left.
3.23. Implement a variant of exercise (19) with LEDs connected to the first shift register moving from left to right and LEDs connected to another one - from right to left.
3.24. Implement a variant of exercise (22) with circular movements of LED lights. Use one button as input, and a second button as input enable.
3.25. Implement a variant of exercise (23) with circular movements of LED lights. Use one button as input, and a second button as input enable.
3.26. Modify the state machine design below by counting the occurrences of "01" sequences (i.e. counting the number of event when moore_out and mealy_out asserted). Output the number of moore_out events to the digits 3:2 of seven-segment display and the number of mealy_out events to the digits 1:0 of seven-segment display.
3.27. Modify the state machine design below to recognize the sequences of "0101" instead of "01". You need to implement only Moore machine.
3.28. Modify the state machine design below to recognize the sequences of "010101" instead of "01". You need to implement only Mealy machine.
3.29. Implement a variant of exercise 27 where you count the number of sequences instead of just recognizing them. Output the value of the counter to seven-segment display.
3.30. Implement a variant of exercise 28 where you count the number of sequences instead of just recognizing them. Output the value of the counter to seven-segment display.
module de0_cv ( input CLOCK2_50, input CLOCK3_50, inout CLOCK4_50, input CLOCK_50, input RESET_N, input [ 3:0] KEY, input [ 9:0] SW, output [ 9:0] LEDR, output [ 6:0] HEX0, output [ 6:0] HEX1, output [ 6:0] HEX2, output [ 6:0] HEX3, output [ 6:0] HEX4, output [ 6:0] HEX5, output [12:0] DRAM_ADDR, output [ 1:0] DRAM_BA, output DRAM_CAS_N, output DRAM_CKE, output DRAM_CLK, output DRAM_CS_N, inout [15:0] DRAM_DQ, output DRAM_LDQM, output DRAM_RAS_N, output DRAM_UDQM, output DRAM_WE_N, output [ 3:0] VGA_B, output [ 3:0] VGA_G, output VGA_HS, output [ 3:0] VGA_R, output VGA_VS, inout PS2_CLK, inout PS2_CLK2, inout PS2_DAT, inout PS2_DAT2, output SD_CLK, inout SD_CMD, inout [ 3:0] SD_DATA, inout [35:0] GPIO_0, inout [35:0] GPIO_1 ); de0_cv_small de0_cv_small ( .CLOCK_50 ( CLOCK_50 ), .RESET_N ( RESET_N ), .KEY ( KEY ), .SW ( SW ), .LEDR ( LEDR ), .HEX0 ( HEX0 ), .HEX1 ( HEX1 ), .HEX2 ( HEX2 ), .HEX3 ( HEX3 ), .HEX4 ( HEX4 ), .HEX5 ( HEX5 ) ); endmodule //---------------------------------------------------------------------------- module clock_divider_50_MHz_to_1_49_Hz ( input clock_50_MHz, input reset_n, output clock_1_49_Hz ); // 50 MHz / 2 ** 25 = 1.49 Hz reg [24:0] count; always @ (posedge clock_50_MHz) begin if (! reset_n) count <= 0; else count <= count + 1; end assign clock_1_49_Hz = count [24]; endmodule //---------------------------------------------------------------------------- module counter_with_load ( input clock, input reset_n, input load, input [15:0] load_data, output reg [15:0] count ); always @ (posedge clock or negedge reset_n) begin if (! reset_n) count <= 0; else if (load) count <= load_data; else count <= count + 1; end endmodule //---------------------------------------------------------------------------- module shift_register_with_enable ( input clock, input reset_n, input in, input enable, output out, output reg [9:0] data ); always @ (posedge clock or negedge reset_n) begin if (! reset_n) data <= 10'b10_0000_0000; else if (enable) data <= { in, data [9:1] }; end assign out = data [0]; endmodule //---------------------------------------------------------------------------- module single_digit_display ( input [3:0] digit, output reg [6:0] seven_segments ); 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: seven_segments = 'b0000011; 'hc: seven_segments = 'b1000110; 'hd: seven_segments = 'b0100001; 'he: seven_segments = 'b0000110; 'hf: seven_segments = 'b0001110; endcase endmodule //---------------------------------------------------------------------------- // Smiling Snail FSM derived from David Harris & Sarah Harris module pattern_fsm_moore ( input clock, input reset_n, input a, output y ); parameter [1:0] S0 = 0, S1 = 1, S2 = 2; reg [1:0] state, next_state; // state register always @ (posedge clock or negedge reset_n) if (! reset_n) state <= S0; else state <= next_state; // next state logic always @* case (state) S0: 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 //---------------------------------------------------------------------------- // Smiling Snail FSM derived from David Harris & Sarah Harris module pattern_fsm_mealy ( input clock, input reset_n, input a, output y ); parameter S0 = 1'b0, S1 = 1'b1; reg state, next_state; // state register always @ (posedge clock or negedge reset_n) if (! reset_n) state <= S0; else state <= next_state; // next state logic always @* case (state) S0: 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 de0_cv_small ( input CLOCK_50, input RESET_N, input [3:0] KEY, input [9:0] SW, output [9:0] LEDR, output [6:0] HEX0, output [6:0] HEX1, output [6:0] HEX2, output [6:0] HEX3, output [6:0] HEX4, output [6:0] HEX5 ); wire clock_before_global, clock, shift_out, fsm_out; clock_divider_50_MHz_to_1_49_Hz clock_divider_50_MHz_to_1_49_Hz ( .clock_50_MHz ( CLOCK_50 ), .reset_n ( RESET_N ), .clock_1_49_Hz ( clock_before_global ) ); global global ( .in ( clock_before_global ), .out ( clock ) ); //------------------------------------------------------------------------ wire [15:0] count; counter_with_load counter_with_load ( .clock ( clock ), .reset_n ( RESET_N ), .load ( ~ KEY [2] ), .load_data ( { 6'b0, SW } ), .count ( count ) ); //------------------------------------------------------------------------ single_digit_display digit_0 ( .digit ( count [ 3: 0] ), .seven_segments ( HEX0 ) ); single_digit_display digit_1 ( .digit ( count [ 7: 4] ), .seven_segments ( HEX1 ) ); single_digit_display digit_2 ( .digit ( count [11: 8] ), .seven_segments ( HEX2 ) ); single_digit_display digit_3 ( .digit ( count [15:12] ), .seven_segments ( HEX3 ) ); //------------------------------------------------------------------------ shift_register_with_enable shift_register_with_enable ( .clock ( clock ), .reset_n ( RESET_N ), .in ( ~ KEY [1] ), .enable ( KEY [0] ), .out ( shift_out ), .data ( LEDR ) ); //------------------------------------------------------------------------ wire moore_fsm_out, mealy_fsm_out; pattern_fsm_moore pattern_fsm_moore ( .clock ( clock ), .reset_n ( RESET_N ), .a ( shift_out ), .y ( moore_fsm_out ) ); pattern_fsm_mealy pattern_fsm_mealy ( .clock ( clock ), .reset_n ( RESET_N ), .a ( shift_out ), .y ( mealy_fsm_out ) ); assign HEX5 = moore_fsm_out ? 7'b1100011 : 7'b1111111; assign HEX4 = mealy_fsm_out ? 7'b1100011 : 7'b1111111; endmodule
FSM code is from textbook Digital Design and Computer Architecture, Second Edition by David Harris and Sarah Harris, 2012. Rest of the exercise is created by Yuri Panchul