From 26abb05614344f2944ed3852d24539a49149e052 Mon Sep 17 00:00:00 2001 From: jaseg Date: Thu, 24 Jun 2021 12:14:40 +0200 Subject: [PATCH] output WIP --- Artix-7-HDMI-processing.xpr | 145 +++++++-------- src/hdmi_design.vhd | 5 +- src/hdmi_io.vhd | 7 +- src/spi_regfile.v | 39 ++-- src/term_emu.v | 327 ++++++++++++++++----------------- src/top.v | 327 +++++++++++++++++++++++++++++++++ src/window_matcher.v | 170 ++++++++--------- test_bench/spi_regfile_tb.v | 2 +- test_bench/window_matcher_tb.v | 2 + 9 files changed, 677 insertions(+), 347 deletions(-) create mode 100644 src/top.v diff --git a/Artix-7-HDMI-processing.xpr b/Artix-7-HDMI-processing.xpr index bfea4ef..af714a4 100644 --- a/Artix-7-HDMI-processing.xpr +++ b/Artix-7-HDMI-processing.xpr @@ -68,24 +68,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - @@ -110,12 +139,6 @@ - - - - - - @@ -140,12 +163,6 @@ - - - - - - @@ -164,18 +181,6 @@ - - - - - - - - - - - - @@ -206,50 +211,45 @@ - - - - - - - - - - - - - - - - - + - + - - + - - + + + + + + + + + + + + + + + - @@ -281,14 +281,6 @@ - - - - - - - - @@ -384,11 +376,6 @@ - - - - - @@ -471,6 +458,20 @@ + + + + + + + + + + + + + + diff --git a/src/hdmi_design.vhd b/src/hdmi_design.vhd index 118cffa..18efb55 100644 --- a/src/hdmi_design.vhd +++ b/src/hdmi_design.vhd @@ -304,7 +304,7 @@ i_hdmi_io: hdmi_io port map ( symbol_ch2 => symbol_ch2 ); -i_processing: pixel_processing Port map ( +i_processing: proc_top Port map ( clk => pixel_clk, switches => sw, ------------------ @@ -318,9 +318,6 @@ i_processing: pixel_processing Port map ( in_blue => in_blue, is_interlaced => is_interlaced, is_second_field => is_second_field, - audio_channel => audio_channel, - audio_de => audio_de, - audio_sample => audio_sample, ------------------- -- Processed pixels ------------------- diff --git a/src/hdmi_io.vhd b/src/hdmi_io.vhd index 04ed9dc..5fd598a 100644 --- a/src/hdmi_io.vhd +++ b/src/hdmi_io.vhd @@ -353,8 +353,11 @@ begin debug(7) <= raw_hsync; debug(6) <= raw_vsync; debug(5) <= is_second_field_i; - debug(4) <= is_interlaced_i; - debug(3 downto 0) <= (others => '0'); + debug(4) <= is_interlaced_i; + debug(3) <= out_hsync; + debug(2) <= out_vsync; + debug(1) <= out_blank; + debug(0) <= '0'; i_edid_rom: edid_rom port map ( clk => clk100, diff --git a/src/spi_regfile.v b/src/spi_regfile.v index 7c44a53..b5bf567 100644 --- a/src/spi_regfile.v +++ b/src/spi_regfile.v @@ -6,25 +6,26 @@ module spi_regfile( input sck, sdi, ncs, output reg sdo, - input [15:0] spi_data_in, - output reg [15:0] spi_data_out, + input [7:0] spi_data_in, + output reg [7:0] spi_data_out, - input [15:0] spi_status_word, - output reg [15:0] spi_cmd_word, + input [7:0] spi_status_word, + output reg [7:0] spi_cmd_word, output reg spi_cmd_begin, output reg spi_cmd_active, output reg spi_cmd_step, output reg [19:0] spi_cmd_idx ); - -reg [14:0] txbuf; -reg [15:0] rxbuf; +reg [6:0] txbuf; +reg [7:0] rxbuf; reg is_cmd_word; reg last_ncs; reg last_sck; reg load_data; +/* SPI mode 0: CPOL = 0, CPHA = 0. Initial SDO setup on falling ~CS edge */ + always @(posedge clk) begin spi_cmd_begin <= 0; spi_cmd_step <= 0; @@ -39,29 +40,29 @@ always @(posedge clk) begin end else begin if (last_ncs && !ncs) begin - txbuf <= spi_status_word[14:0]; - sdo <= spi_status_word[15]; - rxbuf <= 15'h0001; + txbuf <= spi_status_word[6:0]; + sdo <= spi_status_word[7]; + rxbuf <= 8'h01; end if (!ncs) begin if (!last_sck && sck) begin /* sampling edge */ - if (!rxbuf[15]) begin - rxbuf <= {rxbuf[14:0], sdi}; + if (!rxbuf[7]) begin + rxbuf <= {rxbuf[6:0], sdi}; end else begin - rxbuf <= 15'h0001; + rxbuf <= 8'h01; load_data <= 1; if (is_cmd_word) begin - spi_cmd_word <= {rxbuf[14:0], sdi}; + spi_cmd_word <= {rxbuf[6:0], sdi}; is_cmd_word <= 0; spi_cmd_active <= 1; spi_cmd_begin <= 1; spi_cmd_idx <= 0; end else begin - spi_data_out <= {rxbuf[14:0], sdi}; + spi_data_out <= {rxbuf[6:0], sdi}; spi_cmd_idx <= spi_cmd_idx+1; spi_cmd_step <= 1; end @@ -69,12 +70,12 @@ always @(posedge clk) begin end else if (last_sck && !sck) begin /* driving edge */ if (load_data) begin - sdo <= spi_data_in[15]; - txbuf <= spi_data_in[14:0]; + sdo <= spi_data_in[7]; + txbuf <= spi_data_in[6:0]; end else begin - sdo <= txbuf[14]; - txbuf <= {txbuf[13:0], 1'b0}; + sdo <= txbuf[6]; + txbuf <= {txbuf[5:0], 1'b0}; end end diff --git a/src/term_emu.v b/src/term_emu.v index 1305f25..8e3e6dc 100644 --- a/src/term_emu.v +++ b/src/term_emu.v @@ -58,6 +58,17 @@ always @(posedge clk) begin glyph_x <= 0; glyph_y <= 0; num_start <= 0; + cur_fg <= 7; + cur_bg <= 0; + cur_bold <= 0; + cur_underline <= 0; + num_buf_idx <= 0; + csi_act_ctr <= 0; + esc_inval <= 0; + cursor_movement_x_pos <= 0; + cursor_movement_x_neg <= 0; + cursor_movement_y_pos <= 0; + cursor_movement_y_neg <= 0; end else if (!parser_valid && in_byte_valid) begin in_byte_ack <= 1; @@ -131,6 +142,155 @@ always @(posedge clk) begin end end endcase + + end else if (parser_valid) begin + if (cursor_movement_x_pos || cursor_movement_x_neg || cursor_movement_y_pos || cursor_movement_y_neg) begin + csi_act_ctr <= bcd12_inc(csi_act_ctr); + + if (csi_act_ctr != ~num_buf_last) begin + if (cursor_movement_x_pos) begin + if (glyph_x != GLYPHMEM_W-1) glyph_x <= glyph_x + 1; + end else if (cursor_movement_x_neg) begin + if (glyph_x != 0) glyph_x <= glyph_x - 1; + end else if (cursor_movement_y_pos) begin + if (glyph_y != GLYPHMEM_H-1) glyph_y <= glyph_y + 1; + end else if (cursor_movement_y_neg) begin + if (glyph_y != 0) glyph_y <= glyph_y - 1; + end + end + + if (num_buf_last == 0 || ~num_buf_last == 12'h001 || csi_act_ctr == ~num_buf_last) begin + if (cursor_movement_x_pos && cursor_movement_y_pos) begin + num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000}; + cursor_movement_x_pos <= 0; + end else begin + parser_valid <= 0; + end + end + + end else if (parser_action == 8'h41 && !esc_inval) begin /* A; Cursor up */ + cursor_movement_y_neg <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h42 && !esc_inval) begin /* B; Cursor down */ + cursor_movement_y_pos <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h43 && !esc_inval) begin /* C; Cursor forward */ + cursor_movement_x_pos <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h44 && !esc_inval) begin /* D; Cursor back */ + cursor_movement_x_neg <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h45 && !esc_inval) begin /* E; Cursor next line */ + glyph_x <= 0; + cursor_movement_y_pos <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h46 && !esc_inval) begin /* F: Cursor previous line */ + glyph_x <= 0; + cursor_movement_y_neg <= 1; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + + end else if (parser_action == 8'h47 && !esc_inval) begin /* G: Cursor horizontal absolute */ + glyph_x <= 0; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; + if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin + cursor_movement_x_pos <= 1; + end else begin + parser_valid <= 0; + end + + end else if (parser_action == 8'h48 && !esc_inval) begin /* H: Cursor x/y absolute */ + glyph_x <= 0; + glyph_y <= 0; + num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-24] <= num_buf[23:0]; + if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin + cursor_movement_x_pos <= 1; + cursor_movement_y_pos <= 1; + end else begin + parser_valid <= 0; + end + + end else if (parser_action == 8'h6d && !esc_inval) begin /* m; CSI SGR */ + if (num_buf_idx == NUM_BUF_SZ-1) begin + parser_valid <= 0; + end + + case (~num_buf_last) + (12'h000): begin /* reset */ + cur_fg <= 7; + cur_bg <= 0; + cur_bold <= 0; + cur_underline <= 0; + end + (12'h001): begin /* bold */ + cur_bold <= 1; + end + (12'h004): begin /* underlined */ + cur_underline <= 1; + end + (12'h007): begin /* reverse video */ + cur_fg = cur_bg; + cur_bg = cur_fg; + end + (12'h022): begin /* not bold */ + cur_bold <= 0; + end + (12'h024): begin /* not underlined */ + cur_underline <= 0; + end + + (12'h030): cur_fg <= 0; + (12'h031): cur_fg <= 1; + (12'h032): cur_fg <= 2; + (12'h033): cur_fg <= 3; + (12'h034): cur_fg <= 4; + (12'h035): cur_fg <= 5; + (12'h036): cur_fg <= 6; + (12'h037): cur_fg <= 7; + (12'h038): esc_inval <= 1; + (12'h039): cur_fg <= 7; + + (12'h040): cur_bg <= 0; + (12'h041): cur_bg <= 1; + (12'h042): cur_bg <= 2; + (12'h043): cur_bg <= 3; + (12'h044): cur_bg <= 4; + (12'h045): cur_bg <= 5; + (12'h046): cur_bg <= 6; + (12'h047): cur_bg <= 7; + (12'h048): esc_inval <= 1; + (12'h049): cur_bg <= 0; + + (12'h090): cur_fg <= 8; + (12'h091): cur_fg <= 9; + (12'h092): cur_fg <= 10; + (12'h093): cur_fg <= 11; + (12'h094): cur_fg <= 12; + (12'h095): cur_fg <= 13; + (12'h096): cur_fg <= 14; + (12'h097): cur_fg <= 15; + + (12'h100): cur_bg <= 8; + (12'h101): cur_bg <= 9; + (12'h102): cur_bg <= 10; + (12'h103): cur_bg <= 11; + (12'h104): cur_bg <= 12; + (12'h105): cur_bg <= 13; + (12'h106): cur_bg <= 14; + (12'h107): cur_bg <= 15; + /* (12'hfff): ignore! */ + endcase + + num_buf_idx <= num_buf_idx + 1; + num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000}; + + end else begin + parser_valid <= 0; + end end end @@ -156,171 +316,4 @@ begin end endfunction -always @(posedge clk) begin - if (rst) begin - cur_fg <= 7; - cur_bg <= 0; - cur_bold <= 0; - cur_underline <= 0; - num_buf_idx <= 0; - csi_act_ctr <= 0; - esc_inval <= 0; - cursor_movement_x_pos <= 0; - cursor_movement_x_neg <= 0; - cursor_movement_y_pos <= 0; - cursor_movement_y_neg <= 0; - - end else begin - if (parser_valid) begin - if (cursor_movement_x_pos || cursor_movement_x_neg || cursor_movement_y_pos || cursor_movement_y_neg) begin - csi_act_ctr <= bcd12_inc(csi_act_ctr); - - if (csi_act_ctr != ~num_buf_last) begin - if (cursor_movement_x_pos) begin - if (glyph_x != GLYPHMEM_W-1) glyph_x <= glyph_x + 1; - end else if (cursor_movement_x_neg) begin - if (glyph_x != 0) glyph_x <= glyph_x - 1; - end else if (cursor_movement_y_pos) begin - if (glyph_y != GLYPHMEM_H-1) glyph_y <= glyph_y + 1; - end else if (cursor_movement_y_neg) begin - if (glyph_y != 0) glyph_y <= glyph_y - 1; - end - end - - if (num_buf_last == 0 || ~num_buf_last == 12'h001 || csi_act_ctr == ~num_buf_last) begin - if (cursor_movement_x_pos && cursor_movement_y_pos) begin - num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000}; - cursor_movement_x_pos <= 0; - end else begin - parser_valid <= 0; - end - end - - end else if (parser_action == 8'h41 && !esc_inval) begin /* A; Cursor up */ - cursor_movement_y_neg <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h42 && !esc_inval) begin /* B; Cursor down */ - cursor_movement_y_pos <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h43 && !esc_inval) begin /* C; Cursor forward */ - cursor_movement_x_pos <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h44 && !esc_inval) begin /* D; Cursor back */ - cursor_movement_x_neg <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h45 && !esc_inval) begin /* E; Cursor next line */ - glyph_x <= 0; - cursor_movement_y_pos <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h46 && !esc_inval) begin /* F: Cursor previous line */ - glyph_x <= 0; - cursor_movement_y_neg <= 1; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - - end else if (parser_action == 8'h47 && !esc_inval) begin /* G: Cursor horizontal absolute */ - glyph_x <= 0; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] <= num_buf[11:0]; - if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin - cursor_movement_x_pos <= 1; - end else begin - parser_valid <= 0; - end - - end else if (parser_action == 8'h48 && !esc_inval) begin /* H: Cursor x/y absolute */ - glyph_x <= 0; - glyph_y <= 0; - num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-24] <= num_buf[23:0]; - if (num_buf[NUM_BUF_SZ*12-1:NUM_BUF_SZ*12-12] != 0) begin - cursor_movement_x_pos <= 1; - cursor_movement_y_pos <= 1; - end else begin - parser_valid <= 0; - end - - end else if (parser_action == 8'h6d && !esc_inval) begin /* m; CSI SGR */ - if (num_buf_idx == NUM_BUF_SZ-1) begin - parser_valid <= 0; - end - - case (~num_buf_last) - (12'h000): begin /* reset */ - cur_fg <= 7; - cur_bg <= 0; - cur_bold <= 0; - cur_underline <= 0; - end - (12'h001): begin /* bold */ - cur_bold <= 1; - end - (12'h004): begin /* underlined */ - cur_underline <= 1; - end - (12'h007): begin /* reverse video */ - cur_fg = cur_bg; - cur_bg = cur_fg; - end - (12'h022): begin /* not bold */ - cur_bold <= 0; - end - (12'h024): begin /* not underlined */ - cur_underline <= 0; - end - - (12'h030): cur_fg <= 0; - (12'h031): cur_fg <= 1; - (12'h032): cur_fg <= 2; - (12'h033): cur_fg <= 3; - (12'h034): cur_fg <= 4; - (12'h035): cur_fg <= 5; - (12'h036): cur_fg <= 6; - (12'h037): cur_fg <= 7; - (12'h038): esc_inval <= 1; - (12'h039): cur_fg <= 7; - - (12'h040): cur_bg <= 0; - (12'h041): cur_bg <= 1; - (12'h042): cur_bg <= 2; - (12'h043): cur_bg <= 3; - (12'h044): cur_bg <= 4; - (12'h045): cur_bg <= 5; - (12'h046): cur_bg <= 6; - (12'h047): cur_bg <= 7; - (12'h048): esc_inval <= 1; - (12'h049): cur_bg <= 0; - - (12'h090): cur_fg <= 8; - (12'h091): cur_fg <= 9; - (12'h092): cur_fg <= 10; - (12'h093): cur_fg <= 11; - (12'h094): cur_fg <= 12; - (12'h095): cur_fg <= 13; - (12'h096): cur_fg <= 14; - (12'h097): cur_fg <= 15; - - (12'h100): cur_bg <= 8; - (12'h101): cur_bg <= 9; - (12'h102): cur_bg <= 10; - (12'h103): cur_bg <= 11; - (12'h104): cur_bg <= 12; - (12'h105): cur_bg <= 13; - (12'h106): cur_bg <= 14; - (12'h107): cur_bg <= 15; - /* (12'hfff): ignore! */ - endcase - - num_buf_idx <= num_buf_idx + 1; - num_buf <= {num_buf[NUM_BUF_SZ*12-1-12:0], 12'h000}; - - end else begin - parser_valid <= 0; - end - end - end -end - endmodule \ No newline at end of file diff --git a/src/top.v b/src/top.v new file mode 100644 index 0000000..2cb67c8 --- /dev/null +++ b/src/top.v @@ -0,0 +1,327 @@ + +module proc_top( + input clk, + + input sck, sdi, ncs, + output sdo, + + input in_blank, in_hsync, in_vsync, + input [7:0] in_red, + input [7:0] in_green, + input [7:0] in_blue, + input is_interlaced, is_second_field, + + output out_blank, out_hsync, out_vsync, + output [7:0] out_red, + output [7:0] out_green, + output [7:0] out_blue, + + input [7:0] switches +); + +/* ================= */ +/* DEBUG DEBUG DEBUG */ +/* ================= */ + +/* Color bar generator */ + +parameter CB_HRES = 1280; +parameter CB_VRES = 768; +parameter CB_H_FP = 64; +parameter CB_H_BP = 192; +parameter CB_V_FP = 3; +parameter CB_V_BP = 20; + +reg [11:0] cb_x = 0; +reg [11:0] cb_y = 0; +reg [11:0] cb_cnt = 0; +reg [5:0] cb_bar = 0; + +reg cb_hsync = 0, cb_vsync = 0, cb_blank = 1, cb_vactive = 0; +reg [7:0] cb_red; +reg [7:0] cb_green; +reg [7:0] cb_blue; + +assign out_hsync = cb_hsync; +assign out_vsync = cb_vsync; +assign out_blank = cb_blank; +assign out_red = cb_red; +assign out_green = cb_green; +assign out_blue = cb_blue; + +always @(posedge clk) begin + cb_x <= cb_x + 1; + + if (cb_x == 12'h003) begin + cb_hsync <= 1; + end else if (cb_x == 12'h010) begin + cb_hsync <= 0; + end + + if (cb_x == CB_H_FP + CB_HRES + CB_H_BP - 1) begin + cb_x <= 0; + cb_y <= cb_y + 1; + + cb_vsync <= (cb_y == 2) || (cb_y == 3); + + if (cb_y == CB_V_FP - 1) begin + cb_vactive <= 1; + + end else if (cb_y == CB_V_FP + CB_VRES - 1) begin + cb_vactive <= 0; + + end else if (cb_y == CB_V_FP + CB_VRES + CB_V_BP - 1) begin + cb_y <= 0; + end + + end else if (cb_vactive && (cb_x == CB_H_FP - 1)) begin + cb_red <= 0; + cb_green <= 0; + cb_blue <= 0; + cb_blank <= 0; + cb_cnt <= 0; + cb_bar <= 0; + + end else if (cb_vactive && (cb_x == CB_H_FP + CB_HRES - 1)) begin + cb_blank <= 1; + + end + + if (!cb_blank) begin + cb_cnt <= cb_cnt + 1; + + if (cb_cnt == 255) begin + cb_cnt <= 0; + cb_bar <= cb_bar + 1; + + if (cb_bar == 7) begin + cb_bar <= 0; + end + + cb_red <= {8{cb_bar[0]}}; + cb_green <= {8{cb_bar[1]}}; + cb_blue <= {8{cb_bar[2]}}; + end + + end +end + +/* ================= */ +/* END DEBUG END */ +/* ================= */ + +parameter GLYPHMEM_W = 256; /* glyphs */ +parameter GLYPHMEM_H = 128; /* glyphs */ +parameter PAYLOAD_BUF_SIZE = 16384; + +reg rst = 0; +reg [3:0] rst_cnt = 0; + +always @(posedge clk) begin + if (rst_cnt != 0) begin + rst <= 1; + end + + if (rst_cnt != 4'hf) begin + rst_cnt <= rst_cnt + 1; + end else begin + rst <= 0; + end +end + +reg input_idle = 0; +reg [19:0] idle_cnt = 0; +always @(posedge clk) begin + if (in_vsync) begin + idle_cnt <= 0; + input_idle <= 0; + + end else begin + if (idle_cnt == 20'hfffff) begin + input_idle <= 1; + + end else begin + idle_cnt <= idle_cnt + 1; + end + end +end + +/* Switches */ +wire bypass = switches[0]; + +/* spi interface */ +reg [7:0] spi_data_in; +wire [7:0] spi_data_out; +wire win_locked; +wire [7:0] spi_status_word = {5'h00, bypass, win_locked, input_idle}; +wire [7:0] spi_cmd_word; +wire spi_cmd_begin, spi_cmd_active, spi_cmd_step; +wire [19:0] spi_cmd_idx; + +/* term emu */ +wire temu_in_valid = (spi_cmd_word == 8'h23) && spi_cmd_step; +wire glyph_buffer_w_valid; +wire [15:0] glyph_buffer_w_addr; +wire [19:0] glyph_buffer_w_data; + +/* matcher */ +wire win_hsync; +wire win_vsync; +wire win_blank; +wire [11:0] win_w; +wire [11:0] win_h; +wire out_data_en; +wire out_data_valid; +wire [23:0] out_data; + +/* term renderer */ +wire [7:0] win_red; +wire [7:0] win_green; +wire [7:0] win_blue; + +/* spi read index logic */ +reg [15:0] spi_payload_r_idx; +reg [1:0] spi_payload_byte; +always @(posedge clk) begin + if (spi_cmd_begin) begin + spi_payload_r_idx <= 0; + spi_payload_byte <= 0; + end else if (spi_cmd_step) begin + if (spi_payload_byte == 2) begin + spi_payload_r_idx <= spi_payload_r_idx + 1; + spi_payload_byte <= 0; + + end else begin + spi_payload_byte <= spi_payload_byte + 1; + end + end +end + +/* payload buffer access logic */ +reg [23:0] payload_buf [0:PAYLOAD_BUF_SIZE-1]; +reg out_data_en_last; +reg [15:0] payload_w_idx; +reg [23:0] payload_r_data; +always @(posedge clk) begin + out_data_en_last <= out_data_en; + + if (!out_data_en) begin + payload_w_idx <= 0; + end + + if (out_data_valid) begin + payload_buf[payload_w_idx] <= out_data; + payload_w_idx <= payload_w_idx + 1; + end + + payload_r_data <= payload_buf[spi_payload_r_idx]; +end + +/* SPI read payload memory access logic */ +always @(posedge clk) begin + if (spi_cmd_active && (spi_cmd_word == 8'h22)) begin + case (spi_payload_byte) + 0: spi_data_in <= payload_r_data[23:16]; + 1: spi_data_in <= payload_r_data[15:8]; + default: spi_data_in <= payload_r_data[7:0]; + endcase + end +end + +/* glyph memory logic */ +reg [19:0] glyphmem [0:GLYPHMEM_W*GLYPHMEM_H-1]; +reg [19:0] glyphmem_r_data; +always @(posedge clk) begin + if (glyph_buffer_w_valid) begin + glyphmem[glyph_buffer_w_addr] <= glyph_buffer_w_data; + end + + glyphmem_r_data <= glyphmem[glyphmem_r_addr]; +end + +spi_regfile spi_regfile_dut ( + .clk(clk), .rst(rst), + + .sck(sck), .sdi(sdi), .sdo(sdo), .ncs(ncs), + + .spi_data_in(spi_data_in), + .spi_data_out(spi_data_out), + + .spi_status_word(spi_status_word), + .spi_cmd_word(spi_cmd_word), + .spi_cmd_begin(spi_cmd_begin), + .spi_cmd_active(spi_cmd_active), + .spi_cmd_step(spi_cmd_step), + .spi_cmd_idx(spi_cmd_idx) +); + +term_emu #( + .GLYPHMEM_W(GLYPHMEM_W), + .GLYPHMEM_H(GLYPHMEM_H) +) term_emu_i ( + .clk(clk), .rst(rst), + + .in_byte_valid(temu_in_valid), + .in_byte(spi_data_out), + .in_byte_ack(), + + .glyph_buffer_w_valid(glyph_buffer_w_valid), + .glyph_buffer_w_addr(glyph_buffer_w_addr), + .glyph_buffer_w_data(glyph_buffer_w_data) +); + +term_renderer #( + .GLYPHMEM_W(GLYPHMEM_W), + .GLYPHMEM_H(GLYPHMEM_H) + ) term_renderer_i ( + .rst(rst), + .clk(clk), + + .in_vsync(win_vsync), + .in_hsync(win_hsync), + + .glyphmem_data(glyphmem_r_data), + .glyphmem_r_addr(glyphmem_r_addr), + + .out_red(win_red), + .out_green(win_green), + .out_blue(win_blue) +); + +window_matcher window_matcher_i ( + .clk(clk), + .rst(rst), + + .bypass(bypass), + + .in_blank(in_blank), + .in_hsync(in_hsync), + .in_vsync(in_vsync), + .in_red(in_red), + .in_green(in_green), + .in_blue(in_blue), + + .win_hsync(win_hsync), + .win_vsync(win_vsync), + .win_blank(win_blank), + .win_locked(win_locked), + .win_w(win_w), + .win_h(win_h), + + .out_data_en(out_data_en), + .out_data_valid(out_data_valid), + .out_data(out_data), + + .win_red(win_red), + .win_green(win_green), + .win_blue(win_blue), + + .out_blank(), // out_blank), + .out_hsync(), //out_hsync), + .out_vsync(), //out_vsync), + .out_red(), //out_red), + .out_green(), //out_green), + .out_blue() //out_blue) + ); + +endmodule \ No newline at end of file diff --git a/src/window_matcher.v b/src/window_matcher.v index 956c057..59f052d 100644 --- a/src/window_matcher.v +++ b/src/window_matcher.v @@ -24,6 +24,8 @@ module window_matcher( /* Pixel clock and synchronous, active-high reset */ input clk, rst, + input bypass, + /* Input pixel bus */ input in_blank, in_hsync, in_vsync, input [7:0] in_red, [7:0] in_green, [7:0] in_blue, @@ -106,44 +108,98 @@ module window_matcher( ST_MAT_DATA = 6'b100000; reg [5:0] matcher_state; wire matched = matcher_state[5]; + + /* Window sync generator */ + reg [11:0] win_hsync_ctr_int; + reg [11:0] win_vsync_ctr_int; + always @(posedge clk) begin - if (rst == 1 || in_vsync == 0) begin + if (rst == 1) begin + win_hsync_int <= 0; + win_vsync_int <= 0; + win_hsync_ctr_int <= 0; + win_vsync_ctr_int <= 0; + out_data_valid <= 0; + + end + + if (rst == 1 || !in_vsync) begin matcher_state <= ST_MAT_WAITING; win_w_int <= 0; win_h_int <= 0; - end else begin - case (matcher_state) - ST_MAT_WAITING: begin - if (in_pxd_pattern_match) begin - matcher_state <= ST_MAT_RX0; - win_x_int <= scan_x_reg[2]; - win_y_int <= scan_y; + end + + if (!rst) begin + if (in_vsync) begin + case (matcher_state) + ST_MAT_WAITING: begin + if (in_pxd_pattern_match) begin + matcher_state <= ST_MAT_RX0; + win_x_int <= scan_x_reg[2]; + win_y_int <= scan_y; + end + end + ST_MAT_RX0: begin + matcher_state <= ST_MAT_RX1; + end + ST_MAT_RX1: begin + matcher_state <= ST_MAT_RX2; + end + ST_MAT_RX2: begin + matcher_state <= ST_MAT_RX3; + win_w_int <= in_pxd; + end + ST_MAT_RX3: begin + matcher_state <= ST_MAT_MATCHED; + win_h_int <= in_pxd; + end + ST_MAT_MATCHED: begin + matcher_state <= ST_MAT_DATA; + win_hsync_int <= 1; + out_data_valid <= 1; + win_vsync_int <= 1; + win_hsync_ctr_int <= 9; + win_vsync_ctr_int <= 0; + end + endcase + end + + if (matcher_state == ST_MAT_DATA) begin + /* hsync */ + if (scan_x == win_x_int && win_vsync_int == 1) begin + win_hsync_int <= 1; + win_hsync_ctr_int <= 1; + out_data_valid <= 1; + end + + if (win_hsync_int == 1) begin + win_hsync_ctr_int <= win_hsync_ctr_int + 1; + end + + if (win_hsync_ctr_int == win_w_int || in_hsync_reg == 0) begin + win_hsync_int <= 0; + out_data_valid <= 0; + win_hsync_ctr_int <= 0; + end + + if (in_hsync_reg == 1 && in_hsync == 0) begin + if (scan_y == win_y_int) begin + win_vsync_int <= 1; + win_vsync_ctr_int <= 0; + end + + win_vsync_ctr_int <= win_vsync_ctr_int + 1; + end + + if (win_vsync_ctr_int == win_h_int) begin + win_vsync_int <= 0; + end + + if (in_vsync_reg == 1 && in_vsync == 0) begin + win_vsync_ctr_int <= 0; end end - ST_MAT_RX0: begin - matcher_state <= ST_MAT_RX1; - end - ST_MAT_RX1: begin - matcher_state <= ST_MAT_RX2; - end - ST_MAT_RX2: begin - matcher_state <= ST_MAT_RX3; - win_w_int <= in_pxd; - end - ST_MAT_RX3: begin - matcher_state <= ST_MAT_MATCHED; - win_h_int <= in_pxd; - end - ST_MAT_MATCHED: begin - matcher_state <= ST_MAT_DATA; - win_hsync_int <= 1; - out_data_valid <= 1; - win_vsync_int <= 1; - win_hsync_ctr_int <= 9; - win_vsync_ctr_int <= 0; - end - endcase end end @@ -232,56 +288,6 @@ module window_matcher( end end - /* Window sync generator */ - reg [11:0] win_hsync_ctr_int; - reg [11:0] win_vsync_ctr_int; - - always @(posedge clk) begin - if (rst == 1) begin - win_hsync_int <= 0; - win_vsync_int <= 0; - win_hsync_ctr_int <= 0; - win_vsync_ctr_int <= 0; - out_data_valid <= 0; - - end else begin - if (matcher_state == ST_MAT_DATA) begin - /* hsync */ - if (scan_x == win_x_int && win_vsync_int == 1) begin - win_hsync_int <= 1; - win_hsync_ctr_int <= 1; - out_data_valid <= 1; - end - - if (win_hsync_int == 1) begin - win_hsync_ctr_int <= win_hsync_ctr_int + 1; - end - - if (win_hsync_ctr_int == win_w_int || in_hsync_reg == 0) begin - win_hsync_int <= 0; - out_data_valid <= 0; - win_hsync_ctr_int <= 0; - end - - if (in_hsync_reg == 1 && in_hsync == 0) begin - if (scan_y == win_y_int) begin - win_vsync_int <= 1; - win_vsync_ctr_int <= 0; - end - - win_vsync_ctr_int <= win_vsync_ctr_int + 1; - end - - if (win_vsync_ctr_int == win_h_int) begin - win_vsync_int <= 0; - end - - if (in_vsync_reg == 1 && in_vsync == 0) begin - win_vsync_ctr_int <= 0; - end - end - end - end /* Window H/VSYNC outputs */ reg [11:0] win_hsync_ctr; @@ -339,5 +345,5 @@ module window_matcher( assign out_data = out_data_en ? in_pxd_last : 0; /* Compositor */ - assign out_pxd = (win_hsync_int) ? in_pxd_reg : win_pxd; + assign out_pxd = (win_hsync_int && !bypass) ? win_pxd : in_pxd_reg; endmodule diff --git a/test_bench/spi_regfile_tb.v b/test_bench/spi_regfile_tb.v index dc17923..f578667 100644 --- a/test_bench/spi_regfile_tb.v +++ b/test_bench/spi_regfile_tb.v @@ -3,7 +3,7 @@ module spi_regfile_tb(); localparam period = 10; -parameter WORDSIZE = 16; +parameter WORDSIZE = 8; reg clk, rst; reg sck, sdi, ncs; diff --git a/test_bench/window_matcher_tb.v b/test_bench/window_matcher_tb.v index 4a20ba3..383b89b 100644 --- a/test_bench/window_matcher_tb.v +++ b/test_bench/window_matcher_tb.v @@ -78,6 +78,8 @@ module window_matcher_tb(); window_matcher window_matcher_i ( .clk(clk), .rst(rst), + + .bypass(1'b0), .in_blank(in_blank), .in_hsync(in_hsync),