// // the .xdc file is suffixed // // // change log overview: // // 2020/05/26: // // (Jing) edits/changes: // - reg state [BIG CHANGE] (rewrite the state transition) // - reg cursor_posit (tidy/clean up code) // - reg x (fix syntax error due to invalid dimension declaration) // - reg y (fix syntax error due to invalid dimension declaration) // // (Jing) adds/creates: // - integer i // - localparam KEY_ // - wire find_number_pressed // - reg last_change_bcd // - wire method_to_generate_x // - wire find_collision // - reg a // - reg b // // 2020/05/28 forenoon: // // (Jing) edits/changes: // - reg x (split always @ and extend dimension) // - reg y (split always @ and extend dimension) // - reg find_collision (split to find_x_collision and find_y_collision) // - reg state (remove latch inferring) // - reg last_change_bcd (add a localparam to represent non-BCD char) // - reg a (fix syntax error due to dimension expansion of x and y) // - reg b (fix syntax error due to dimension expansion of x and y) // // (Jing) adds/creates: // - reg round // - reg led // - reg rng_10 (random number generator) // // (Jing) sidenotes: // - split out the miscellaneous signals from "global" section. // - comment out the vga part. // // 2020/05/28 afternoon: // // (Jing) sidenotes: // - slightly modified the state transition. // - rename ssd_digit_? to extended_bcd_digit[0:3] // - separates extended_bcd_digit[0:3] out to their own sections // - rename extended_bcd_digit[0:3] to ssd_content_selector[0:3] // - [rewrite] anode 1-hot enable and cathode select. // - instantiates extended_bcd_to_ssd_decoder. // - adds reg ssd and reg point. // - ssd_cathode is now composed of {ssd, point}. // - the cursor is now a blinking point. // - rename find_?_collision to ?_valid. // - add clk_1hz and timer. // - the SSD will show total time after 4A0B. // - you can now press X to see the value of X. // - you can now press Y to see the value of Y. // - you can now press T to see the current time. // - (2020/05/28 23:51) fully debugged and playable. // // 2020/06/11: // (Jing) sidenote: // - instantiate the RandomX.v (see the "lfsr", "x_valid", and "x" sections) // - use a 16-bit LFSR to replace the timing-based randomizer (see "x") // // 2020/06/12: // (Jing) sidenote: // - create "number_scancode" (convert the BCD to corresponding scancode). // - rename "find_number_pressed" to "right_number_pressed". // - create "left_number_pressed". // - add P, Q, W, E, R, and T into the number list // (representing 10, 11, 12, 13, 14, and 15 respectively) // (see "left_number_pressed" and "number_scancode" sections). // - expand y[cursor_posit] to y[round][cursor_posit]. // - rewrite "ssd_content_selector" (it's combinational logic now). // - players can now press left-hand-side keyboard to query log. // (see "y" and "ssd_content_selector" sections) // - round will now reset to 0 after gameover (see "round" section). // // 2020/06/18: // (Jing) note: // - add new switchs input "auto_generate_y", "auto_generate_ab". // - rewrite lots of codes to implement a simple AI. // - rename GAMEOVER to STATE_GG, // WAIT_X to STATE_X, // WAIT_Y to STATE_Y, // SHOW_AB to STATE_AB. // - players can now press shift + left-hand-side-numbers to query ab log. // module final_project_TOP( /* // debug switch input debugswitch0, // W17 input debugswitch1, // W16 input debugswitch2, // V16 input switch0, switch1, switch2, switch3, switch4, switch5, switch6, switch7, */ // SSD output [7:0] ssd_cathode, output [3:0] ssd_anode, // I2S (speaker) output audio_mclk, // master clock output audio_lrck, // left-right clock output audio_sck, // serial clock output audio_sdin, // serial audio data input // LED output reg [15:0] led, // PS2 (keyboard) inout PS2_DATA, inout PS2_CLK, // DIP switch input auto_generate_x, input auto_generate_y, input auto_generate_ab, // miscellaneous input clk_100mhz, input rst_n // active low reset ); // // global (declaration only) // // integer: // // i, j: // for (; ; ) begin // // Statements // end // // reg: // // state: // the current state and localparam of the FSM. // the definition is in the "state transition" section below. // x: // the target number to be guessed // the definition is in the "x" section below. // usage: " x[cursor_posit] " // y: // the definition is in the "y" section below. // usage: " y[round][cursor_posit] " // // log: // // 2020/06/12: // (Jing) add one more integer (see "j"). // (Jing) expand y[cursor_posit] to y[round][cursor_posit]. // integer i; integer j; integer k; integer l; reg [1:0] state; localparam STATE_GG = 4'd0; localparam STATE_X = 4'd1; localparam STATE_Y = 4'd2; localparam STATE_AB = 4'd3; reg [3:0] x[0:3]; reg [3:0] y[0:15][0:3]; reg [2:0] a[0:15]; reg [2:0] b[0:15]; // // miscellaneous // // wire: // // rst: // active high reset. // reset: // active high reset. // // reg: // // clk_freerun: // a free-run n-bit binary counter to generate 100M / 2^n Hz clock. // localparam TRUE = 1'b1; localparam FALSE = 1'b0; wire rst; wire reset; assign rst = ~rst_n; assign reset = ~rst_n; reg [31:0] clk_freerun; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) clk_freerun <= 'b0; else clk_freerun <= clk_freerun + 32'b1; end // // keyboard IP // // wire: // // key_down: // status bits. Each bit indicates pressed (1) or released (0) of each // button of the keyboard. // last_change: // represent the key which has been pressed or released. // key_valid: // should be active for one clock period when any key is pressed or // released. // wire [511:0] key_down; wire [8:0] last_change; wire key_valid; KeyboardDecoder KeyboardDecoder( // output .key_down, .last_change, .key_valid, // inout .PS2_DATA, .PS2_CLK, // input .rst, .clk (clk_100mhz) // 100mhz clock ); // // localparam KEY_??? // // usage: // " if (key_down[KEY_???]) " // " if (last_change == KEY_???) " // // note: // usually checked with " if (key_valid) " // // left-hand-side numbers localparam KEY_0L = 9'h45; localparam KEY_1L = 9'h16; localparam KEY_2L = 9'h1E; localparam KEY_3L = 9'h26; localparam KEY_4L = 9'h25; localparam KEY_5L = 9'h2E; localparam KEY_6L = 9'h36; localparam KEY_7L = 9'h3D; localparam KEY_8L = 9'h3E; localparam KEY_9L = 9'h46; // right-hand-side numbers localparam KEY_0R = 9'h70; localparam KEY_1R = 9'h69; localparam KEY_2R = 9'h72; localparam KEY_3R = 9'h7A; localparam KEY_4R = 9'h6B; localparam KEY_5R = 9'h73; localparam KEY_6R = 9'h74; localparam KEY_7R = 9'h6C; localparam KEY_8R = 9'h75; localparam KEY_9R = 9'h7D; // alphabet localparam KEY_A = 9'h01C; localparam KEY_B = 9'h032; localparam KEY_C = 9'h021; localparam KEY_D = 9'h023; localparam KEY_E = 9'h024; localparam KEY_F = 9'h02B; localparam KEY_G = 9'h034; localparam KEY_H = 9'h033; localparam KEY_I = 9'h043; localparam KEY_J = 9'h03B; localparam KEY_K = 9'h042; localparam KEY_L = 9'h04B; localparam KEY_M = 9'h03A; localparam KEY_N = 9'h031; localparam KEY_O = 9'h044; localparam KEY_P = 9'h04D; localparam KEY_Q = 9'h015; localparam KEY_R = 9'h02D; localparam KEY_S = 9'h01B; localparam KEY_T = 9'h02C; localparam KEY_U = 9'h03C; localparam KEY_V = 9'h02A; localparam KEY_W = 9'h01D; localparam KEY_X = 9'h022; localparam KEY_Y = 9'h035; localparam KEY_Z = 9'h01A; // miscellaneous localparam KEY_MINUS = 9'h04E; localparam KEY_EQUAL = 9'h055; localparam KEY_LSHIFT = 9'h012; localparam KEY_RSHIFT = 9'h059; localparam KEY_ENTER = 9'h05A; localparam KEY_BACKSPACE = 9'h066; localparam KEY_LESS_THAN = 9'h041; localparam KEY_MORE_THAN = 9'h049; // // right_number_pressed // left_number_pressed // // log: // // 2020/06/12: // (Jing) rename "find_number_pressed" to "right_number_pressed". // (Jing) create "left_number_pressed". // wire right_number_pressed; assign right_number_pressed = key_down[KEY_0R] | key_down[KEY_1R] | key_down[KEY_2R] | key_down[KEY_3R] | key_down[KEY_4R] | key_down[KEY_5R] | key_down[KEY_6R] | key_down[KEY_7R] | key_down[KEY_8R] | key_down[KEY_9R]; wire left_number_pressed; assign left_number_pressed = key_down[KEY_0L] | key_down[KEY_1L] | key_down[KEY_2L] | key_down[KEY_3L] | key_down[KEY_4L] | key_down[KEY_5L] | key_down[KEY_6L] | key_down[KEY_7L] | key_down[KEY_8L] | key_down[KEY_9L] | key_down[KEY_P] | key_down[KEY_Q] | key_down[KEY_W] | key_down[KEY_E] | key_down[KEY_R] | key_down[KEY_T]; // // last_change_bcd // last_change in bcd decoded // (LUT) convert scancode to BCD // // change log: // // 2020/05/28: // (Jing) add a localparam (defalut 4'hC) to represent a non-BCD char // // 2020/06/12: // (Jing) remove localparam NOT_BCD. now 4'hE represents a non-BCD char // reg [3:0] last_change_bcd; always @* begin case (last_change) // left-hand-side keyboard 8'h45: last_change_bcd = 4'd0; 8'h16: last_change_bcd = 4'd1; 8'h1E: last_change_bcd = 4'd2; 8'h26: last_change_bcd = 4'd3; 8'h25: last_change_bcd = 4'd4; 8'h2E: last_change_bcd = 4'd5; 8'h36: last_change_bcd = 4'd6; 8'h3D: last_change_bcd = 4'd7; 8'h3E: last_change_bcd = 4'd8; 8'h46: last_change_bcd = 4'd9; // right-hand-side keyboard 8'h70: last_change_bcd = 4'd0; 8'h69: last_change_bcd = 4'd1; 8'h72: last_change_bcd = 4'd2; 8'h7A: last_change_bcd = 4'd3; 8'h6B: last_change_bcd = 4'd4; 8'h73: last_change_bcd = 4'd5; 8'h74: last_change_bcd = 4'd6; 8'h6C: last_change_bcd = 4'd7; 8'h75: last_change_bcd = 4'd8; 8'h7D: last_change_bcd = 4'd9; default: last_change_bcd = 4'hE; // catch "E"rror endcase end // // number_scancode: // (LUT) convert BCD to scancode (left-hand-side keyboard) // // usage: number_scancode[BCD] // // // log: // 2020/06/12: // (Jing) initial commit // wire [7:0] number_scancode[0:15]; assign number_scancode[0] = KEY_0L; assign number_scancode[1] = KEY_1L; assign number_scancode[2] = KEY_2L; assign number_scancode[3] = KEY_3L; assign number_scancode[4] = KEY_4L; assign number_scancode[5] = KEY_5L; assign number_scancode[6] = KEY_6L; assign number_scancode[7] = KEY_7L; assign number_scancode[8] = KEY_8L; assign number_scancode[9] = KEY_9L; assign number_scancode[10] = KEY_P; assign number_scancode[11] = KEY_Q; assign number_scancode[12] = KEY_W; assign number_scancode[13] = KEY_E; assign number_scancode[14] = KEY_R; assign number_scancode[15] = KEY_T; // // lfsr: // // log: // 2020/06/11: // (Jing) initial commit // // 2020/06/19: // (Jing) change initial condition. // reg [15:0] lfsr; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin lfsr <= 'b0; end else if (lfsr == 16'b0) begin lfsr <= 16'hFFFF; // seed end else begin lfsr <= {lfsr, lfsr[10] ^ lfsr[12] ^ lfsr[13] ^ lfsr[15]}; end end // // round // // log: // // 2020/06/12: // (Jing) round will now reset to 0 after gameover // // 2020/06/19: // (Jing) rewrite some nested if-else to improve readability. // reg [3:0] round; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin round <= 'b0; end else if (key_valid && key_down[KEY_ENTER]) begin if (state == STATE_GG) round <= 16'h0; if (state == STATE_AB) round <= round + 16'b1; end else begin round <= round; end end // // cursor_posit // cursor_step // // 3 2 1 0 (positional) // // change: // 2020/06/18: // (Jing) rename cursor_position to cursor_posit. // (Jing) add cursor_step. // wire [1:0] cursor_step; assign cursor_step = (state == STATE_AB) ? (2'd2) : (2'd1); reg [1:0] cursor_posit; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin cursor_posit <= 'b0; end else if (key_valid) begin case (1'b1) right_number_pressed: cursor_posit <= cursor_posit - cursor_step; key_down[KEY_BACKSPACE]: cursor_posit <= cursor_posit + cursor_step; key_down[KEY_MORE_THAN]: cursor_posit <= cursor_posit - cursor_step; key_down[KEY_LESS_THAN]: cursor_posit <= cursor_posit + cursor_step; key_down[KEY_ENTER]: cursor_posit <= 2'd3; default: cursor_posit <= cursor_posit; endcase end else begin cursor_posit <= cursor_posit; end end // // x_valid // y_valid // // // change log: // // 2020/05/28: // (Jing) find_collision split to find_x_collision and find_y_collision // (Jing) rename find_?_collision to ?_valid // wire x_valid; assign x_valid = (x[0] != x[1]) & (x[0] != x[2]) & (x[0] != x[3]) & (x[1] != x[2]) & (x[1] != x[3]) & (x[2] != x[3]) & (x[0] <= 4'd9) & (x[1] <= 4'd9) & (x[2] <= 4'd9) & (x[3] <= 4'd9); wire y_valid; assign y_valid = (y[round][0] != y[round][1]) & (y[round][0] != y[round][2]) & (y[round][0] != y[round][3]) & (y[round][1] != y[round][2]) & (y[round][1] != y[round][3]) & (y[round][2] != y[round][3]) & (y[round][0] <= 4'd9) & (y[round][1] <= 4'd9) & (y[round][2] <= 4'd9) & (y[round][3] <= 4'd9); wire ab_valid; assign ab_valid = ( (a[round] + b[round]) <= 3'd4 ); // // count_16 // find_y_conflict_log // // change: // // 2020/06/19: // (Jing) initial commit. // reg [3:0] count_16; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) count_16 <= 'b0; else count_16 <= count_16 + 4'b1; end wire find_y_conflict_log; assign find_y_conflict_log = (count_16 < round) && ( (y[round][0] == y[count_16][0]) + (y[round][1] == y[count_16][1]) + (y[round][2] == y[count_16][2]) + (y[round][3] == y[count_16][3]) != a[count_16] || (y[round][0] == y[count_16][3]) + (y[round][0] == y[count_16][2]) + (y[round][0] == y[count_16][1]) + (y[round][1] == y[count_16][3]) + (y[round][1] == y[count_16][2]) + (y[round][1] == y[count_16][0]) + (y[round][2] == y[count_16][3]) + (y[round][2] == y[count_16][1]) + (y[round][2] == y[count_16][0]) + (y[round][3] == y[count_16][2]) + (y[round][3] == y[count_16][1]) + (y[round][3] == y[count_16][0]) != b[count_16] ); // // x // // declared in the "global" section above: // reg [3:0] x[0:3]; // // change log: // // 2020/05/26: // (Jing) tidy up // // 2020/05/28: // (Jing) split always@ (improve readability) // (Jing) the default value is now set to be "4'hF - cursor_posit" // // 2020/06/11: // (Jing) use a 16-bit LFSR to replace the timing-based randomizer. // // 2020/06/18: // (Jing) rewrite to implement a simple AI. // always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin x[0] <= 'b0; x[1] <= 'b0; x[2] <= 'b0; x[3] <= 'b0; end else if (state == STATE_GG && key_valid && key_down[KEY_ENTER]) begin x[0] <= 4'hF; x[1] <= 4'hF; x[2] <= 4'hF; x[3] <= 4'hF; end else if (state == STATE_X) begin if (auto_generate_x) begin if (!x_valid) begin x[0] <= lfsr >> 0; x[1] <= lfsr >> 4; x[2] <= lfsr >> 8; x[3] <= lfsr >> 12; end end else begin // !auto_generate_x if (key_valid) begin if (right_number_pressed) x[cursor_posit] <= last_change_bcd; if (key_down[KEY_BACKSPACE]) x[cursor_posit] <= 4'hF; end end end else begin x[0] <= x[0]; x[1] <= x[1]; x[2] <= x[2]; x[3] <= x[3]; end end // // y // // declared in the "global" section above: // reg [3:0] y[0:15][0:3]; // // change log: // // 2020/05/26: // (Jing) tidy up // // 2020/05/28: // (Jing) split always@ // (Jing) the default value is now set to be "4'hF - cursor_posit" // // 2020/06/12: // {Jing) y will now reset to 4'hF after gameover. // // 2020/06/18: // (Jing) rewrite to implement a simple AI. // always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin for (i = 0; i <= 15; i = i + 1) begin for (j = 0; j <= 3; j = j + 1) begin y[i][j] <= 'b0; end end end else if (state == STATE_GG && key_valid && key_down[KEY_ENTER]) begin for (i = 0; i <= 15; i = i + 1) begin for (j = 0; j <= 3; j = j + 1) begin y[i][j] <= 4'hF; end end end else if (state == STATE_Y) begin if (auto_generate_y) begin if (find_y_conflict_log || !y_valid) begin y[round][0] <= lfsr >> 0; y[round][1] <= lfsr >> 4; y[round][2] <= lfsr >> 8; y[round][3] <= lfsr >> 12; end end else begin // !auto_generate_y if (key_valid) begin if (right_number_pressed) y[round][cursor_posit] <= last_change_bcd; if (key_down[KEY_BACKSPACE]) y[round][cursor_posit] <= 4'hF; end end end else begin for (i = 0; i <= 15; i = i + 1) begin for (j = 0; j <= 3; j = j + 1) begin y[i][j] <= y[i][j]; end end end end // // a b // // declared in "global" section: // // reg [2:0] a[0:15]; // reg [2:0] b[0:15]; // // change log: // // 2020/05/28: // (Jing) fix syntax error due to dimension expansion of x and y // // 2020/06/18: // (Jing) rewrite to implement a simple AI. // always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin for (i = 0; i <= 15; i = i + 1) begin a[i] <= 'b0; b[i] <= 'b0; end end else if (state == STATE_GG && key_valid && key_down[KEY_ENTER]) begin for (i = 0; i <= 15; i = i + 1) begin a[i] <= 3'b0; b[i] <= 3'b0; end end else if (state == STATE_AB) begin if (auto_generate_ab) begin a[round] <= (x[0] == y[round][0]) + (x[1] == y[round][1]) + (x[2] == y[round][2]) + (x[3] == y[round][3]); b[round] <= (x[0] == y[round][1]) + (x[0] == y[round][2]) + (x[0] == y[round][3]) + (x[1] == y[round][0]) + (x[1] == y[round][2]) + (x[1] == y[round][3]) + (x[2] == y[round][0]) + (x[2] == y[round][1]) + (x[2] == y[round][3]) + (x[3] == y[round][0]) + (x[3] == y[round][1]) + (x[3] == y[round][2]); end else begin // !auto_generate_ab if (key_valid) begin if (right_number_pressed) begin if (cursor_posit == 2'd3) a[round] <= last_change_bcd; if (cursor_posit == 2'd1) b[round] <= last_change_bcd; end if (key_down[KEY_BACKSPACE]) begin if (cursor_posit == 2'd3) a[round] <= 4'hF; if (cursor_posit == 2'd1) b[round] <= 4'hF; end end end end else begin for (i = 0; i <= 15; i = i + 1) begin a[i] <= a[i]; b[i] <= b[i]; end end end // // reg: // // timer: // 0 ~ (2^12 - 1) = 4095 > 3600 = 60 * 60 seconds // count_100m: // 0 ~ 100m - 1 = 99_999_999 // reg [26:0] count_100m; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) count_100m <= 'b0; else count_100m <= (count_100m < 27'd99_999_999) ? (count_100m + 27'b1) : (27'b0); end reg [11:0] timer; always @(posedge count_100m[26] or negedge rst_n) begin if (~rst_n) begin timer <= 'b0; end else if (round == 16'h0 && state == STATE_Y) begin timer <= 12'd0; end else if (state == STATE_GG) begin timer <= timer; end else begin timer <= timer + 12'b1; end end // // // ssd_content_selector // // change log: // // 2020/05/28: // (Jing) rename extended_bcd_digit[0:3] to ssd_content_selector[0:3] // (Jing) rewrite always @ (it's combinational logic now) // (Jing) players can now press left-hand-side keyboard to query log. // reg [3:0] ssd_content_selector[0:3]; always @* begin // default (catch "E"rror) ssd_content_selector[0] = 4'hE; ssd_content_selector[1] = 4'hE; ssd_content_selector[2] = 4'hE; ssd_content_selector[3] = 4'hE; // show basic info based on current state if (state == STATE_GG) begin if (clk_freerun[27]) begin ssd_content_selector[0] = 4'hB; ssd_content_selector[1] = b[round]; ssd_content_selector[2] = 4'hA; ssd_content_selector[3] = a[round]; end else begin ssd_content_selector[0] = timer % 60 % 10; ssd_content_selector[1] = timer % 60 / 10; ssd_content_selector[2] = timer / 60 % 10; ssd_content_selector[3] = timer / 60 / 10; end end if (state == STATE_X) begin ssd_content_selector[0] = x[0]; ssd_content_selector[1] = x[1]; ssd_content_selector[2] = x[2]; ssd_content_selector[3] = x[3]; end if (state == STATE_Y) begin ssd_content_selector[0] = y[round][0]; ssd_content_selector[1] = y[round][1]; ssd_content_selector[2] = y[round][2]; ssd_content_selector[3] = y[round][3]; end if (state == STATE_AB) begin ssd_content_selector[0] = 4'hB; ssd_content_selector[1] = b[round]; ssd_content_selector[2] = 4'hA; ssd_content_selector[3] = a[round]; end // press left-hand-side keyboard to query log for (i = 0; i <= 15; i = i + 1) begin if (key_down[number_scancode[i]]) begin ssd_content_selector[0] = y[i][0]; ssd_content_selector[1] = y[i][1]; ssd_content_selector[2] = y[i][2]; ssd_content_selector[3] = y[i][3]; if (key_down[KEY_LSHIFT]) begin ssd_content_selector[0] = 4'hB; ssd_content_selector[1] = b[i]; ssd_content_selector[2] = 4'hA; ssd_content_selector[3] = a[i]; end end end // show timer when "T" is pressed if (key_down[KEY_T]) begin ssd_content_selector[0] = timer % 60 % 10; ssd_content_selector[1] = timer % 60 / 10; ssd_content_selector[2] = timer / 60 % 10; ssd_content_selector[3] = timer / 60 / 10; end // show more info for debugging purposes if (key_down[KEY_X]) begin ssd_content_selector[0] = x[0]; ssd_content_selector[1] = x[1]; ssd_content_selector[2] = x[2]; ssd_content_selector[3] = x[3]; end if (key_down[KEY_Y]) begin ssd_content_selector[0] = y[round][0]; ssd_content_selector[1] = y[round][1]; ssd_content_selector[2] = y[round][2]; ssd_content_selector[3] = y[round][3]; end if (key_down[KEY_S]) begin ssd_content_selector[0] = state; ssd_content_selector[1] = state; ssd_content_selector[2] = state; ssd_content_selector[3] = state; end if (key_down[KEY_V]) begin ssd_content_selector[0] = volume; ssd_content_selector[1] = volume; ssd_content_selector[2] = volume; ssd_content_selector[3] = volume; end end // // SSD // // output: // // ssd_cathode: // The cathodes of similar segments on all four displays are connected into // seven circuit nodes labeled CA through CG. // ssd_anode: // The common anode signals are available as four "digit enable" input // signals to the 4-digit display. // // reg: // // ssd: // decoded from extended BCD. // point // indicate the blinking cursor. // // change log: // // 2020/05/28: // (Jing) rename ssd_digit_? to extended_bcd_digit[0:3] // (Jing) separate extended_bcd_digit[0:3] out to their own sections // (Jing) [rewrite] anode 1-hot enable and cathode select. // (Jing) instantiate extended_bcd_to_ssd_decoder. // (Jing) ssd_cathode is now composed of {ssd, point} // reg [6:0] ssd; always @* begin case(ssd_content_selector[clk_freerun[19:18]]) // cathode select 4'h0: ssd = 7'b0000001; // display 0 4'h1: ssd = 7'b1001111; // display 1 4'h2: ssd = 7'b0010010; // display 2 4'h3: ssd = 7'b0000110; // display 3 4'h4: ssd = 7'b1001100; // display 4 4'h5: ssd = 7'b0100100; // display 5 4'h6: ssd = 7'b0100000; // display 6 4'h7: ssd = 7'b0001111; // display 7 4'h8: ssd = 7'b0000000; // display 8 4'h9: ssd = 7'b0000100; // display 9 4'hA: ssd = 7'b0001000; // display A 4'hB: ssd = 7'b1100000; // diaplay b 4'hF: ssd = 7'b1111111; // blank, the default value of x[] and y[][] default: ssd = 'b0; // catch error endcase end wire hide_cursor; assign hide_cursor = (key_down[KEY_T]) || (state == STATE_GG) || (state == STATE_X && auto_generate_x) || (state == STATE_Y && auto_generate_y) || (state == STATE_AB && auto_generate_ab); wire point; assign point = (clk_freerun[25]) // blinking cursor & (clk_freerun[19:18] == cursor_posit) & (~hide_cursor); assign ssd_cathode = {ssd, ~point}; // merge cathode assign ssd_anode = ~( 'b1 << clk_freerun[19:18] ); // anode 1-hot enable // // state transition // // declared in the "global" section above: // // reg [1:0] state; // localparam STATE_GG = 4'd0; // localparam STATE_X = 4'd1; // localparam STATE_Y = 4'd2; // localparam STATE_AB = 4'd3; // // // change log: // // 2020/05/26: // (Jing) [rewrite] reduce the number of states from 11 to 4 // (require further discussion) // // 2020/05/28: // (Jing) remove latch inferring // // 2020/06/18: // (Jing) rename GAMEOVER to STATE_GG, // WAIT_X to STATE_X, // WAIT_Y to STATE_Y, // SHOW_AB to STATE_AB. // (Jing) rewrite some condition. // always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin state <= 'b0; end else begin case (state) STATE_GG: begin if (key_valid && key_down[KEY_ENTER]) state <= STATE_X; end STATE_X: begin if (x_valid) begin if (auto_generate_x || key_valid && key_down[KEY_ENTER]) begin state <= STATE_Y; end end end STATE_Y: begin if (y_valid && key_valid && key_down[KEY_ENTER]) state <= STATE_AB; end STATE_AB: begin if (ab_valid) begin if (a[round] == 3'd4) begin if (auto_generate_ab || key_down[KEY_ENTER]) state <= STATE_GG; end else begin if (key_valid && key_down[KEY_ENTER]) state <= STATE_Y; end end end default: begin state <= state; end endcase end end // // led // // log: // // 2020/06/12: // (Jing) remove debugging switch // always @* begin led = ~(16'b1111_1111_1111_1111 << round); led[round] = clk_freerun[25]; // blinking end // // music section // // modified from music_player_tSoMI.v // // change: // // 2020/06/13: // Jing: // - fully debugged. the music sounds great. // // 2020/06/18: // Jing: // - rename some signals to improve the readibility. // // // music sheet: // // reg: // // duration_list // freq_list // // monkey island modified from: // // https://youtu.be/xo2_ksqxbiQ 00:00 ~ 01:30 // https://github.com/pdxiv/monkey-island-pc-speaker-theme-on-arduino // https://youtu.be/6ORsT4Gs9hA // // change: // // 2020/06/23: // localparam WIDTH_OF_FREQUENCY = 16; localparam NUMBER_OF_NOTE = 1440; localparam NON_TONE = 16'd1; reg [15:0] duration_list[0:NUMBER_OF_NOTE-1]; // ms reg [15:0] freq_list [0:NUMBER_OF_NOTE-1]; // Hz always @* begin for (i = 0; i < NUMBER_OF_NOTE; i = i + 1) begin duration_list[i] = { // duration start (all notes in one line) 16'd9, 16'd1, 16'd1, 16'd17, 16'd17, 16'd16, 16'd13, 16'd18, 16'd24, 16'd55, 16'd15, 16'd124, 16'd12, 16'd12, 16'd15, 16'd15, 16'd12, 16'd106, 16'd6, 16'd12, 16'd12, 16'd15, 16'd85, 16'd51, 16'd16, 16'd153, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd135, 16'd14, 16'd155, 16'd14, 16'd139, 16'd14, 16'd10, 16'd19, 16'd41, 16'd81, 16'd14, 16'd10, 16'd19, 16'd27, 16'd14, 16'd14, 16'd17, 16'd14, 16'd15, 16'd7, 16'd15, 16'd17, 16'd134, 16'd22, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd30, 16'd92, 16'd12, 16'd9, 16'd18, 16'd122, 16'd17, 16'd16, 16'd153, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd135, 16'd14, 16'd155, 16'd14, 16'd139, 16'd14, 16'd10, 16'd19, 16'd41, 16'd81, 16'd14, 16'd10, 16'd19, 16'd116, 16'd19, 16'd249, 16'd68, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd135, 16'd8, 16'd135, 16'd21, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd109, 16'd13, 16'd12, 16'd12, 16'd20, 16'd141, 16'd177, 16'd4, 16'd126, 16'd14, 16'd14, 16'd16, 16'd123, 16'd14, 16'd10, 16'd16, 16'd137, 16'd8, 16'd5, 16'd305, 16'd10, 16'd15, 16'd15, 16'd84, 16'd39, 16'd10, 16'd15, 16'd18, 16'd145, 16'd286, 16'd20, 16'd10, 16'd16, 16'd17, 16'd121, 16'd15, 16'd12, 16'd14, 16'd137, 16'd8, 16'd145, 16'd164, 16'd15, 16'd16, 16'd14, 16'd119, 16'd15, 16'd16, 16'd17, 16'd129, 16'd164, 16'd9, 16'd15, 16'd137, 16'd14, 16'd11, 16'd18, 16'd122, 16'd14, 16'd11, 16'd15, 16'd119, 16'd249, 16'd89, 16'd10, 16'd16, 16'd15, 16'd36, 16'd82, 16'd10, 16'd5, 16'd16, 16'd15, 16'd24, 16'd8, 16'd6, 16'd17, 16'd36, 16'd6, 16'd11, 16'd12, 16'd7, 16'd10, 16'd24, 16'd137, 16'd15, 16'd128, 16'd9, 16'd12, 16'd12, 16'd18, 16'd74, 16'd48, 16'd12, 16'd12, 16'd18, 16'd135, 16'd8, 16'd308, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd9, 16'd18, 16'd143, 16'd169, 16'd144, 16'd14, 16'd10, 16'd19, 16'd121, 16'd14, 16'd14, 16'd13, 16'd137, 16'd15, 16'd5, 16'd287, 16'd10, 16'd10, 16'd15, 16'd15, 16'd10, 16'd92, 16'd18, 16'd10, 16'd15, 16'd18, 16'd176, 16'd127, 16'd15, 16'd137, 16'd10, 16'd15, 16'd15, 16'd124, 16'd10, 16'd15, 16'd18, 16'd116, 16'd164, 16'd22, 16'd16, 16'd136, 16'd10, 16'd12, 16'd17, 16'd28, 16'd1, 16'd96, 16'd15, 16'd12, 16'd14, 16'd137, 16'd5, 16'd312, 16'd18, 16'd7, 16'd15, 16'd124, 16'd18, 16'd23, 16'd166, 16'd173, 16'd123, 16'd14, 16'd10, 16'd19, 16'd20, 16'd102, 16'd14, 16'd7, 16'd16, 16'd3, 16'd143, 16'd143, 16'd21, 16'd152, 16'd9, 16'd17, 16'd16, 16'd111, 16'd8, 16'd14, 16'd10, 16'd19, 16'd122, 16'd3, 16'd1, 16'd164, 16'd18, 16'd133, 16'd6, 16'd13, 16'd12, 16'd14, 16'd18, 16'd121, 16'd12, 16'd14, 16'd15, 16'd137, 16'd220, 16'd105, 16'd8, 16'd13, 16'd16, 16'd32, 16'd91, 16'd12, 16'd13, 16'd16, 16'd124, 16'd204, 16'd134, 16'd12, 16'd15, 16'd15, 16'd12, 16'd111, 16'd12, 16'd12, 16'd20, 16'd125, 16'd1, 16'd6, 16'd169, 16'd152, 16'd14, 16'd14, 16'd16, 16'd123, 16'd9, 16'd17, 16'd16, 16'd143, 16'd181, 16'd17, 16'd122, 16'd8, 16'd10, 16'd18, 16'd125, 16'd12, 16'd14, 16'd18, 16'd1, 16'd157, 16'd173, 16'd130, 16'd12, 16'd10, 16'd16, 16'd124, 16'd12, 16'd13, 16'd16, 16'd166, 16'd169, 16'd128, 16'd12, 16'd12, 16'd15, 16'd125, 16'd12, 16'd12, 16'd20, 16'd133, 16'd169, 16'd4, 16'd152, 16'd14, 16'd14, 16'd16, 16'd121, 16'd14, 16'd14, 16'd14, 16'd146, 16'd155, 16'd39, 16'd115, 16'd15, 16'd8, 16'd21, 16'd125, 16'd10, 16'd15, 16'd15, 16'd145, 16'd317, 16'd10, 16'd15, 16'd15, 16'd76, 16'd47, 16'd10, 16'd15, 16'd15, 16'd6, 16'd99, 16'd32, 16'd15, 16'd154, 16'd16, 16'd132, 16'd5, 16'd10, 16'd15, 16'd18, 16'd108, 16'd13, 16'd10, 16'd15, 16'd15, 16'd137, 16'd177, 16'd143, 16'd15, 16'd12, 16'd17, 16'd121, 16'd10, 16'd12, 16'd17, 16'd163, 16'd160, 16'd118, 16'd12, 16'd18, 16'd7, 16'd15, 16'd6, 16'd118, 16'd18, 16'd8, 16'd15, 16'd118, 16'd56, 16'd178, 16'd109, 16'd12, 16'd12, 16'd15, 16'd125, 16'd12, 16'd12, 16'd18, 16'd122, 16'd14, 16'd16, 16'd153, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd135, 16'd14, 16'd155, 16'd154, 16'd9, 16'd14, 16'd19, 16'd102, 16'd19, 16'd14, 16'd10, 16'd16, 16'd32, 16'd16, 16'd18, 16'd17, 16'd9, 16'd17, 16'd17, 16'd3, 16'd1, 16'd9, 16'd1, 16'd3, 16'd146, 16'd10, 16'd15, 16'd137, 16'd12, 16'd9, 16'd18, 16'd30, 16'd95, 16'd12, 16'd12, 16'd18, 16'd152, 16'd152, 16'd15, 16'd137, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd15, 16'd112, 16'd152, 16'd43, 16'd14, 16'd139, 16'd14, 16'd10, 16'd19, 16'd78, 16'd44, 16'd14, 16'd10, 16'd16, 16'd99, 16'd33, 16'd126, 16'd47, 16'd18, 16'd138, 16'd12, 16'd13, 16'd17, 16'd42, 16'd1, 16'd33, 16'd47, 16'd12, 16'd13, 16'd17, 16'd97, 16'd38, 16'd139, 16'd13, 16'd158, 16'd7, 16'd12, 16'd13, 16'd15, 16'd124, 16'd12, 16'd13, 16'd17, 16'd127, 16'd118, 16'd51, 16'd23, 16'd1, 16'd59, 16'd1, 16'd9, 16'd1, 16'd40, 16'd13, 16'd12, 16'd12, 16'd13, 16'd17, 16'd89, 16'd34, 16'd12, 16'd13, 16'd19, 16'd65, 16'd68, 16'd1, 16'd9, 16'd1, 16'd59, 16'd1, 16'd9, 16'd1, 16'd58, 16'd22, 16'd153, 16'd4, 16'd14, 16'd10, 16'd18, 16'd117, 16'd5, 16'd14, 16'd8, 16'd16, 16'd121, 16'd18, 16'd15, 16'd6, 16'd139, 16'd163, 16'd7, 16'd13, 16'd14, 16'd124, 16'd14, 16'd13, 16'd14, 16'd137, 16'd15, 16'd154, 16'd16, 16'd136, 16'd14, 16'd13, 16'd14, 16'd124, 16'd14, 16'd8, 16'd16, 16'd48, 16'd1, 16'd69, 16'd21, 16'd9, 16'd117, 16'd43, 16'd136, 16'd5, 16'd10, 16'd14, 16'd11, 16'd17, 16'd109, 16'd14, 16'd14, 16'd11, 16'd17, 16'd135, 16'd3, 16'd148, 16'd9, 16'd159, 16'd14, 16'd14, 16'd15, 16'd124, 16'd14, 16'd11, 16'd17, 16'd118, 16'd70, 16'd1, 16'd9, 16'd1, 16'd59, 16'd1, 16'd23, 16'd9, 16'd160, 16'd17, 16'd14, 16'd15, 16'd101, 16'd1, 16'd22, 16'd14, 16'd11, 16'd17, 16'd109, 16'd26, 16'd39, 16'd1, 16'd60, 16'd1, 16'd25, 16'd43, 16'd8, 16'd122, 16'd22, 16'd12, 16'd13, 16'd18, 16'd25, 16'd1, 16'd69, 16'd26, 16'd12, 16'd13, 16'd18, 16'd113, 16'd5, 16'd52, 16'd1, 16'd88, 16'd39, 16'd12, 16'd122, 16'd17, 16'd12, 16'd13, 16'd18, 16'd117, 16'd5, 16'd12, 16'd13, 16'd18, 16'd122, 16'd13, 16'd9, 16'd172, 16'd136, 16'd12, 16'd13, 16'd16, 16'd124, 16'd12, 16'd13, 16'd16, 16'd128, 16'd151, 16'd26, 16'd16, 16'd136, 16'd12, 16'd13, 16'd18, 16'd87, 16'd35, 16'd12, 16'd13, 16'd16, 16'd120, 16'd130, 16'd56, 16'd126, 16'd26, 16'd11, 16'd14, 16'd16, 16'd123, 16'd11, 16'd14, 16'd16, 16'd73, 16'd63, 16'd16, 16'd136, 16'd122, 16'd47, 16'd14, 16'd11, 16'd14, 16'd125, 16'd14, 16'd11, 16'd17, 16'd109, 16'd26, 16'd14, 16'd155, 16'd15, 16'd137, 16'd11, 16'd14, 16'd16, 16'd123, 16'd11, 16'd14, 16'd16, 16'd136, 16'd16, 16'd153, 16'd15, 16'd137, 16'd14, 16'd11, 16'd14, 16'd125, 16'd14, 16'd11, 16'd17, 16'd114, 16'd17, 16'd17, 16'd10, 16'd15, 16'd13, 16'd17, 16'd13, 16'd16, 16'd17, 16'd15, 16'd19, 16'd18, 16'd140, 16'd11, 16'd13, 16'd12, 16'd17, 16'd123, 16'd13, 16'd12, 16'd17, 16'd89, 16'd47, 16'd17, 16'd152, 16'd92, 16'd60, 16'd13, 16'd12, 16'd17, 16'd123, 16'd13, 16'd12, 16'd17, 16'd85, 16'd51, 16'd16, 16'd309, 16'd13, 16'd12, 16'd17, 16'd123, 16'd13, 16'd12, 16'd17, 16'd136, 16'd16, 16'd153, 16'd17, 16'd136, 16'd13, 16'd12, 16'd17, 16'd54, 16'd69, 16'd13, 16'd12, 16'd17, 16'd140, 16'd110, 16'd55, 16'd15, 16'd44, 16'd92, 16'd6, 16'd6, 16'd13, 16'd17, 16'd8, 16'd116, 16'd13, 16'd8, 16'd17, 16'd135, 16'd5, 16'd17, 16'd152, 16'd117, 16'd35, 16'd11, 16'd13, 16'd18, 16'd123, 16'd11, 16'd13, 16'd18, 16'd118, 16'd117, 16'd69, 16'd15, 16'd137, 16'd13, 16'd13, 16'd15, 16'd124, 16'd13, 16'd13, 16'd15, 16'd137, 16'd17, 16'd152, 16'd15, 16'd137, 16'd11, 16'd13, 16'd18, 16'd135, 16'd13, 16'd15, 16'd103, 16'd17, 16'd9, 16'd17, 16'd3, 16'd18, 16'd43, 16'd16, 16'd8, 16'd16, 16'd86, 16'd116, 16'd11, 16'd14, 16'd15, 16'd123, 16'd14, 16'd11, 16'd17, 16'd150, 16'd1, 16'd145, 16'd162, 16'd11, 16'd14, 16'd15, 16'd123, 16'd8, 16'd18, 16'd15, 16'd143, 16'd5, 16'd5, 16'd309, 16'd14, 16'd11, 16'd17, 16'd123, 16'd14, 16'd11, 16'd17, 16'd136, 16'd17, 16'd152, 16'd16, 16'd136, 16'd14, 16'd11, 16'd17, 16'd123, 16'd5, 16'd8, 16'd11, 16'd17, 16'd12, 16'd13, 16'd12, 16'd14, 16'd12, 16'd5, 16'd14, 16'd12, 16'd1, 16'd1, 16'd10, 16'd6, 16'd3, 16'd1, 16'd2, 16'd36, 16'd106, 16'd191, 16'd12, 16'd12, 16'd18, 16'd109, 16'd13, 16'd12, 16'd12, 16'd20, 16'd141, 16'd7, 16'd3, 16'd134, 16'd17, 16'd14, 16'd20, 16'd118, 16'd14, 16'd10, 16'd19, 16'd123, 16'd14, 16'd10, 16'd16, 16'd137, 16'd15, 16'd27, 16'd223, 16'd56, 16'd10, 16'd15, 16'd15, 16'd53, 16'd70, 16'd10, 16'd15, 16'd18, 16'd107, 16'd27, 16'd173, 16'd7, 16'd3, 16'd137, 16'd16, 16'd3, 16'd5, 16'd18, 16'd104, 16'd18, 16'd16, 16'd10, 16'd15, 16'd136, 16'd8, 16'd143, 16'd14, 16'd17, 16'd117, 16'd19, 16'd20, 16'd6, 16'd15, 16'd123, 16'd16, 16'd3, 16'd5, 16'd18, 16'd134, 16'd164, 16'd5, 16'd15, 16'd137, 16'd15, 16'd27, 16'd122, 16'd19, 16'd6, 16'd16, 16'd137, 16'd15, 16'd19, 16'd281, 16'd6, 16'd16, 16'd12, 16'd13, 16'd85, 16'd39, 16'd24, 16'd18, 16'd24, 16'd14, 16'd12, 16'd8, 16'd14, 16'd12, 16'd13, 16'd24, 16'd14, 16'd36, 16'd280, 16'd12, 16'd12, 16'd18, 16'd109, 16'd13, 16'd12, 16'd12, 16'd18, 16'd135, 16'd15, 16'd6, 16'd244, 16'd51, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd9, 16'd94, 16'd1, 16'd48, 16'd142, 16'd6, 16'd16, 16'd131, 16'd6, 16'd14, 16'd10, 16'd19, 16'd123, 16'd14, 16'd10, 16'd16, 16'd137, 16'd15, 16'd23, 16'd257, 16'd22, 16'd10, 16'd15, 16'd18, 16'd46, 16'd75, 16'd10, 16'd15, 16'd18, 16'd161, 16'd142, 16'd15, 16'd137, 16'd19, 16'd6, 16'd15, 16'd125, 16'd15, 16'd3, 16'd2, 16'd18, 16'd147, 16'd8, 16'd170, 16'd135, 16'd20, 16'd6, 16'd18, 16'd121, 16'd16, 16'd23, 16'd138, 16'd316, 16'd5, 16'd19, 16'd6, 16'd16, 16'd124, 16'd15, 16'd25, 16'd120, 16'd173, 16'd17, 16'd143, 16'd9, 16'd14, 16'd10, 16'd16, 16'd120, 16'd4, 16'd14, 16'd14, 16'd16, 16'd47, 16'd1, 16'd89, 16'd9, 16'd139, 16'd13, 16'd134, 16'd27, 16'd14, 16'd10, 16'd19, 16'd123, 16'd9, 16'd17, 16'd16, 16'd100, 16'd64, 16'd122, 16'd153, 16'd20, 16'd12, 16'd14, 16'd18, 16'd117, 16'd12, 16'd14, 16'd15, 16'd166, 16'd143, 16'd146, 16'd7, 16'd12, 16'd13, 16'd16, 16'd124, 16'd12, 16'd13, 16'd16, 16'd132, 16'd152, 16'd109, 16'd68, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd20, 16'd133, 16'd135, 16'd38, 16'd117, 16'd31, 16'd14, 16'd11, 16'd18, 16'd123, 16'd14, 16'd11, 16'd18, 16'd104, 16'd52, 16'd124, 16'd1, 16'd34, 16'd14, 16'd112, 16'd19, 16'd14, 16'd13, 16'd16, 16'd122, 16'd14, 16'd13, 16'd14, 16'd154, 16'd147, 16'd121, 16'd40, 16'd13, 16'd14, 16'd14, 16'd124, 16'd13, 16'd13, 16'd14, 16'd137, 16'd161, 16'd115, 16'd49, 16'd12, 16'd13, 16'd16, 16'd124, 16'd12, 16'd13, 16'd18, 16'd134, 16'd165, 16'd143, 16'd14, 16'd14, 16'd11, 16'd140, 16'd13, 16'd11, 16'd17, 16'd157, 16'd134, 16'd14, 16'd107, 16'd49, 16'd12, 16'd13, 16'd17, 16'd118, 16'd12, 16'd13, 16'd17, 16'd165, 16'd155, 16'd35, 16'd99, 16'd6, 16'd12, 16'd13, 16'd17, 16'd123, 16'd12, 16'd13, 16'd17, 16'd107, 16'd16, 16'd143, 16'd39, 16'd14, 16'd138, 16'd16, 16'd26, 16'd5, 16'd117, 16'd16, 16'd3, 16'd7, 16'd15, 16'd137, 16'd5, 16'd151, 16'd9, 16'd18, 16'd134, 16'd15, 16'd27, 16'd109, 16'd14, 16'd15, 16'd10, 16'd16, 16'd157, 16'd148, 16'd12, 16'd18, 16'd73, 16'd50, 16'd12, 16'd12, 16'd18, 16'd123, 16'd12, 16'd12, 16'd18, 16'd17, 16'd85, 16'd33, 16'd16, 16'd153, 16'd12, 16'd22, 16'd109, 16'd9, 16'd16, 16'd12, 16'd18, 16'd100, 16'd23, 16'd12, 16'd12, 16'd18, 16'd144, 16'd152, 16'd165, 16'd12, 16'd12, 16'd15, 16'd125, 16'd12, 16'd12, 16'd20, 16'd158, 16'd143, 16'd9, 16'd144, 16'd14, 16'd10, 16'd19, 16'd121, 16'd14, 16'd14, 16'd14, 16'd154, 16'd138, 16'd10, 16'd122, 16'd38, 16'd11, 16'd15, 16'd15, 16'd123, 16'd11, 16'd15, 16'd15, 16'd107, 16'd218, 16'd107, 16'd28, 16'd11, 16'd15, 16'd15, 16'd123, 16'd11, 16'd15, 16'd15, 16'd135, 16'd126, 16'd43, 16'd5, 16'd68, 16'd1, 16'd40, 16'd35, 16'd4, 16'd14, 16'd10, 16'd19, 16'd104, 16'd14, 16'd18, 16'd10, 16'd19, 16'd126, 16'd159, 16'd9, 16'd156, 16'd11, 16'd14, 16'd17, 16'd3, 16'd120, 16'd11, 16'd14, 16'd17, 16'd6, 16'd66, 16'd8, 16'd51, 16'd6, 16'd71, 16'd249, 16'd71 // end of duration list // duration end } >> (NUMBER_OF_NOTE - i - 1) * WIDTH_OF_FREQUENCY; end end always @* begin for (i = 0; i < NUMBER_OF_NOTE; i = i + 1) begin freq_list[i] = { // freq start (1440 notes in one line) 16'd988, NON_TONE, NON_TONE, 16'd784, 16'd659, 16'd494, 16'd392, 16'd330, 16'd165, NON_TONE, 16'd330, NON_TONE, 16'd165, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd494, NON_TONE, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd147, NON_TONE, 16'd294, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd147, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd147, 16'd494, 16'd147, 16'd659, 16'd147, 16'd784, NON_TONE, NON_TONE, 16'd988, 16'd165, NON_TONE, 16'd330, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd494, NON_TONE, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd147, NON_TONE, 16'd294, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd147, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd147, NON_TONE, 16'd165, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd494, 16'd659, NON_TONE, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd740, NON_TONE, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, NON_TONE, NON_TONE, 16'd659, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, 16'd98, NON_TONE, 16'd196, 16'd247, 16'd294, 16'd587, 16'd196, 16'd247, 16'd294, NON_TONE, 16'd392, 16'd587, 16'd523, 16'd196, 16'd247, 16'd294, 16'd494, 16'd196, 16'd247, 16'd294, 16'd587, 16'd523, NON_TONE, 16'd262, NON_TONE, 16'd220, 16'd262, 16'd330, 16'd523, 16'd220, 16'd262, 16'd330, NON_TONE, 16'd494, NON_TONE, 16'd196, 16'd247, 16'd330, 16'd82, NON_TONE, NON_TONE, NON_TONE, 16'd247, 16'd330, 16'd82, NON_TONE, 16'd494, 16'd659, 16'd82, NON_TONE, 16'd784, NON_TONE, NON_TONE, 16'd988, 16'd82, NON_TONE, 16'd330, NON_TONE, 16'd659, 16'd247, 16'd330, 16'd392, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd494, 16'd659, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd740, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd131, NON_TONE, 16'd659, NON_TONE, 16'd196, 16'd262, 16'd330, NON_TONE, 16'd131, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd330, NON_TONE, 16'd196, 16'd262, 16'd330, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd740, 16'd784, NON_TONE, 16'd247, NON_TONE, 16'd196, 16'd247, 16'd294, 16'd784, NON_TONE, 16'd784, 16'd196, 16'd247, 16'd294, NON_TONE, 16'd440, 16'd880, 16'd220, 16'd880, 16'd262, NON_TONE, 16'd220, 16'd262, NON_TONE, 16'd740, 16'd147, 16'd220, 16'd294, 16'd370, 16'd147, NON_TONE, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd784, 16'd740, NON_TONE, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd740, 16'd220, 16'd294, 16'd370, 16'd740, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd98, NON_TONE, 16'd784, 16'd247, 16'd294, 16'd392, 16'd784, 16'd247, 16'd294, 16'd392, NON_TONE, 16'd740, 16'd123, 16'd247, 16'd311, 16'd370, 16'd123, NON_TONE, 16'd247, 16'd311, 16'd370, NON_TONE, 16'd659, 16'd165, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, NON_TONE, 16'd784, 16'd740, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, 16'd740, 16'd784, NON_TONE, 16'd98, 16'd247, 16'd294, 16'd392, 16'd784, 16'd247, 16'd294, 16'd392, NON_TONE, NON_TONE, 16'd740, 16'd123, 16'd247, 16'd311, 16'd370, NON_TONE, 16'd247, 16'd311, 16'd370, NON_TONE, 16'd659, 16'd165, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd740, NON_TONE, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd659, NON_TONE, 16'd131, 16'd196, 16'd262, 16'd330, 16'd659, 16'd196, 16'd262, 16'd330, NON_TONE, 16'd659, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd196, 16'd262, 16'd330, NON_TONE, 16'd131, NON_TONE, 16'd392, NON_TONE, 16'd247, NON_TONE, 16'd659, 16'd196, 16'd262, 16'd330, 16'd659, NON_TONE, 16'd196, 16'd262, 16'd330, NON_TONE, 16'd587, 16'd523, 16'd196, 16'd247, 16'd294, 16'd494, 16'd196, 16'd247, 16'd294, 16'd587, 16'd523, 16'd110, NON_TONE, 16'd220, 16'd440, 16'd262, NON_TONE, 16'd523, 16'd220, 16'd523, 16'd262, 16'd110, NON_TONE, 16'd494, 16'd82, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd82, NON_TONE, 16'd494, NON_TONE, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd147, NON_TONE, 16'd123, 16'd220, 16'd294, 16'd370, 16'd147, NON_TONE, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd494, NON_TONE, 16'd659, NON_TONE, 16'd784, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, 16'd165, NON_TONE, 16'd330, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd165, NON_TONE, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd494, NON_TONE, 16'd294, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd587, NON_TONE, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd659, 16'd1047, NON_TONE, 16'd330, 16'd131, 16'd330, 16'd392, 16'd523, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd330, 16'd392, 16'd523, 16'd165, NON_TONE, 16'd784, NON_TONE, 16'd196, NON_TONE, 16'd330, 16'd392, 16'd523, NON_TONE, 16'd330, 16'd392, 16'd523, NON_TONE, 16'd1047, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd880, 16'd330, 16'd392, 16'd523, 16'd880, NON_TONE, 16'd330, 16'd392, 16'd523, 16'd1047, NON_TONE, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd98, 16'd784, 16'd294, 16'd392, 16'd494, 16'd784, NON_TONE, 16'd294, 16'd392, 16'd494, 16'd123, NON_TONE, 16'd392, NON_TONE, 16'd784, 16'd147, 16'd294, 16'd392, 16'd494, NON_TONE, 16'd294, 16'd392, 16'd494, NON_TONE, 16'd392, NON_TONE, 16'd247, NON_TONE, 16'd294, 16'd392, 16'd494, NON_TONE, 16'd294, 16'd392, 16'd494, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd440, 16'd880, NON_TONE, 16'd147, NON_TONE, 16'd587, 16'd294, 16'd440, 16'd523, 16'd587, NON_TONE, 16'd294, 16'd440, 16'd523, 16'd185, NON_TONE, 16'd587, NON_TONE, 16'd220, 16'd294, 16'd440, 16'd523, NON_TONE, 16'd294, 16'd440, 16'd523, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd880, 16'd294, 16'd440, 16'd523, 16'd784, NON_TONE, 16'd784, 16'd294, 16'd440, 16'd523, 16'd880, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd988, NON_TONE, 16'd247, 16'd165, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd123, NON_TONE, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd247, 16'd98, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd82, NON_TONE, 16'd330, 16'd659, NON_TONE, 16'd330, 16'd392, 16'd494, NON_TONE, 16'd330, 16'd392, 16'd494, NON_TONE, 16'd370, NON_TONE, 16'd247, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd392, NON_TONE, 16'd330, 16'd392, 16'd494, NON_TONE, 16'd440, NON_TONE, 16'd87, NON_TONE, 16'd262, 16'd349, 16'd440, NON_TONE, 16'd262, 16'd349, 16'd440, 16'd110, NON_TONE, 16'd1047, NON_TONE, 16'd131, NON_TONE, 16'd220, 16'd262, 16'd349, NON_TONE, 16'd220, 16'd262, 16'd349, 16'd175, NON_TONE, 16'd349, NON_TONE, 16'd523, NON_TONE, 16'd262, 16'd349, 16'd440, NON_TONE, 16'd262, 16'd349, 16'd440, NON_TONE, 16'd1047, NON_TONE, 16'd523, NON_TONE, 16'd220, 16'd262, 16'd349, NON_TONE, 16'd220, 16'd262, 16'd349, NON_TONE, 16'd1319, 16'd988, 16'd392, 16'd784, 16'd392, 16'd659, 16'd392, 16'd494, NON_TONE, 16'd392, NON_TONE, 16'd330, 16'd165, NON_TONE, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd392, 16'd494, 16'd659, 16'd123, NON_TONE, 16'd784, NON_TONE, 16'd98, NON_TONE, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd392, 16'd494, 16'd659, 16'd82, NON_TONE, 16'd740, NON_TONE, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd740, NON_TONE, 16'd784, NON_TONE, 16'd392, 16'd494, 16'd659, 16'd370, NON_TONE, 16'd392, 16'd494, 16'd659, NON_TONE, 16'd392, NON_TONE, 16'd262, NON_TONE, 16'd131, NON_TONE, 16'd311, 16'd392, 16'd523, NON_TONE, NON_TONE, 16'd311, 16'd392, 16'd523, 16'd156, NON_TONE, 16'd784, NON_TONE, 16'd196, NON_TONE, 16'd262, 16'd311, 16'd392, NON_TONE, 16'd262, 16'd311, 16'd392, 16'd262, 16'd523, NON_TONE, 16'd392, NON_TONE, 16'd311, 16'd392, 16'd523, NON_TONE, 16'd311, 16'd392, 16'd523, NON_TONE, 16'd784, NON_TONE, 16'd392, NON_TONE, 16'd262, 16'd311, 16'd392, NON_TONE, 16'd311, 16'd392, NON_TONE, 16'd1175, 16'd587, 16'd880, 16'd587, 16'd740, 16'd587, 16'd440, 16'd587, 16'd370, NON_TONE, 16'd294, 16'd370, 16'd440, 16'd587, NON_TONE, 16'd370, 16'd440, 16'd587, 16'd220, NON_TONE, NON_TONE, 16'd185, 16'd370, 16'd440, 16'd587, NON_TONE, 16'd370, 16'd440, 16'd587, 16'd147, NON_TONE, 16'd659, NON_TONE, 16'd370, 16'd440, 16'd587, NON_TONE, 16'd370, 16'd440, 16'd587, NON_TONE, 16'd659, NON_TONE, 16'd740, NON_TONE, 16'd370, 16'd440, 16'd587, 16'd147, NON_TONE, 16'd370, 16'd440, 16'd587, 16'd165, 16'd392, 16'd165, 16'd494, 16'd165, NON_TONE, 16'd659, 16'd165, NON_TONE, NON_TONE, 16'd784, NON_TONE, 16'd988, NON_TONE, 16'd988, 16'd165, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd294, NON_TONE, 16'd740, NON_TONE, 16'd220, NON_TONE, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd330, NON_TONE, 16'd659, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd98, NON_TONE, NON_TONE, NON_TONE, 16'd247, NON_TONE, 16'd587, 16'd392, 16'd587, NON_TONE, 16'd247, 16'd294, 16'd392, NON_TONE, 16'd392, 16'd587, NON_TONE, 16'd294, 16'd523, NON_TONE, 16'd247, 16'd494, 16'd392, 16'd494, 16'd247, NON_TONE, 16'd587, 16'd392, 16'd587, 16'd523, NON_TONE, 16'd262, NON_TONE, 16'd262, 16'd440, 16'd523, 16'd262, 16'd523, 16'd440, NON_TONE, 16'd392, NON_TONE, 16'd494, NON_TONE, 16'd247, NON_TONE, 16'd392, 16'd82, NON_TONE, 16'd247, 16'd392, 16'd82, 16'd494, NON_TONE, NON_TONE, 16'd659, NON_TONE, 16'd784, 16'd82, 16'd988, 16'd82, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd330, NON_TONE, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd784, NON_TONE, 16'd784, 16'd740, NON_TONE, 16'd440, 16'd659, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd523, NON_TONE, 16'd659, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd196, 16'd262, 16'd330, 16'd131, NON_TONE, 16'd392, NON_TONE, 16'd262, 16'd523, 16'd392, NON_TONE, 16'd262, NON_TONE, NON_TONE, 16'd392, 16'd740, 16'd494, 16'd784, NON_TONE, 16'd247, 16'd494, 16'd392, 16'd784, 16'd247, 16'd392, NON_TONE, 16'd880, NON_TONE, 16'd262, 16'd523, 16'd440, NON_TONE, 16'd262, 16'd440, NON_TONE, 16'd740, NON_TONE, 16'd147, NON_TONE, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd784, 16'd220, 16'd294, 16'd370, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd740, NON_TONE, 16'd659, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, 16'd740, NON_TONE, 16'd784, 16'd98, NON_TONE, 16'd247, 16'd294, 16'd392, 16'd784, 16'd247, 16'd294, 16'd392, NON_TONE, 16'd740, 16'd123, NON_TONE, 16'd247, 16'd311, 16'd370, NON_TONE, 16'd247, 16'd311, 16'd370, NON_TONE, 16'd659, 16'd165, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd740, NON_TONE, 16'd659, NON_TONE, 16'd294, 16'd370, 16'd440, 16'd587, 16'd294, 16'd370, 16'd440, 16'd740, NON_TONE, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd98, NON_TONE, 16'd294, 16'd392, 16'd494, 16'd784, 16'd294, 16'd392, 16'd494, NON_TONE, 16'd740, 16'd123, NON_TONE, 16'd311, 16'd370, 16'd494, NON_TONE, 16'd311, 16'd370, 16'd494, NON_TONE, 16'd659, 16'd165, NON_TONE, 16'd330, 16'd392, 16'd494, NON_TONE, 16'd330, 16'd392, 16'd494, 16'd784, 16'd740, 16'd659, NON_TONE, 16'd370, 16'd440, 16'd587, 16'd370, 16'd440, 16'd587, NON_TONE, 16'd659, NON_TONE, 16'd131, NON_TONE, 16'd330, 16'd392, 16'd523, 16'd659, 16'd330, 16'd392, 16'd523, NON_TONE, 16'd659, NON_TONE, 16'd131, NON_TONE, 16'd330, 16'd392, 16'd523, NON_TONE, 16'd330, 16'd392, 16'd523, 16'd131, NON_TONE, 16'd98, NON_TONE, 16'd294, NON_TONE, 16'd247, 16'd392, NON_TONE, 16'd587, 16'd247, NON_TONE, 16'd587, 16'd392, NON_TONE, 16'd440, 16'd523, NON_TONE, 16'd330, 16'd494, 16'd262, 16'd440, 16'd523, NON_TONE, 16'd262, NON_TONE, 16'd440, NON_TONE, 16'd494, 16'd165, NON_TONE, 16'd82, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd82, NON_TONE, 16'd370, NON_TONE, 16'd165, NON_TONE, 16'd82, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd659, NON_TONE, 16'd247, 16'd330, 16'd392, NON_TONE, 16'd247, 16'd330, 16'd392, 16'd784, 16'd740, NON_TONE, 16'd659, 16'd220, 16'd294, 16'd370, 16'd587, 16'd220, 16'd294, 16'd370, NON_TONE, 16'd659, NON_TONE, 16'd131, NON_TONE, 16'd262, 16'd330, 16'd392, 16'd659, 16'd262, 16'd330, 16'd392, 16'd131, NON_TONE, 16'd131, NON_TONE, 16'd262, 16'd330, 16'd392, NON_TONE, 16'd262, 16'd330, 16'd392, NON_TONE, 16'd880, NON_TONE, 16'd440, 16'd784, NON_TONE, 16'd784, NON_TONE, 16'd740, 16'd220, 16'd294, 16'd370, 16'd740, NON_TONE, 16'd220, 16'd294, 16'd370, 16'd880, 16'd784, NON_TONE, 16'd659, 16'd185, 16'd220, 16'd294, NON_TONE, 16'd740, 16'd185, 16'd220, 16'd294, NON_TONE, 16'd196, 16'd247, 16'd392, 16'd330, 16'd494, 16'd659, NON_TONE // end of freq list // freq end } >> (NUMBER_OF_NOTE - i - 1) * WIDTH_OF_FREQUENCY; end end // // sheet timing interpretation: (note duration) // // reg: // duration_count // note_index // reg [31:0] duration_count; reg [15:0] note_index; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin duration_count <= 'b0; end else if (state == STATE_AB) begin duration_count <= 32'b0; end else if (duration_count < duration_list[note_index] * 100_000) begin duration_count <= duration_count + 32'b1; end else begin duration_count <= 32'b0; end end always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin note_index <= 'b0; end else if (state == STATE_AB) begin note_index <= 16'b0; end else if (duration_count == duration_list[note_index] * 100_000) begin if (note_index < NUMBER_OF_NOTE) note_index <= note_index + 16'b1; else note_index <= 16'b0; end else begin note_index <= note_index; end end // // touhou pause sound effect modified from: // // https://twitter.com/Romantique_Tp/status/911623655083380737 // localparam FREQ_C5 = 16'd523; localparam FREQ_F5 = 16'd698; localparam FREQ_G5 = 16'd784; localparam FREQ_A5S = 16'd932; localparam FREQ_C6 = 16'd1046; wire [15:0] th_left_freq_list[0:11]; wire [15:0] th_right_freq_list[0:11]; assign th_left_freq_list[0] = NON_TONE; assign th_left_freq_list[1] = FREQ_C5; assign th_left_freq_list[2] = FREQ_F5; assign th_left_freq_list[3] = FREQ_G5; assign th_left_freq_list[4] = FREQ_A5S; assign th_left_freq_list[5] = FREQ_G5; assign th_left_freq_list[6] = FREQ_F5; assign th_left_freq_list[7] = FREQ_C5; assign th_left_freq_list[8] = FREQ_F5; assign th_left_freq_list[9] = FREQ_G5; assign th_left_freq_list[10] = FREQ_A5S; assign th_left_freq_list[11] = FREQ_C6; assign th_right_freq_list[0] = NON_TONE; assign th_right_freq_list[1] = FREQ_C5; assign th_right_freq_list[2] = FREQ_C5; assign th_right_freq_list[3] = FREQ_F5; assign th_right_freq_list[4] = FREQ_F5; assign th_right_freq_list[5] = FREQ_G5; assign th_right_freq_list[6] = FREQ_G5; assign th_right_freq_list[7] = FREQ_A5S; assign th_right_freq_list[8] = FREQ_A5S; assign th_right_freq_list[9] = FREQ_C6; assign th_right_freq_list[10] = FREQ_C6; assign th_right_freq_list[11] = FREQ_C6; // // touhou notes rolling // // reg: // th_duration_count // th_note_index // reg [31:0] th_duration_count; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin th_duration_count <= 'b0; end else if (state == STATE_GG) begin th_duration_count <= 32'b0; end else if (th_duration_count < 10_000_000) begin th_duration_count <= th_duration_count + 32'b1; end else begin th_duration_count <= 32'b0; end end reg [3:0] th_note_index; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin th_note_index <= 'b0; end else if (state == STATE_GG && key_valid) begin if (key_down[KEY_ENTER] || right_number_pressed) th_note_index <= 16'b0; end else if (th_duration_count == 10_000_000 && th_note_index <= 16'd11) begin th_note_index <= th_note_index + 16'b1; end else begin th_note_index <= th_note_index; end end // // Dual-Tone Multi-Frequency (DTMF) // // usage: // " dtmf_low_freq[last_change_bcd] " // // wire: // dtmf_low_freq // dtmf_high_freq // // change: // 2020/06/23: // (Jing) initial commit. // localparam dtmf_low_freq_0 = 16'd697; localparam dtmf_low_freq_1 = 16'd770; localparam dtmf_low_freq_2 = 16'd852; localparam dtmf_low_freq_3 = 16'd941; localparam dtmf_high_freq_0 = 16'd1209; localparam dtmf_high_freq_1 = 16'd1336; localparam dtmf_high_freq_2 = 16'd1477; localparam dtmf_high_freq_3 = 16'd1633; wire [15:0] dtmf_low_freq[0:9]; assign dtmf_low_freq[0] = dtmf_low_freq_3; assign dtmf_low_freq[1] = dtmf_low_freq_0; assign dtmf_low_freq[2] = dtmf_low_freq_0; assign dtmf_low_freq[3] = dtmf_low_freq_0; assign dtmf_low_freq[4] = dtmf_low_freq_1; assign dtmf_low_freq[5] = dtmf_low_freq_1; assign dtmf_low_freq[6] = dtmf_low_freq_1; assign dtmf_low_freq[7] = dtmf_low_freq_2; assign dtmf_low_freq[8] = dtmf_low_freq_2; assign dtmf_low_freq[9] = dtmf_low_freq_2; wire [15:0] dtmf_high_freq[0:9]; assign dtmf_high_freq[0] = dtmf_high_freq_1; assign dtmf_high_freq[1] = dtmf_high_freq_0; assign dtmf_high_freq[2] = dtmf_high_freq_1; assign dtmf_high_freq[3] = dtmf_high_freq_2; assign dtmf_high_freq[4] = dtmf_high_freq_0; assign dtmf_high_freq[5] = dtmf_high_freq_1; assign dtmf_high_freq[6] = dtmf_high_freq_2; assign dtmf_high_freq[7] = dtmf_high_freq_0; assign dtmf_high_freq[8] = dtmf_high_freq_1; assign dtmf_high_freq[9] = dtmf_high_freq_2; // // determine freq counter limit: // // reg: // freq_count_left_lim // freq_count_right_lim // // change: // 2020/06/23: // (Jing) add Dual-Tone Multi-Frequency (DTMF) // reg [31:0] freq_count_left_lim; always @* begin freq_count_left_lim = 32'hFFFF_FFFF; // default if (16'b0 < th_note_index && th_note_index <= 16'd11) freq_count_left_lim = 50_000_000 / th_left_freq_list[th_note_index]; if (state == STATE_GG) freq_count_left_lim = 50_000_000 / freq_list[note_index]; if (right_number_pressed) freq_count_left_lim = 50_000_000 / dtmf_low_freq[last_change_bcd]; end reg [31:0] freq_count_right_lim; always @* begin freq_count_right_lim = 32'hFFFF_FFFF; // default if (16'b0 < th_note_index && th_note_index <= 16'd11) freq_count_right_lim = 50_000_000 / th_right_freq_list[th_note_index]; if (right_number_pressed) freq_count_right_lim = 50_000_000 / dtmf_high_freq[last_change_bcd]; end // // freq counter for wave: // // reg: // freq_count_left // freq_count_right // reg [31:0] freq_count_left; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin freq_count_left <= 'b0; end else if (freq_count_left < freq_count_left_lim) begin freq_count_left <= freq_count_left + 32'b1; end else begin freq_count_left <= 32'b0; end end reg [31:0] freq_count_right; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin freq_count_right <= 'b0; end else if (freq_count_right < freq_count_right_lim) begin freq_count_right <= freq_count_right + 32'b1; end else begin freq_count_right <= 32'b0; end end // // determine the phase: // // reg: // phase_left // phase_right // reg phase_left; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin phase_left <= 'b0; end else if (freq_count_left == freq_count_left_lim) begin phase_left <= ~phase_left; end else begin phase_left <= phase_left; end end reg phase_right; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin phase_right <= 'b0; end else if (freq_count_right == freq_count_right_lim) begin phase_right <= ~phase_right; end else begin phase_right <= phase_right; end end // // determine 2's complement of audio_left/audio_right: // // reg: // volume // // wire: // audio_left // audio_right // // change: // 2020/06/23: // (Jing) press minus or plus to adjust sound volume // reg [3:0] volume; always @(posedge clk_100mhz or negedge rst_n) begin if (~rst_n) begin volume <= 'b0; end else if (key_valid) begin if (key_down[KEY_MINUS]) volume <= volume + 4'b1; if (key_down[KEY_EQUAL]) volume <= volume - 4'b1; end else begin volume <= volume; end end wire [15:0] audio_left; wire [15:0] audio_right; assign audio_left = (phase_left) ? (16'b0111_1111_1111_1111 >> volume) : ~(16'b0111_1111_1111_1111 >> volume); assign audio_right = (phase_right) ? (16'b0111_1111_1111_1111 >> volume) : ~(16'b0111_1111_1111_1111 >> volume); // // I2S: // // I2S bus specification: (page 5 ~ 6) // https://www.sparkfun.com/datasheets/BreakoutBoards/I2SBUS.pdf // // declared as output (wire): // audio_mclk // audio_lrck // audio_sck // audio_sdin // // reg: // audio_lrck_delayed // audio_lrck_delayed_delayed // sdin_counter // assign audio_mclk = clk_freerun[1]; // 25MHz (~24.5760MHz) assign audio_lrck = clk_freerun[8]; // 25MHz/128 (~192kHz) assign audio_sck = clk_freerun[3]; // 25MHz/128*32 (25MHz/4) reg audio_lrck_delayed; always @(negedge audio_sck or negedge rst_n) begin if (~rst_n) audio_lrck_delayed <= 'b0; else audio_lrck_delayed <= audio_lrck; end reg audio_lrck_delayed_delayed; always @(negedge audio_sck or negedge rst_n) begin if (~rst_n) audio_lrck_delayed_delayed <= 'b0; else audio_lrck_delayed_delayed <= audio_lrck_delayed; end reg [3:0] sdin_counter; always @(negedge audio_sck or negedge rst_n) begin if (~rst_n) sdin_counter <= 4'h0; else sdin_counter <= sdin_counter - 'b1; end assign audio_sdin = audio_lrck_delayed_delayed ? audio_left [sdin_counter] : audio_right[sdin_counter]; endmodule /* # This behaves somewhat like a comment # miscellaneous set_property IOSTANDARD LVCMOS33 [get_ports clk_100mhz] set_property IOSTANDARD LVCMOS33 [get_ports rst_n] set_property PACKAGE_PIN W5 [get_ports clk_100mhz] set_property PACKAGE_PIN V17 [get_ports rst_n] # switch set_property IOSTANDARD LVCMOS33 [get_ports auto_generate_x] set_property IOSTANDARD LVCMOS33 [get_ports auto_generate_y] set_property IOSTANDARD LVCMOS33 [get_ports auto_generate_ab] set_property PACKAGE_PIN R2 [get_ports auto_generate_x] set_property PACKAGE_PIN T1 [get_ports auto_generate_y] set_property PACKAGE_PIN U1 [get_ports auto_generate_ab] # SSD set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_cathode[0]}] set_property PACKAGE_PIN W7 [get_ports {ssd_cathode[7]}] set_property PACKAGE_PIN W6 [get_ports {ssd_cathode[6]}] set_property PACKAGE_PIN U8 [get_ports {ssd_cathode[5]}] set_property PACKAGE_PIN V8 [get_ports {ssd_cathode[4]}] set_property PACKAGE_PIN U5 [get_ports {ssd_cathode[3]}] set_property PACKAGE_PIN V5 [get_ports {ssd_cathode[2]}] set_property PACKAGE_PIN U7 [get_ports {ssd_cathode[1]}] set_property PACKAGE_PIN V7 [get_ports {ssd_cathode[0]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_anode[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_anode[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_anode[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {ssd_anode[0]}] set_property PACKAGE_PIN W4 [get_ports {ssd_anode[3]}] set_property PACKAGE_PIN V4 [get_ports {ssd_anode[2]}] set_property PACKAGE_PIN U4 [get_ports {ssd_anode[1]}] set_property PACKAGE_PIN U2 [get_ports {ssd_anode[0]}] # PS2 set_property IOSTANDARD LVCMOS33 [get_ports PS2_CLK] set_property IOSTANDARD LVCMOS33 [get_ports PS2_DATA] set_property PACKAGE_PIN C17 [get_ports PS2_CLK] set_property PACKAGE_PIN B17 [get_ports PS2_DATA] # LED set_property IOSTANDARD LVCMOS33 [get_ports {led[15]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[14]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[13]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[12]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[11]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[10]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[9]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[8]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[7]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[6]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[5]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[4]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[3]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[2]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[1]}] set_property IOSTANDARD LVCMOS33 [get_ports {led[0]}] set_property PACKAGE_PIN L1 [get_ports {led[15]}] set_property PACKAGE_PIN P1 [get_ports {led[14]}] set_property PACKAGE_PIN N3 [get_ports {led[13]}] set_property PACKAGE_PIN P3 [get_ports {led[12]}] set_property PACKAGE_PIN U3 [get_ports {led[11]}] set_property PACKAGE_PIN W3 [get_ports {led[10]}] set_property PACKAGE_PIN V3 [get_ports {led[9]}] set_property PACKAGE_PIN V13 [get_ports {led[8]}] set_property PACKAGE_PIN V14 [get_ports {led[7]}] set_property PACKAGE_PIN U14 [get_ports {led[6]}] set_property PACKAGE_PIN U15 [get_ports {led[5]}] set_property PACKAGE_PIN W18 [get_ports {led[4]}] set_property PACKAGE_PIN V19 [get_ports {led[3]}] set_property PACKAGE_PIN U19 [get_ports {led[2]}] set_property PACKAGE_PIN E19 [get_ports {led[1]}] set_property PACKAGE_PIN U16 [get_ports {led[0]}] # miscellaneous set_property IOSTANDARD LVCMOS33 [get_ports rst_n] set_property IOSTANDARD LVCMOS33 [get_ports clk_100mhz] set_property PACKAGE_PIN V17 [get_ports rst_n] set_property PACKAGE_PIN W5 [get_ports clk_100mhz] # I2S set_property IOSTANDARD LVCMOS33 [get_ports audio_sdin] set_property IOSTANDARD LVCMOS33 [get_ports audio_sck] set_property IOSTANDARD LVCMOS33 [get_ports audio_mclk] set_property IOSTANDARD LVCMOS33 [get_ports audio_lrck] set_property PACKAGE_PIN A16 [get_ports audio_lrck] set_property PACKAGE_PIN A14 [get_ports audio_mclk] set_property PACKAGE_PIN B15 [get_ports audio_sck] set_property PACKAGE_PIN B16 [get_ports audio_sdin] # debug #set_property IOSTANDARD LVCMOS33 [get_ports switch0] #set_property IOSTANDARD LVCMOS33 [get_ports switch1] #set_property IOSTANDARD LVCMOS33 [get_ports switch2] #set_property IOSTANDARD LVCMOS33 [get_ports switch3] #set_property IOSTANDARD LVCMOS33 [get_ports switch4] #set_property IOSTANDARD LVCMOS33 [get_ports switch5] #set_property IOSTANDARD LVCMOS33 [get_ports switch6] #set_property IOSTANDARD LVCMOS33 [get_ports switch7] #set_property PACKAGE_PIN V15 [get_ports switch0] #set_property PACKAGE_PIN W14 [get_ports switch1] #set_property PACKAGE_PIN W13 [get_ports switch2] #set_property PACKAGE_PIN V2 [get_ports switch3] #set_property PACKAGE_PIN T3 [get_ports switch4] #set_property PACKAGE_PIN T2 [get_ports switch5] #set_property PACKAGE_PIN R3 [get_ports switch6] #set_property PACKAGE_PIN W2 [get_ports switch7] # debug #set_property IOSTANDARD LVCMOS33 [get_ports {debugswitch0}] #set_property IOSTANDARD LVCMOS33 [get_ports {debugswitch1}] #set_property IOSTANDARD LVCMOS33 [get_ports {debugswitch2}] #set_property PACKAGE_PIN W17 [get_ports {debugswitch0}] #set_property PACKAGE_PIN W16 [get_ports {debugswitch1}] #set_property PACKAGE_PIN V16 [get_ports {debugswitch2}] */