tachibana/src/top.v

370 lines
No EOL
7.6 KiB
Verilog

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,
output [5:0] debug,
input [7:0] switches
);
/* ================= */
/* DEBUG DEBUG DEBUG */
/* ================= */
/* Color bar generator */
/*
parameter CB_HRES = 1280;
parameter CB_VRES = 720;
parameter CB_H_FP = 68;
parameter CB_H_BP = 300;
parameter CB_V_FP = 25;
parameter CB_V_BP = 5;
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_hsync <= in_hsync;
//cb_vsync <= in_vsync;
//cb_blank <= in_blank;
//cb_red <= in_red;
//cb_green <= in_green;
//cb_blue <= in_blue;
cb_x <= cb_x + 1;
cb_hsync <= cb_x >= 8 && cb_x <= 15;
cb_vsync <= cb_y >= 4 && cb_y <= 7;
if (cb_x == CB_H_FP + CB_HRES + CB_H_BP - 1) begin
cb_x <= 0;
cb_y <= cb_y + 1;
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;
end else if (cb_vactive && (cb_x == CB_H_FP + CB_HRES - 1)) begin
cb_blank <= 1;
cb_cnt <= 0;
cb_bar <= 0;
end
if (!cb_blank) begin
cb_cnt <= cb_cnt + 1;
if (cb_cnt == 127) begin
cb_cnt <= 0;
cb_bar <= cb_bar + 1;
if (cb_bar == 7) begin
cb_bar <= 0;
end
end
end
if (cb_y < CB_V_FP + 30 || cb_y > CB_V_FP + CB_VRES - 30) begin
cb_red <= {8{cb_bar[0]}};
cb_green <= {8{cb_bar[1]}};
cb_blue <= {8{cb_bar[2]}};
end else begin
cb_red <= in_red;
cb_green <= in_green;
cb_blue <= in_blue;
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_blank;
wire [11:0] win_w;
wire [11:0] win_h;
wire out_data_en;
wire out_data_valid;
wire [23:0] out_data;
wire [7:0] matcher_debug;
assign debug = {matcher_debug[3:2], win_blank, win_locked, out_data_en, out_data_valid};
/* 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(in_vsync),
.in_hsync(in_hsync),
.glyphmem_data(glyphmem_r_data),
.glyphmem_r_addr(glyphmem_r_addr),
.out_red(win_red),
.out_green(win_green),
.out_blue(win_blue)
);
wire [11:0] win_x_dbg;
wire [11:0] win_y_dbg;
wire [11:0] win_w_dbg;
wire [11:0] win_h_dbg;
window_matcher window_matcher_i (
.clk(clk),
.rst(rst),
.bypass(bypass),
.debug(matcher_debug),
.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_blank(win_blank),
.win_locked(win_locked),
.win_w(win_w),
.win_h(win_h),
.win_x_dbg(win_x_dbg),
.win_y_dbg(win_y_dbg),
.win_w_dbg(win_w_dbg),
.win_h_dbg(win_h_dbg),
.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)
);
ila_0 i_ila_0 (
.clk(clk),
.probe0(win_x_dbg),
.probe1(win_y_dbg),
.probe2(win_w_dbg),
.probe3(win_h_dbg),
.probe4({in_red, in_green, in_blue}),
.probe5(in_blank),
.probe6(in_hsync),
.probe7(in_vsync),
.probe8(1'b0),
.probe9(1'b0),
.probe10(win_blank),
.probe11(win_locked),
.probe12(out_data_en),
.probe13(out_data_valid),
.probe14(out_hsync),
.probe15(out_vsync)
);
endmodule