From ee1f6c47e1eff920068f4bceaf604f9535a2e8a9 Mon Sep 17 00:00:00 2001 From: Wojciech Kosior Date: Tue, 1 Sep 2020 10:54:59 +0200 Subject: start anew --- src/example.v | 1226 --------------------------------------------------------- 1 file changed, 1226 deletions(-) delete mode 100644 src/example.v (limited to 'src/example.v') diff --git a/src/example.v b/src/example.v deleted file mode 100644 index c588dba..0000000 --- a/src/example.v +++ /dev/null @@ -1,1226 +0,0 @@ -`default_nettype none - -module hex_print(input wire [3:0] halfbyte, - input wire [7:0] x, - input wire [15:0] y, - - output wire pixel - ); - wire [0:7] number_0 [15:0]; - wire [0:7] number_1 [15:0]; - wire [0:7] number_2 [15:0]; - wire [0:7] number_3 [15:0]; - wire [0:7] number_4 [15:0]; - wire [0:7] number_5 [15:0]; - wire [0:7] number_6 [15:0]; - wire [0:7] number_7 [15:0]; - wire [0:7] number_8 [15:0]; - wire [0:7] number_9 [15:0]; - - wire [0:7] letter_A [15:0]; - wire [0:7] letter_B [15:0]; - wire [0:7] letter_C [15:0]; - wire [0:7] letter_D [15:0]; - wire [0:7] letter_E [15:0]; - wire [0:7] letter_F [15:0]; - - assign number_0[0] = 8'b00000000; - assign number_0[1] = 8'b00011000; - assign number_0[2] = 8'b00100100; - assign number_0[3] = 8'b00100100; - assign number_0[4] = 8'b01000110; - assign number_0[5] = 8'b01001010; - assign number_0[6] = 8'b01001010; - assign number_0[7] = 8'b01001010; - assign number_0[8] = 8'b01010010; - assign number_0[9] = 8'b01010010; - assign number_0[10] = 8'b01010010; - assign number_0[11] = 8'b01100010; - assign number_0[12] = 8'b00100100; - assign number_0[13] = 8'b00100100; - assign number_0[14] = 8'b00011000; - assign number_0[15] = 8'b00000000; - - assign number_1[0] = 8'b00000000; - assign number_1[1] = 8'b00001000; - assign number_1[2] = 8'b00011000; - assign number_1[3] = 8'b00111000; - assign number_1[4] = 8'b00001000; - assign number_1[5] = 8'b00001000; - assign number_1[6] = 8'b00001000; - assign number_1[7] = 8'b00001000; - assign number_1[8] = 8'b00001000; - assign number_1[9] = 8'b00001000; - assign number_1[10] = 8'b00001000; - assign number_1[11] = 8'b00001000; - assign number_1[12] = 8'b00001000; - assign number_1[13] = 8'b00001000; - assign number_1[14] = 8'b00001000; - assign number_1[15] = 8'b00000000; - - assign number_2[0] = 8'b00000000; - assign number_2[1] = 8'b00111000; - assign number_2[2] = 8'b01000100; - assign number_2[3] = 8'b00000010; - assign number_2[4] = 8'b00000010; - assign number_2[5] = 8'b00000010; - assign number_2[6] = 8'b00000010; - assign number_2[7] = 8'b00000100; - assign number_2[8] = 8'b00001000; - assign number_2[9] = 8'b00010000; - assign number_2[10] = 8'b00100000; - assign number_2[11] = 8'b00100000; - assign number_2[12] = 8'b01000000; - assign number_2[13] = 8'b01000000; - assign number_2[14] = 8'b01111110; - assign number_2[15] = 8'b00000000; - - assign number_3[0] = 8'b00000000; - assign number_3[1] = 8'b00111000; - assign number_3[2] = 8'b01000100; - assign number_3[3] = 8'b00000010; - assign number_3[4] = 8'b00000010; - assign number_3[5] = 8'b00000010; - assign number_3[6] = 8'b00000100; - assign number_3[7] = 8'b00011000; - assign number_3[8] = 8'b00000100; - assign number_3[9] = 8'b00000010; - assign number_3[10] = 8'b00000010; - assign number_3[11] = 8'b00000010; - assign number_3[12] = 8'b00000010; - assign number_3[13] = 8'b01000100; - assign number_3[14] = 8'b00111000; - assign number_3[15] = 8'b00000000; - - assign number_4[0] = 8'b00000000; - assign number_4[1] = 8'b00001000; - assign number_4[2] = 8'b00001000; - assign number_4[3] = 8'b00010000; - assign number_4[4] = 8'b00010000; - assign number_4[5] = 8'b00100000; - assign number_4[6] = 8'b00100000; - assign number_4[7] = 8'b01000100; - assign number_4[8] = 8'b01111110; - assign number_4[9] = 8'b00000100; - assign number_4[10] = 8'b00000100; - assign number_4[11] = 8'b00000100; - assign number_4[12] = 8'b00000100; - assign number_4[13] = 8'b00000100; - assign number_4[14] = 8'b00000100; - assign number_4[15] = 8'b00000000; - - assign number_5[0] = 8'b00000000; - assign number_5[1] = 8'b01111100; - assign number_5[2] = 8'b01000000; - assign number_5[3] = 8'b01000000; - assign number_5[4] = 8'b01000000; - assign number_5[5] = 8'b01000000; - assign number_5[6] = 8'b01111000; - assign number_5[7] = 8'b00000100; - assign number_5[8] = 8'b00000010; - assign number_5[9] = 8'b00000010; - assign number_5[10] = 8'b00000010; - assign number_5[11] = 8'b00000010; - assign number_5[12] = 8'b00000010; - assign number_5[13] = 8'b01000100; - assign number_5[14] = 8'b00111000; - assign number_5[15] = 8'b00000000; - - assign number_6[0] = 8'b00000000; - assign number_6[1] = 8'b00001100; - assign number_6[2] = 8'b00010000; - assign number_6[3] = 8'b00100000; - assign number_6[4] = 8'b00100000; - assign number_6[5] = 8'b01000000; - assign number_6[6] = 8'b01000000; - assign number_6[7] = 8'b01011000; - assign number_6[8] = 8'b01100100; - assign number_6[9] = 8'b01000010; - assign number_6[10] = 8'b01000010; - assign number_6[11] = 8'b01000010; - assign number_6[12] = 8'b01000010; - assign number_6[13] = 8'b00100100; - assign number_6[14] = 8'b00011000; - assign number_6[15] = 8'b00000000; - - assign number_7[0] = 8'b00000000; - assign number_7[1] = 8'b01111110; - assign number_7[2] = 8'b00000010; - assign number_7[3] = 8'b00000100; - assign number_7[4] = 8'b00000100; - assign number_7[5] = 8'b00001000; - assign number_7[6] = 8'b00001000; - assign number_7[7] = 8'b00111100; - assign number_7[8] = 8'b00010000; - assign number_7[9] = 8'b00010000; - assign number_7[10] = 8'b00010000; - assign number_7[11] = 8'b00100000; - assign number_7[12] = 8'b00100000; - assign number_7[13] = 8'b00100000; - assign number_7[14] = 8'b00100000; - assign number_7[15] = 8'b00000000; - - assign number_8[0] = 8'b00000000; - assign number_8[1] = 8'b00011000; - assign number_8[2] = 8'b00100100; - assign number_8[3] = 8'b01000010; - assign number_8[4] = 8'b01000010; - assign number_8[5] = 8'b01000010; - assign number_8[6] = 8'b00100100; - assign number_8[7] = 8'b00011000; - assign number_8[8] = 8'b00100100; - assign number_8[9] = 8'b01000010; - assign number_8[10] = 8'b01000010; - assign number_8[11] = 8'b01000010; - assign number_8[12] = 8'b01000010; - assign number_8[13] = 8'b00100100; - assign number_8[14] = 8'b00011000; - assign number_8[15] = 8'b00000000; - - assign number_9[0] = 8'b00000000; - assign number_9[1] = 8'b00011000; - assign number_9[2] = 8'b00100100; - assign number_9[3] = 8'b01000010; - assign number_9[4] = 8'b01000010; - assign number_9[5] = 8'b01000010; - assign number_9[6] = 8'b01000010; - assign number_9[7] = 8'b00100110; - assign number_9[8] = 8'b00011010; - assign number_9[9] = 8'b00000010; - assign number_9[10] = 8'b00000010; - assign number_9[11] = 8'b00000100; - assign number_9[12] = 8'b00000100; - assign number_9[13] = 8'b00001000; - assign number_9[14] = 8'b00110000; - assign number_9[15] = 8'b00000000; - - assign letter_A[0] = 8'b00000000; - assign letter_A[1] = 8'b00011000; - assign letter_A[2] = 8'b00100100; - assign letter_A[3] = 8'b00100100; - assign letter_A[4] = 8'b00100100; - assign letter_A[5] = 8'b01000010; - assign letter_A[6] = 8'b01000010; - assign letter_A[7] = 8'b01000010; - assign letter_A[8] = 8'b01111110; - assign letter_A[9] = 8'b01000010; - assign letter_A[10] = 8'b01000010; - assign letter_A[11] = 8'b01000010; - assign letter_A[12] = 8'b01000010; - assign letter_A[13] = 8'b01000010; - assign letter_A[14] = 8'b01000010; - assign letter_A[15] = 8'b00000000; - - assign letter_B[0] = 8'b00000000; - assign letter_B[1] = 8'b01111000; - assign letter_B[2] = 8'b01000100; - assign letter_B[3] = 8'b01000010; - assign letter_B[4] = 8'b01000010; - assign letter_B[5] = 8'b01000010; - assign letter_B[6] = 8'b01000100; - assign letter_B[7] = 8'b01111000; - assign letter_B[8] = 8'b01000100; - assign letter_B[9] = 8'b01000010; - assign letter_B[10] = 8'b01000010; - assign letter_B[11] = 8'b01000010; - assign letter_B[12] = 8'b01000010; - assign letter_B[13] = 8'b01000100; - assign letter_B[14] = 8'b01111000; - assign letter_B[15] = 8'b00000000; - - assign letter_C[0] = 8'b00000000; - assign letter_C[1] = 8'b00011100; - assign letter_C[2] = 8'b00100010; - assign letter_C[3] = 8'b00100000; - assign letter_C[4] = 8'b01000000; - assign letter_C[5] = 8'b01000000; - assign letter_C[6] = 8'b01000000; - assign letter_C[7] = 8'b01000000; - assign letter_C[8] = 8'b01000000; - assign letter_C[9] = 8'b01000000; - assign letter_C[10] = 8'b01000000; - assign letter_C[11] = 8'b01000000; - assign letter_C[12] = 8'b00100000; - assign letter_C[13] = 8'b00100010; - assign letter_C[14] = 8'b00011100; - assign letter_C[15] = 8'b00000000; - - assign letter_D[0] = 8'b00000000; - assign letter_D[1] = 8'b01110000; - assign letter_D[2] = 8'b01001000; - assign letter_D[3] = 8'b01000100; - assign letter_D[4] = 8'b01000100; - assign letter_D[5] = 8'b01000010; - assign letter_D[6] = 8'b01000010; - assign letter_D[7] = 8'b01000010; - assign letter_D[8] = 8'b01000010; - assign letter_D[9] = 8'b01000010; - assign letter_D[10] = 8'b01000010; - assign letter_D[11] = 8'b01000100; - assign letter_D[12] = 8'b01000100; - assign letter_D[13] = 8'b01001000; - assign letter_D[14] = 8'b01110000; - assign letter_D[15] = 8'b00000000; - - assign letter_E[0] = 8'b00000000; - assign letter_E[1] = 8'b01111110; - assign letter_E[2] = 8'b01000000; - assign letter_E[3] = 8'b01000000; - assign letter_E[4] = 8'b01000000; - assign letter_E[5] = 8'b01000000; - assign letter_E[6] = 8'b01000000; - assign letter_E[7] = 8'b01111000; - assign letter_E[8] = 8'b01000000; - assign letter_E[9] = 8'b01000000; - assign letter_E[10] = 8'b01000000; - assign letter_E[11] = 8'b01000000; - assign letter_E[12] = 8'b01000000; - assign letter_E[13] = 8'b01000000; - assign letter_E[14] = 8'b01111110; - assign letter_E[15] = 8'b00000000; - - assign letter_F[0] = 8'b00000000; - assign letter_F[1] = 8'b01111110; - assign letter_F[2] = 8'b01000000; - assign letter_F[3] = 8'b01000000; - assign letter_F[4] = 8'b01000000; - assign letter_F[5] = 8'b01000000; - assign letter_F[6] = 8'b01000000; - assign letter_F[7] = 8'b01111000; - assign letter_F[8] = 8'b01000000; - assign letter_F[9] = 8'b01000000; - assign letter_F[10] = 8'b01000000; - assign letter_F[11] = 8'b01000000; - assign letter_F[12] = 8'b01000000; - assign letter_F[13] = 8'b01000000; - assign letter_F[14] = 8'b01000000; - assign letter_F[15] = 8'b00000000; - - assign pixel = halfbyte == 0 ? number_0[y][x] : - halfbyte == 1 ? number_1[y][x] : - halfbyte == 2 ? number_2[y][x] : - halfbyte == 3 ? number_3[y][x] : - halfbyte == 4 ? number_4[y][x] : - halfbyte == 5 ? number_5[y][x] : - halfbyte == 6 ? number_6[y][x] : - halfbyte == 7 ? number_7[y][x] : - halfbyte == 8 ? number_8[y][x] : - halfbyte == 9 ? number_9[y][x] : - halfbyte == 10 ? letter_A[y][x] : - halfbyte == 11 ? letter_B[y][x] : - halfbyte == 12 ? letter_C[y][x] : - halfbyte == 13 ? letter_D[y][x] : - halfbyte == 14 ? letter_E[y][x] : - letter_F[y][x]; -endmodule - -module vga_timing(input wire clock_50mhz, - input wire reset, - - output reg h_sync, - output reg v_sync, - output reg display_on, - output reg pixel_starting, - output reg row_starting); - - parameter h_pixels = 640; - parameter v_pixels = 480; - parameter h_front_porch = 16; - parameter v_front_porch = 10; - parameter h_pulse = 96; - parameter v_pulse = 2; - parameter h_back_porch = 48; - parameter v_back_porch = 33; - parameter h_pol = 1'b0; - parameter v_pol = 1'b1; - - parameter h_pulse_start = h_front_porch; - parameter v_pulse_start = v_front_porch; - parameter h_pulse_end = h_front_porch + h_pulse; - parameter v_pulse_end = v_front_porch + v_pulse; - parameter h_active_video_start = h_front_porch + h_pulse + h_back_porch; - parameter v_active_video_start = v_front_porch + v_pulse + v_back_porch; - parameter h_frame_end = h_active_video_start + h_pixels; - parameter v_frame_end = v_active_video_start + v_pixels; - - reg [9:0] h_counter; - reg [9:0] v_counter; - - reg divider; // 25MHz - - wire display_on_next_tick; - assign display_on_next_tick = (h_counter < h_frame_end - 1) && - (h_counter >= h_active_video_start - 1) && - (v_counter < v_frame_end) && - (v_counter >= v_active_video_start); - - always @ (posedge clock_50mhz) begin - if (reset) begin - divider <= 1'b0; - - h_counter <= 0; - v_counter <= 0; - - h_sync <= ~h_pol; - v_sync <= ~v_pol; - display_on <= 0; - pixel_starting <= 0; - row_starting <= 0; - end // if (reset) - else begin - divider <= divider + 1; - - if (divider == 1'b1) begin - display_on <= display_on_next_tick; - pixel_starting <= display_on_next_tick; - row_starting <= display_on_next_tick && h_counter == h_active_video_start - 1; - - if (h_counter < h_frame_end - 1) begin - h_counter <= h_counter + 1; - - h_sync <= h_pol ^ (h_counter < h_pulse_start - 1 || h_counter >= h_pulse_end - 1); - end - else begin - h_counter <= 0; - - if (v_counter < v_frame_end - 1) begin - v_counter <= v_counter + 1; - - v_sync <= v_pol ^ (v_counter < v_pulse_start - 1 || v_counter >= v_pulse_end - 1); - end - else begin - v_counter <= 0; - end // else: !if(v_counter < v_frame_end - 1) - end // else: !if(h_counter < h_frame_end - 1) - end // if (divider == 1'b1) - else begin - pixel_starting <= 0; - row_starting <= 0; - end - end // else: !if(reset) - end // always @ (posedge clock_50mhz) -endmodule // vga_timing - -module vga_pass_colors(input wire clock_50mhz, - input wire reset, - - input wire h_sync_next_tick, - input wire v_sync_next_tick, - input wire display_on_next_tick, - input wire pixel_on_next_tick, - - output reg h_sync, - output reg v_sync, - output reg [2:0] vga_red, - output reg [2:0] vga_green, - output reg [2:0] vga_blue - ); - - wire [8:0] color_next_tick; - assign color_next_tick = !display_on_next_tick ? 0 : - pixel_on_next_tick ? color1 : color2; - - parameter color1 = {3'b010, 3'b111, 3'b101}; - parameter color2 = {3'b000, 3'b000, 3'b111}; - - always @ (posedge clock_50mhz) begin - if (reset) begin - h_sync <= 0; - v_sync <= 0; - vga_red <= 0; - vga_green <= 0; - vga_blue <= 0; - end - else begin - h_sync <= h_sync_next_tick; - v_sync <= v_sync_next_tick; - - vga_red <= color_next_tick[8:6]; - vga_green <= color_next_tick[5:3]; - vga_blue <= color_next_tick[2:0]; - end // else: !if(reset) - end // always @ (posedge clock_50mhz) -endmodule // vga_pass_colors - -module vga_hexmode(input wire clock_50mhz, - input wire reset, - - input wire can_read, - input wire [15:0] read_data, - - output wire want_to_read, - output wire [17:0] read_addr, - - input wire [17:0] displayed_memory_base, - - output wire h_sync, - output wire v_sync, - output wire [2:0] vga_red, - output wire [2:0] vga_green, - output wire [2:0] vga_blue - ); - wire h_sync_next_tick; - wire v_sync_next_tick; - wire display_on_next_tick; - wire pixel_starting_next_tick; - wire row_starting_next_tick; - - vga_timing timing(clock_50mhz, reset, - h_sync_next_tick, v_sync_next_tick, display_on_next_tick, - pixel_starting_next_tick, row_starting_next_tick); - - parameter queue_size = 4; - - /* will store 4 consecutive hex digits copied from read_data[15:0] */ - reg [15:0] digits_queue; - reg [1:0] digits_in_queue; - - parameter words_per_line = 20; - parameter lines = 30; - parameter words_per_screen = words_per_line * lines; - parameter digit_h_pixels = 8; - parameter digit_v_pixels = 16; - parameter word_digits = 4; - - reg [2:0] digit_x; - wire [2:0] subsequent_digit_x; - assign subsequent_digit_x = digit_x == digit_h_pixels - 1 ? 0 : digit_x + 1; - - reg [3:0] digit_y; - wire [3:0] subsequent_digit_y; - assign subsequent_digit_y = digit_y == digit_v_pixels - 1 ? 0 : digit_y + 1; - - wire digit_starting_next_tick; - assign digit_starting_next_tick = pixel_starting_next_tick && - digit_x == digit_h_pixels - 1; - - wire line_starting_next_tick; - assign line_starting_next_tick = row_starting_next_tick && - digit_y == digit_v_pixels - 1; - - reg [4:0] word_in_line; - reg [11:0] word_idx; - wire [11:0] subsequent_word_idx; - assign subsequent_word_idx = word_idx == words_per_screen - 1 ? - 0 : word_idx + 1; - - assign read_addr = displayed_memory_base + word_idx; - - reg [3:0] current_digit; - wire [3:0] digit_next_tick; - assign digit_next_tick = digit_starting_next_tick ? - digits_queue[15:12] : current_digit; - - wire pixel_on_next_tick; - - hex_print hex_print(digit_next_tick, - pixel_starting_next_tick ? subsequent_digit_x : digit_x, - row_starting_next_tick ? subsequent_digit_y : digit_y, - pixel_on_next_tick); - - vga_pass_colors color_pass(clock_50mhz, reset, h_sync_next_tick, - v_sync_next_tick, display_on_next_tick, - pixel_on_next_tick, h_sync, v_sync, - vga_red, vga_green, vga_blue); - - /* 0 - waiting for read; 1 - reading; 2 - reading done */ - reg [1:0] reading_state; - - assign want_to_read = reading_state == 0 || - (digit_starting_next_tick && - digits_in_queue - 1 == 0); - - wire reading; - /* If new read can start, the previous one is ignored */ - assign reading = reading_state == 1 && !(want_to_read); - - always @ (posedge clock_50mhz) begin - if (reset) begin - digits_queue <= 16'bxxxxxxxxxxxxxxxx; - digits_in_queue <= 0; - reading_state <= 0; - digit_x <= digit_h_pixels - 1; - digit_y <= digit_v_pixels - 1; - word_in_line <= 0; - word_idx <= 0; - end - else begin - if (pixel_starting_next_tick) - digit_x <= subsequent_digit_x; - - if (digit_starting_next_tick) begin - current_digit <= digit_next_tick; - - /* - * Once there's only 1 digit in the queue, word_idx shall - * already be pointing at the next address. - */ - if (digits_in_queue - 3 == 0) begin - if (word_in_line == words_per_line - 1) begin - word_in_line <= 0; - if (digit_y == digit_v_pixels - 1) - word_idx <= subsequent_word_idx; - else - word_idx <= word_idx - (words_per_line - 1); - end - else begin - word_in_line <= word_in_line + 1; - word_idx <= subsequent_word_idx; - end - end - - /* - * Hopefully read will always finish before we pop the next digit - * from the queue. But we still need to avoid multiple drivers. - */ - if (!reading) - digits_queue <= {digits_queue[11:0], 4'bxxxx}; - end - - if (row_starting_next_tick) - digit_y <= subsequent_digit_y; - - digits_in_queue <= digits_in_queue + (reading ? queue_size : 0) - - (digit_starting_next_tick ? 1 : 0); - - if (want_to_read) begin - if (can_read) - reading_state <= 1; - else - reading_state <= 0; - end - else if (reading_state == 1) begin - reading_state <= 2; - digits_queue <= read_data; - end - end // else: !if(reset) - end // always @ (posedge clock_50mhz) -endmodule - -module on_button_write(input wire clock_50mhz, - input wire reset, - - input wire can_write, - output reg [15:0] write_data, - - output wire want_to_write, - output wire [17:0] write_addr, - - input wire [17:0] written_memory_base, - input wire but - ); - /* - * We use a reg to snapshot (and invert) the button signal (button2). - * If we didn't snapshot it, we'd get timing problems. - */ - reg button_pressed; - - /* 0 - waiting for write, 1 - writing, 2 - write complete */ - reg [1:0] write_state; - - parameter cooldown_start = 25'b111111111111111111111111; - reg [23:0] but_cooldown; - - reg [4:0] write_idx; - assign write_addr = written_memory_base + write_idx; - - wire perform_action; - assign perform_action = button_pressed && !but_cooldown; - assign want_to_write = perform_action || write_state == 0; - - always @ (posedge clock_50mhz) begin - if (reset) begin - but_cooldown <= cooldown_start; - write_data <= 16'b000100000000000; - write_state <= 2; - write_idx <= 0; - button_pressed <= 0; - end - else begin - button_pressed <= !but; - - if (perform_action) - but_cooldown <= cooldown_start; - else if (but_cooldown) - but_cooldown <= but_cooldown - 1; - - if (want_to_write) begin - if (can_write) - write_state <= 1; - else - write_state <= 0; - end - else if (write_state == 1) begin - write_state <= 2; - - write_data <= write_data + 1; - write_idx <= write_idx >= 30 ? 0 : write_idx + 1; - end - end - end // always @ (posedge clock_50mhz) -endmodule - -module winbond_spi(input wire clock_50mhz, - input wire reset, - - input wire operate, - input wire [31:0] send_data, - input wire [2:0] bytes_to_send, - input wire [14:0] bytes_to_receive, - - output reg byte_ready, - output reg [7:0] received_data, - output reg operation_finished, - - output reg sdo, - input wire sdi, - output wire sck, - output reg ss_n - ); - reg working; - reg operating; - - reg [31:0] sdo_data; - reg [5:0] bits_to_output; - - parameter sending = 0; - parameter receiving = 1; - reg state; - - reg [6:0] sdi_data; - reg [17:0] bits_to_receive; - reg [3:0] bits_received; - reg send_only_operation; - - assign sck = clock_50mhz; - - always @ (posedge clock_50mhz) begin - if (reset || !operate) begin - operating <= 0; - byte_ready <= 0; - operation_finished <= 0; - - bits_to_receive <= 18'hXXXXX; - bits_to_output <= 6'hXX; - sdi_data <= 7'hXX; - sdo_data <= 32'hXXXXXXXX; - received_data <= 8'hXX; - send_only_operation <= 1'bx; - state <= 1'bx; - end - else begin - operating <= 1; - - if (!operating && operate) begin - bits_to_receive <= bytes_to_receive * 8; - bits_to_output <= bytes_to_send * 8; - sdo_data <= send_data; - send_only_operation <= bytes_to_receive == 0; - state <= sending; - byte_ready <= 0; - operation_finished <= 0; - - sdi_data <= 7'hXX; - received_data <= 8'hXX; - end - else begin - if (operation_finished) begin - byte_ready <= 0; - - bits_to_receive <= 18'hXXXXX; - bits_to_output <= 6'hXX; - sdi_data <= 7'hXX; - sdo_data <= 32'hXXXXXXXX; - received_data <= 8'hXX; - send_only_operation <= 1'bx; - state <= 1'bx; - end - else begin - if (state == sending) begin - byte_ready <= 0; - bits_to_output <= bits_to_output - 1; - sdo_data <= {sdo_data[30:0], 1'bx}; - - if (bits_to_output - 1 == 0) begin - state <= receiving; - if (send_only_operation) - operation_finished <= 1; - end - - sdi_data <= 7'hXX; - received_data <= 8'hXX; - end // if (state == sending) - - if (state == receiving) begin - - bits_to_receive <= bits_to_receive - 1; - sdi_data <= {sdi_data[5:0], sdi}; - - if (bits_to_receive % 8 - 1 == 0) begin - byte_ready <= 1; - received_data <= {sdi_data[6:0], sdi}; - end - else begin - byte_ready <= 0; - received_data <= 8'hXX; - end - - if (bits_to_receive - 1 == 0) - operation_finished <= 1; - - bits_to_output <= 6'hXX; - sdo_data <= 32'hXXXXXXXX; - end // if (state == receiving) - end // else: !if(operation_finished) - end // else: !if(!operating && operate) - end // else: !if(reset || !operate) - end // always @ (posedge clock_50mhz) - - always @ (negedge clock_50mhz) begin - sdo <= sdo_data[31]; - - if (!operating) begin - ss_n <= 1; - end - else begin - if (operation_finished) - ss_n <= 1; - else - ss_n <= 0; - end - end // always @ (negedge clock_50mhz) -endmodule // winbond_spi - -module spi_chip_powerup(input wire clock_50mhz, - input wire reset, - - output reg want_spi_operation, - output wire [31:0] spi_send_data, - output wire [2:0] spi_bytes_to_send, - output wire [14:0] spi_bytes_to_receive, - - input wire spi_operation_finished, - - input wire operate, - output reg finished_operating - ); - parameter power_up_instruction = 8'hAB; - - assign spi_send_data = {power_up_instruction, 24'hXXXXXX}; - assign spi_bytes_to_send = 1; - assign spi_bytes_to_receive = 0; - - parameter sending_power_up = 0; - parameter waiting = 1; - reg state; - - parameter freq = 50; /* Mhz */ - parameter powerup_wait_time = 3000; /* ns */ - parameter powerup_wait_ticks = powerup_wait_time * freq / 1000; - reg [7:0] powerup_wait_counter; - - reg operating; - - always @ (posedge clock_50mhz) begin - if (reset || !operate) begin - want_spi_operation <= 0; - finished_operating <= 0; - operating <= 0; - - state <= 1'bx; - powerup_wait_counter <= 8'hXX; - end - else begin - operating <= 1; - - if (!operating && operate) begin - want_spi_operation <= 1; - finished_operating <= 0; - state <= sending_power_up; - - powerup_wait_counter <= 8'hXX; - end - else begin - if (state == sending_power_up) begin - finished_operating <= 0; - - if (spi_operation_finished) begin - powerup_wait_counter <= powerup_wait_ticks; - state <= waiting; - want_spi_operation <= 0; - end - else begin - want_spi_operation <= 1; - - powerup_wait_counter <= 8'hXX; - end - end // if (state == sending_power_up) - - if (state == waiting) begin - want_spi_operation <= 0; - - if (powerup_wait_counter == 0) begin - finished_operating <= 1; - end - else begin - finished_operating <= 0; - powerup_wait_counter <= powerup_wait_counter - 1; - end - end // if (state == waiting) - end // else: !if(!operating && operate) - end // else: !if(reset || !operate) - end // always @ (posedge clock_50mhz) -endmodule // spi_chip_powerup - -module spi_sram_copy(input wire clock_50mhz, - input wire reset, - - input wire can_write, - output reg [15:0] write_data, - - output wire want_to_write, /* sram memory */ - output wire [17:0] write_addr, - - input wire [17:0] written_memory_base, - - output reg want_spi_operation, - output wire [31:0] spi_send_data, - output wire [2:0] spi_bytes_to_send, - output wire [14:0] spi_bytes_to_receive, - - input wire spi_byte_ready, - input wire [7:0] received_byte, - - input wire [23:0] flash_memory_base, - - input wire operate, - output reg finished_operating - ); - parameter fast_read_instruction = 8'h0B; - - parameter words_to_copy = 600; - - assign spi_bytes_to_send = 5; - - reg [9:0] words_left_to_receive; - assign spi_bytes_to_receive = words_left_to_receive * 2; - - reg [9:0] word_idx; - - assign write_addr = written_memory_base + word_idx; - - wire [23:0] read_addr; - assign read_addr = flash_memory_base + 16 * word_idx; - assign spi_send_data = {fast_read_instruction, read_addr}; - - reg write_word_ready; - assign want_to_write = write_word_ready; - - wire write_happens; - assign write_happens = want_to_write && can_write; - - reg [7:0] high_byte; - reg high_byte_received; - - wire word_received; - assign word_received = high_byte_received && spi_byte_ready; - - /* true if next spi data word came b4 we handled the previous one :c */ - wire data_discarded; - assign data_discarded = word_received && write_word_ready && !write_happens; - - reg reading_finished; - - reg operating; - - always @ (posedge clock_50mhz) begin - if (reset || !operate) begin - operating <= 0; - want_spi_operation <= 0; - finished_operating <= 0; - write_word_ready <= 0; - - words_left_to_receive <= 10'hXXX; - word_idx <= 10'hXXX; - high_byte <= 8'hXX; - high_byte_received <= 1'bx; - reading_finished <= 1'bx; - end // if (reset || !operate) - else begin - operating <= 1; - - if (operate && !operating) begin - want_spi_operation <= 1; - finished_operating <= 0; - write_word_ready <= 0; - words_left_to_receive <= words_to_copy; - word_idx <= 0; - reading_finished <= 0; - high_byte_received <= 0; - - high_byte <= 8'hXX; - end // if (operate && !operating) - else if (finished_operating) begin - want_spi_operation <= 0; - write_word_ready <= 0; - words_left_to_receive <= 10'hXX; - word_idx <= 10'hXX; - reading_finished <= 1'bx; - high_byte_received <= 1'bx; - high_byte <= 8'hXX; - end - else begin - /* - * if spi data comes too fast, we discard it and start reading - * anew once we write current data - */ - if (reading_finished) - want_spi_operation <= 0; - else if (data_discarded) - want_spi_operation <= 0; - else if (write_happens) - want_spi_operation <= 1; - - if (spi_byte_ready) begin - if (high_byte_received) begin - high_byte_received <= 0; - - high_byte <= 8'hXX; - end - else begin - high_byte <= received_byte; - high_byte_received <= 1; - end - end // if (spi_byte_ready) - - if (word_received && !data_discarded) begin - words_left_to_receive <= words_left_to_receive - 1; - write_word_ready <= 1; - write_data <= {high_byte, received_byte}; - - if (words_left_to_receive - 1 == 0) - reading_finished <= 1; - end - else if (write_happens) begin - write_word_ready <= 0; - write_data <= 16'hXXXX; - end - else if (!write_word_ready) begin - write_data <= 16'hXXXX; - end - - if (write_happens) begin - word_idx <= word_idx + 1; - - if (reading_finished) - finished_operating <= 1; - end - end // else: !if(finished_operating) - end // else: !if(reset || !operate) - end // always @ (posedge clock_50mhz) -endmodule // spi_sram_copy - -module top(input wire clock_100mhz, - input wire but1, - input wire but2, - - output reg [17:0] sram_addr, - inout wire [15:0] sram_io, - output reg sram_cs_n, - output reg sram_oe_n, - output reg sram_we_n, - - output wire h_sync, - output wire v_sync, - output wire [2:0] vga_red, - output wire [2:0] vga_green, - output wire [2:0] vga_blue, - - output wire sdo, - input wire sdi, - output wire sck, - output wire ss_n - ); - /* - * We use a reg to snapshot (and invert) the reset signal - * (actually button1). If we didn't snapshot it, we'd get - * timing problems - */ - reg reset; - - reg err_disabled; - - reg clock_50mhz; - /* - * `initial` usually isn't synthesizable, but it helps run the code - * in test-benches - */ - initial begin - reset <= 1; - clock_50mhz <= 0; - err_disabled <= 0; - end - - always @ (posedge clock_100mhz) - clock_50mhz <= clock_50mhz + 1; - - parameter memory_base = 18'b010101010101010101; - parameter flash_base = 24'h000000; - - wire vga_io_available; - assign vga_io_available = 1; - wire vga_wants_io; - wire [17:0] vga_io_addr; - - vga_hexmode vga(clock_50mhz, reset, vga_io_available, sram_io, vga_wants_io, - vga_io_addr, memory_base, - h_sync, v_sync, vga_red, vga_green, vga_blue); - - reg last_reset; - always @ (posedge clock_50mhz) - last_reset <= reset; - - wire spi_operation_wanted; - wire [31:0] spi_send_data; - wire [2:0] spi_bytes_to_send; - wire [14:0] spi_bytes_to_receive; - wire spi_byte_ready; - wire [7:0] spi_received_data; - wire spi_operation_finished; - - winbond_spi spi(clock_50mhz, reset, spi_operation_wanted, - spi_send_data, spi_bytes_to_send, - spi_bytes_to_receive, spi_byte_ready, - spi_received_data, spi_operation_finished, - sdo, sdi, sck, ss_n); - - wire chip_powerup_wants_operation; - wire [31:0] chip_powerup_send_data; - wire [2:0] chip_powerup_bytes_to_send; - wire [14:0] chip_powerup_bytes_to_receive; - wire chip_powerup_finished_operating; - - spi_chip_powerup chip_powerup(clock_50mhz, reset, - chip_powerup_wants_operation, - chip_powerup_send_data, - chip_powerup_bytes_to_send, - chip_powerup_bytes_to_receive, - spi_operation_finished, !reset, - chip_powerup_finished_operating); - - wire data_copy_sram_io_available; - assign data_copy_sram_io_available = vga_io_available && !vga_wants_io; - wire [15:0] data_copy_write_data; - wire data_copy_wants_sram_io; - wire [17:0] data_copy_sram_io_addr; - wire data_copy_wants_spi_operation; - wire [31:0] data_copy_spi_send_data; - wire [2:0] data_copy_spi_bytes_to_send; - wire [14:0] data_copy_spi_bytes_to_receive; - wire data_copy_finished_operating; - - spi_sram_copy data_copy(clock_50mhz, reset, data_copy_sram_io_available, - data_copy_write_data, data_copy_wants_sram_io, - data_copy_sram_io_addr, memory_base, - data_copy_wants_spi_operation, - data_copy_spi_send_data, data_copy_spi_bytes_to_send, - data_copy_spi_bytes_to_receive, spi_byte_ready, - spi_received_data, flash_base, - chip_powerup_finished_operating, - data_copy_finished_operating); - - assign { - spi_operation_wanted, - spi_send_data, - spi_bytes_to_send, - spi_bytes_to_receive - } - = !chip_powerup_finished_operating ? - { - chip_powerup_wants_operation, - chip_powerup_send_data, - chip_powerup_bytes_to_send, - chip_powerup_bytes_to_receive - } : - !data_copy_finished_operating ? - { - data_copy_wants_spi_operation, - data_copy_spi_send_data, - data_copy_spi_bytes_to_send, - data_copy_spi_bytes_to_receive - } : - {1'b0, 32'hXXXXXXXX, 3'hX, 15'hXXXX}; - - wire butwrite_io_available; - assign butwrite_io_available = data_copy_sram_io_available - && !data_copy_wants_sram_io; - - wire butwrite_wants_io; - wire [17:0] butwrite_io_addr; - wire [15:0] butwrite_write_data; - - on_button_write butwrite(clock_50mhz, reset, butwrite_io_available, - butwrite_write_data, butwrite_wants_io, - butwrite_io_addr, memory_base, but2); - - reg [15:0] write_data; - reg write_in_progress; - - always @ (posedge clock_50mhz) begin - reset <= !but1 || err_disabled; - - if (!but1) - err_disabled <= 0; - - if (reset) begin - err_disabled <= 0; - write_in_progress <= 0; - sram_oe_n <= 1'b1; - sram_cs_n <= 1'b1; - write_data <= 16'bxxxxxxxxxxxxxxxx; - end - else begin - if (vga_wants_io) begin - write_in_progress <= 0; - sram_oe_n <= 1'b0; - sram_cs_n <= 1'b0; - sram_addr <= vga_io_addr; - end - else if (data_copy_wants_sram_io) begin - write_in_progress <= 1; - sram_oe_n <= 1'b1; - sram_cs_n <= 1'b0; - sram_addr <= data_copy_sram_io_addr; - write_data <= data_copy_write_data; - end - else if (butwrite_wants_io) begin - write_in_progress <= 1; - sram_oe_n <= 1'b1; - sram_cs_n <= 1'b0; - sram_addr <= butwrite_io_addr; - write_data <= butwrite_write_data; - if (butwrite_io_addr > memory_base + 30) - err_disabled <= 1; - end - else begin - write_in_progress <= 0; - sram_oe_n <= 1'b1; - sram_cs_n <= 1'b1; - end - end - end // always @ (posedge clock_50mhz) - - always @ (negedge clock_100mhz) begin - if (reset) begin - sram_we_n <= 1'b1; - end - else begin - if (write_in_progress) - sram_we_n <= !sram_we_n; - else - sram_we_n <= 1'b1; - end - end - - assign sram_io = sram_we_n ? 16'bzzzzzzzzzzzzzzzz : write_data; -endmodule // top -- cgit v1.2.3