1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-04 20:05:57 +00:00
8bitworkshop/presets/verilog/tile_renderer.v

127 lines
2.7 KiB
Verilog

`include "hvsync_generator.v"
`include "font_cp437_8x8.v"
`include "ram.v"
module tile_renderer(clk, reset, hpos, vpos, display_on,
rgb,
ram_addr, ram_read,
rom_addr, rom_data);
input clk, reset;
input [8:0] hpos;
input [8:0] vpos;
input display_on;
output [3:0] rgb;
output reg [15:0] ram_addr;
input [7:0] ram_read;
output [10:0] rom_addr;
input [7:0] rom_data;
reg [7:0] page_base = 0; // page table base (8 bits)
reg [15:0] row_base; // row table base (16 bits)
wire [4:0] row = vpos[7:3]; // 5-bit row, vpos / 8
wire [4:0] col = hpos[7:3]; // 5-bit column, hpos / 8
wire [2:0] yofs = vpos[2:0]; // scanline of cell (0-7)
wire [2:0] xofs = hpos[2:0]; // which pixel to draw (0-7)
reg [7:0] char;
reg [7:0] attr;
reg [7:0] next_char;
reg [7:0] next_attr;
// tile ROM address
assign rom_addr = {char, yofs};
// lookup char and attr
always @(posedge clk)
if (hpos[8]) begin
case (hpos[7:0])
// read row_base from page table (2 bytes)
// TODO: why 2 cycles?
0: ram_addr <= {page_base, row, 3'b000};
2: row_base[7:0] <= ram_read;
3: ram_addr <= {page_base, row, 3'b001};
5: row_base[15:8] <= ram_read;
endcase
end else begin
case (hpos[2:0])
0: ram_addr <= row_base + 16'(col);
2: next_char <= ram_read;
3: ram_addr <= row_base + 16'(col) + 32;
5: next_attr <= ram_read;
7: begin
char <= next_char;
attr <= next_attr;
end
endcase
end
// extract bit from ROM output
assign rgb = display_on
? (rom_data[~xofs] ? attr[3:0] : attr[7:4])
: 0;
endmodule
module test_tilerender_top(clk, reset, hsync, vsync, rgb);
input clk, reset;
output hsync, vsync;
output [3:0] rgb;
wire display_on;
wire [8:0] hpos;
wire [8:0] vpos;
reg [15:0] ram_addr;
wire [7:0] ram_read;
reg [7:0] ram_write = 0;
reg ram_writeenable = 0;
wire [10:0] rom_addr;
wire [7:0] rom_data;
hvsync_generator hvsync_gen(
.clk(clk),
.reset(reset),
.hsync(hsync),
.vsync(vsync),
.display_on(display_on),
.hpos(hpos),
.vpos(vpos)
);
// RAM
RAM #(16,8) ram(
.clk(clk),
.dout(ram_read),
.din(ram_write),
.addr(ram_addr),
.we(ram_writeenable)
);
tile_renderer tile_gen(
.clk(clk),
.reset(reset),
.hpos(hpos),
.vpos(vpos),
.display_on(display_on),
.ram_addr(ram_addr),
.ram_read(ram_read),
.rom_addr(rom_addr),
.rom_data(rom_data),
.rgb(rgb)
);
// tile ROM
font_cp437_8x8 tile_rom(
.addr(rom_addr),
.data(rom_data)
);
endmodule