USTC-RVSoC/RTL/video_ram.sv
WangXuan95 ceda0f04c3 update
2022-04-08 14:24:46 +08:00

86 lines
2.6 KiB
Systemverilog

module video_ram #(
parameter VGA_CLK_DIV = 1
)(
input logic clk, rstn,
output logic o_hsync, o_vsync,
output logic o_red, o_green, o_blue,
naive_bus.slave bus
);
logic vga_req;
logic [ 9:0] vga_addr_h;
logic [ 1:0] vga_addr_l, vga_addr_l_latch = 2'b00;
logic [ 7:0] vga_ascii;
logic [ 9:0] cell_wr_addr, cell_rd_addr;
logic [ 7:0] vga_rdata [4];
assign bus.rd_gnt = (~vga_req) & bus.rd_req;
assign bus.wr_gnt = bus.wr_req;
assign bus.rd_data = {vga_rdata[3],vga_rdata[2],vga_rdata[1],vga_rdata[0]};
assign cell_wr_addr = bus.wr_addr[11:2];
assign cell_rd_addr = vga_req ? vga_addr_h : bus.rd_addr[11:2];
always @ (posedge clk or negedge rstn)
if(~rstn)
vga_addr_l_latch <= 2'b00;
else
vga_addr_l_latch <= vga_addr_l;
ram ram_i0(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[0] ),
.i_waddr ( cell_wr_addr ),
.i_wdata ( bus.wr_data[ 7: 0] ),
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[0] )
);
ram ram_i1(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[1] ),
.i_waddr ( cell_wr_addr ),
.i_wdata ( bus.wr_data[15: 8] ),
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[1] )
);
ram ram_i2(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[2] ),
.i_waddr ( cell_wr_addr ),
.i_wdata ( bus.wr_data[23:16] ),
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[2] )
);
ram ram_i3(
.clk ( clk ),
.i_we ( bus.wr_req & bus.wr_be[3] ),
.i_waddr ( cell_wr_addr ),
.i_wdata ( bus.wr_data[31:24] ),
.i_raddr ( cell_rd_addr ),
.o_rdata ( vga_rdata[3] )
);
always_comb
case(vga_addr_l_latch)
2'b00 : vga_ascii <= vga_rdata[0];
2'b01 : vga_ascii <= vga_rdata[1];
2'b10 : vga_ascii <= vga_rdata[2];
2'b11 : vga_ascii <= vga_rdata[3];
endcase
vga_char_86x32 #(
.VGA_CLK_DIV ( VGA_CLK_DIV )
) vga_char_86x32_i (
.clk ( clk ),
.hsync ( o_hsync ),
.vsync ( o_vsync ),
.red ( o_red ),
.green ( o_green ),
.blue ( o_blue ),
.req ( vga_req ),
.addr ( {vga_addr_h,vga_addr_l} ),
.ascii ( vga_ascii )
);
endmodule