aboutsummaryrefslogtreecommitdiff
path: root/src/example.v
diff options
context:
space:
mode:
Diffstat (limited to 'src/example.v')
-rw-r--r--src/example.v1226
1 files changed, 0 insertions, 1226 deletions
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