mirror of
https://github.com/alangarf/apple-one.git
synced 2024-05-31 22:41:28 +00:00
Initial VGA working with the apple one output. YAY!
This commit is contained in:
parent
451bff1592
commit
2432225d01
|
@ -52,6 +52,7 @@ $(BUILDDIR)/apple1.blif: $(SOURCEDIR)/apple1.v \
|
|||
$(SOURCEDIR)/uart/uart.v \
|
||||
$(SOURCEDIR)/uart/async_tx_rx.v \
|
||||
$(SOURCEDIR)/vga/vga.v \
|
||||
$(SOURCEDIR)/vga/vram.v \
|
||||
$(SOURCEDIR)/ps2keyboard/ps2keyboard.v \
|
||||
$(SOURCEDIR)/boards/ice40hx8k/clock_pll.v \
|
||||
$(SOURCEDIR)/boards/ice40hx8k/apple1_hx8k.v
|
||||
|
|
|
@ -1,20 +1,3 @@
|
|||
000000
|
||||
000001
|
||||
000010
|
||||
000011
|
||||
000100
|
||||
000101
|
||||
000110
|
||||
000111
|
||||
001000
|
||||
001001
|
||||
001010
|
||||
001011
|
||||
001100
|
||||
001101
|
||||
001110
|
||||
001111
|
||||
010000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -78,15 +61,7 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
000001
|
||||
010000
|
||||
010000
|
||||
001100
|
||||
000101
|
||||
100000
|
||||
001111
|
||||
001110
|
||||
000101
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -118,10 +93,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
010110
|
||||
000111
|
||||
000001
|
||||
100001
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -158,13 +129,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
110110
|
||||
110100
|
||||
110000
|
||||
011000
|
||||
110100
|
||||
111000
|
||||
110000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -198,7 +162,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -238,7 +201,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -278,7 +240,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -318,7 +279,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -358,7 +318,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -398,7 +357,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -438,7 +396,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -478,7 +435,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -518,7 +474,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -558,7 +513,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -598,7 +552,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -638,7 +591,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -678,7 +630,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -718,7 +669,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -758,7 +708,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -798,7 +747,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -838,7 +786,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -878,7 +825,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -918,7 +864,6 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
101110
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
@ -954,7 +899,62 @@
|
|||
100000
|
||||
100000
|
||||
100000
|
||||
000100
|
||||
000011
|
||||
000010
|
||||
000001
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
100000
|
||||
|
|
45
rtl/apple1.v
45
rtl/apple1.v
|
@ -36,6 +36,7 @@ module apple1(
|
|||
input ps2_din, // PS/2 keyboard serial data input
|
||||
|
||||
// Outputs to VGA display
|
||||
input clr_screen_btn, // active high clear screen button
|
||||
output vga_h_sync, // hozizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output reg vga_red, // red VGA signal
|
||||
|
@ -57,10 +58,12 @@ module apple1(
|
|||
// Clocks
|
||||
|
||||
wire cpu_clken;
|
||||
wire blink_clken;
|
||||
clock my_clock(
|
||||
.clk25(clk25),
|
||||
.rst_n(rst_n),
|
||||
.cpu_clken(cpu_clken)
|
||||
.cpu_clken(cpu_clken),
|
||||
.blink_clken(blink_clken)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
@ -87,20 +90,29 @@ module apple1(
|
|||
.we (we),
|
||||
.irq_n (1'b1),
|
||||
.nmi_n (1'b1),
|
||||
.ready (cpu_clken),
|
||||
.pc_monitor (pc_monitor)
|
||||
.ready (cpu_clken)
|
||||
//.pc_monitor (pc_monitor)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// Address Decoding
|
||||
|
||||
wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF
|
||||
wire ram_cs = (ab[15:13] == 3'b000); // 0x0000 -> 0x1FFF
|
||||
|
||||
wire uart_cs = (ab[15:2] == 14'b11010000000100); // 0xD010 -> 0xD013
|
||||
wire ps2kb_cs = 1'b0;
|
||||
//wire uart_cs = (ab[15:1] == 15'b110100000001001); // 0xD012 -> 0xD013
|
||||
//wire ps2kb_cs = 1'b0;
|
||||
//wire vga_cs = 1'b0;
|
||||
|
||||
//wire ps2kb_cs = (ab[15:1] == 15'b110100000001000); // 0xD010 -> 0xD011
|
||||
wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF
|
||||
//wire uart_cs = (ab[15:1] == 15'b110100000001001); // 0xD012 -> 0xD013
|
||||
//wire vga_cs = 1'b0;
|
||||
|
||||
//wire uart_cs = (ab[15:1] == 15'b110100000001000); // 0xD010 -> 0xD011
|
||||
wire ps2kb_cs = 1'b0;
|
||||
wire vga_cs = (ab[15:1] == 15'b110100000001001); // 0xD012 -> 0xD013
|
||||
|
||||
wire basic_cs = (ab[15:12] == 4'b1110); // 0xE000 -> 0xEFFF
|
||||
wire rom_cs = (ab[15:8] == 8'b11111111); // 0xFF00 -> 0xFFFF
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// RAM and ROM
|
||||
|
@ -152,7 +164,8 @@ module apple1(
|
|||
.uart_cts(uart_cts),
|
||||
|
||||
//.address({1'b1, ab[0]}), // for ps/2
|
||||
.address(ab[1:0]),
|
||||
//.address({1'b0, ab[0]}), // for vga
|
||||
.address(ab[1:0]), // for uart
|
||||
.w_en(we & uart_cs),
|
||||
.din(dbo),
|
||||
.dout(uart_dout)
|
||||
|
@ -173,13 +186,21 @@ module apple1(
|
|||
// VGA Display interface
|
||||
vga my_vga(
|
||||
.clk25(clk25),
|
||||
.in(),
|
||||
.in_stb(),
|
||||
.enable(vga_cs & cpu_clken),
|
||||
.rst(rst),
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
.vga_grn(vga_grn),
|
||||
.vga_blu(vga_blu)
|
||||
.vga_blu(vga_blu),
|
||||
|
||||
.address(ab[0]),
|
||||
.w_en(we & vga_cs),
|
||||
.din(dbo),
|
||||
|
||||
.clr_screen_btn(clr_screen_btn),
|
||||
.blink_clken(blink_clken),
|
||||
.debug(pc_monitor)
|
||||
);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -66,6 +66,7 @@ module apple1_top(
|
|||
.uart_rx(uart_rx),
|
||||
.uart_tx(uart_tx),
|
||||
.uart_cts(uart_cts),
|
||||
.clr_screen_btn(button[1]),
|
||||
.vga_h_sync(vga_h_sync),
|
||||
.vga_v_sync(vga_v_sync),
|
||||
.vga_red(vga_red),
|
||||
|
|
19
rtl/clock.v
19
rtl/clock.v
|
@ -28,7 +28,8 @@ module clock(
|
|||
input rst_n, // active low synchronous reset
|
||||
|
||||
// Clock enables
|
||||
output reg cpu_clken // 1MHz clock enable for the CPU and devices
|
||||
output reg cpu_clken, // 1MHz clock enable for the CPU and devices
|
||||
output reg blink_clken // 1Hz clock enable for cursor blink
|
||||
);
|
||||
|
||||
// generate clock enable once every
|
||||
|
@ -69,4 +70,20 @@ module clock(
|
|||
end
|
||||
`endif
|
||||
|
||||
reg [20:0] bclk_div;
|
||||
always @(posedge clk25)
|
||||
begin
|
||||
// note: bclk_div should be compared to
|
||||
// N-1, where N is the clock divisor
|
||||
if (cpu_clken)
|
||||
begin
|
||||
if ((bclk_div == 500000) || (rst_n == 1'b0))
|
||||
bclk_div <= 0;
|
||||
else
|
||||
bclk_div <= bclk_div + 1'b1;
|
||||
|
||||
blink_clken <= (bclk_div[20:0] == 0);
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -136,7 +136,7 @@ module uart(
|
|||
`ifdef SIM
|
||||
if ((din & 8'h7f) >= 32)
|
||||
$write("%c", din & 8'h7f);
|
||||
`endif
|
||||
`endif
|
||||
|
||||
uart_tx_byte <= {1'b0, din[6:0]};
|
||||
uart_tx_stb <= 1;
|
||||
|
|
249
rtl/vga/vga.v
249
rtl/vga/vga.v
|
@ -1,21 +1,42 @@
|
|||
module vga(
|
||||
input clk25,
|
||||
input [6:0] in,
|
||||
input in_stb,
|
||||
output vga_h_sync,
|
||||
output vga_v_sync,
|
||||
output vga_red,
|
||||
output vga_grn,
|
||||
output vga_blu
|
||||
input clk25, // clock signal
|
||||
input enable, // clock enable strobe,
|
||||
input rst, // active high reset signal
|
||||
output vga_h_sync, // horizontal VGA sync pulse
|
||||
output vga_v_sync, // vertical VGA sync pulse
|
||||
output vga_red, // red VGA signal
|
||||
output vga_grn, // green VGA signal
|
||||
output vga_blu, // blue VGA signal
|
||||
input address, // address bus
|
||||
input w_en, // active high write enable strobe
|
||||
input [7:0] din, // 8-bit data bas (input)
|
||||
input clr_screen_btn, // active high clear screen button
|
||||
input blink_clken, // cursor blink enable strobe
|
||||
output [15:0] debug
|
||||
);
|
||||
|
||||
reg [5:0] v_ram[0:959] /* synthesis syn_ramstyle = "block_ram" */;
|
||||
|
||||
reg [4:0] c_rom[0:447] /* synthesis syn_ramstyle = "block_ram" */;
|
||||
initial begin
|
||||
$readmemb("../../roms/vga_vram.bin", v_ram, 0, 959);
|
||||
$readmemb("../../roms/vga_font.bin", c_rom, 0, 447);
|
||||
end
|
||||
|
||||
reg [9:0] vram_r_addr;
|
||||
reg [9:0] vram_w_addr;
|
||||
reg vram_r_en;
|
||||
reg vram_w_en;
|
||||
reg [5:0] vram_din;
|
||||
reg [5:0] vram_dout;
|
||||
|
||||
vram my_vram(
|
||||
.clk(clk25),
|
||||
.read_addr(vram_r_addr),
|
||||
.write_addr(vram_w_addr),
|
||||
.r_en(vram_r_en),
|
||||
.w_en(vram_w_en),
|
||||
.din(vram_din),
|
||||
.dout(vram_dout)
|
||||
);
|
||||
|
||||
// video structure constants
|
||||
parameter hpixels = 800; // horizontal pixels per line
|
||||
parameter vlines = 521; // vertical lines per frame
|
||||
|
@ -34,6 +55,9 @@ module vga(
|
|||
reg [3:0] hdot;
|
||||
reg [4:0] vdot;
|
||||
|
||||
reg [5:0] h_cursor;
|
||||
reg [4:0] v_cursor;
|
||||
|
||||
wire vga_h_act;
|
||||
wire vga_v_act;
|
||||
|
||||
|
@ -42,7 +66,7 @@ module vga(
|
|||
|
||||
assign vga_h_sync = (hc < hpulse) ? 0 : 1;
|
||||
assign vga_v_sync = (vc < vpulse) ? 0 : 1;
|
||||
// assign vblank = (vc >= vbp && vc < vfp) ? 0:1;
|
||||
//assign vblank = (vc >= vbp && vc < vfp) ? 0:1;
|
||||
|
||||
always @(posedge clk25)
|
||||
begin
|
||||
|
@ -87,6 +111,7 @@ module vga(
|
|||
end
|
||||
else
|
||||
begin
|
||||
// reset vertical counters
|
||||
vc <= 0;
|
||||
vdot <= 0;
|
||||
vpos <= 0;
|
||||
|
@ -99,64 +124,186 @@ module vga(
|
|||
assign vga_grn = out;
|
||||
assign vga_blu = out;
|
||||
|
||||
always @(posedge clk25)
|
||||
reg [8:0] cur_chr_offset;
|
||||
reg [9:0] v_pos_offset;
|
||||
reg [3:0] v_offset;
|
||||
reg [2:0] h_offset;
|
||||
reg blink;
|
||||
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
case ({vga_h_act, vga_v_act})
|
||||
default:
|
||||
if (rst)
|
||||
begin
|
||||
vram_r_addr = 10'd0;
|
||||
vram_r_en = 1'b0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
// get the current character from vram and build
|
||||
// offset to map into character ROM (5x7 font)
|
||||
if (blink && (hpos == h_cursor && vpos == v_cursor))
|
||||
cur_chr_offset = 9'd0; // the @ character
|
||||
else
|
||||
begin
|
||||
vram_r_en = 1'b1;
|
||||
v_pos_offset = (vpos * 40);
|
||||
vram_r_addr = (v_pos_offset + {4'b0, hpos});
|
||||
cur_chr_offset = (vram_dout * 7);
|
||||
|
||||
//cur_chr_offset <= (v_ram[hpos + (40 * vpos)] * 7);
|
||||
end
|
||||
|
||||
case ({vga_h_act, vga_v_act})
|
||||
default:
|
||||
// outside display area
|
||||
out = 1'b0;
|
||||
end
|
||||
|
||||
2'b11:
|
||||
2'b11:
|
||||
begin
|
||||
// inside display frame
|
||||
case (vdot)
|
||||
5'b00000,
|
||||
5'b00001,
|
||||
5'b00010,
|
||||
5'b00011,
|
||||
5'b10010,
|
||||
5'b10011:
|
||||
// blank row for spacing
|
||||
// we're inside the visible screen display frame
|
||||
//
|
||||
// scan doubling is achieved by ignoring bit 0 of both vdot
|
||||
// and hdot counters, in affect doubling the pixel size
|
||||
// (each pixel becomes screen pixels)
|
||||
case (vdot[4:1])
|
||||
4'b0000,
|
||||
4'b0001,
|
||||
4'b1001:
|
||||
begin
|
||||
// blank lines for spacing
|
||||
out = 1'b0;
|
||||
end
|
||||
|
||||
default:
|
||||
case (hdot)
|
||||
4'b0000,
|
||||
4'b0001,
|
||||
4'b1100,
|
||||
4'b1101,
|
||||
4'b1110,
|
||||
4'b1111:
|
||||
// blank column for spacing
|
||||
begin
|
||||
// work out character rom offset for current line
|
||||
// taking away 2 from counter to allow for the two
|
||||
// blank preceding lines
|
||||
v_offset = (vdot[4:1] - 2);
|
||||
|
||||
case (hdot[3:1])
|
||||
3'b000,
|
||||
3'b110,
|
||||
3'b111:
|
||||
begin
|
||||
// blank columns for spacing
|
||||
out = 1'b0;
|
||||
end
|
||||
|
||||
default:
|
||||
// into character pixels
|
||||
// TODO: fix this mess
|
||||
out = c_rom[(v_ram[hpos + (vpos * 40)] * 7) + (vdot[4:1] - 2)][5 - hdot[3:1]];
|
||||
begin
|
||||
// work out the character rom offset for the current
|
||||
// column. We reverse the dot pattern by subtracting
|
||||
// the column from the number of pixel in the
|
||||
// character row in rom
|
||||
h_offset = (5 - hdot[3:1]);
|
||||
|
||||
// grab the pixel from the character rom for
|
||||
// the given screen column and line
|
||||
out = c_rom[cur_chr_offset + {5'b0, v_offset}][h_offset];
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
end
|
||||
endcase
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
// FIXME: This is horrible
|
||||
reg [5:0] cur_pos;
|
||||
reg stb;
|
||||
always @(posedge clk25)
|
||||
begin
|
||||
if (in_stb & ~stb)
|
||||
begin
|
||||
v_ram[{4'b0, cur_pos}] <= {~in[6], in[4:0]};
|
||||
stb <= 1;
|
||||
cur_pos <= cur_pos + 1;
|
||||
end
|
||||
reg cls_flag, cls_running;
|
||||
reg char_seen;
|
||||
|
||||
if (~in_stb & stb)
|
||||
always @(posedge clk25 or posedge rst)
|
||||
begin
|
||||
if (rst)
|
||||
begin
|
||||
stb <= 0;
|
||||
blink <= 1'b1;
|
||||
h_cursor <= 6'd0;
|
||||
v_cursor <= 5'd0;
|
||||
char_seen <= 0;
|
||||
debug <= 0;
|
||||
cls_running <= 0;
|
||||
cls_flag <= 1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (cls_flag || clr_screen_btn)
|
||||
begin
|
||||
if ((vpos == 0) && (hpos == 0))
|
||||
cls_running <= 1;
|
||||
|
||||
if (cls_running)
|
||||
begin
|
||||
// clear the vram using the position pointers
|
||||
// very similar to the original apple 1 :)
|
||||
vram_w_addr <= ((vpos * 40) + {4'b0, hpos});
|
||||
vram_din <= 6'd0;
|
||||
vram_w_en <= 1;
|
||||
|
||||
if ((vpos == 23) && (hpos == 40))
|
||||
begin
|
||||
cls_running <= 0;
|
||||
end
|
||||
end
|
||||
else
|
||||
begin
|
||||
cls_flag <= 0;
|
||||
end
|
||||
end
|
||||
begin
|
||||
vram_w_en <= 0;
|
||||
|
||||
if (address == 1'b0) // address low == TX register
|
||||
begin
|
||||
if (enable & w_en & ~char_seen)
|
||||
begin
|
||||
// incoming character
|
||||
debug <= {8'd0, din};
|
||||
char_seen <= 1;
|
||||
|
||||
case(din)
|
||||
8'h8D:
|
||||
begin
|
||||
// handle carriage return
|
||||
h_cursor <= 0;
|
||||
v_cursor <= v_cursor + 1;
|
||||
end
|
||||
|
||||
8'h7F:
|
||||
// ignore the DDR call to the PIA
|
||||
h_cursor <= h_cursor + 1;
|
||||
|
||||
default:
|
||||
begin
|
||||
vram_w_addr <= ((v_cursor * 40) + {4'b0, h_cursor});
|
||||
vram_din <= {~din[6], din[4:0]};
|
||||
vram_w_en <= 1;
|
||||
|
||||
h_cursor <= h_cursor + 1;
|
||||
end
|
||||
endcase
|
||||
|
||||
if (h_cursor == 39)
|
||||
begin
|
||||
h_cursor <= 0;
|
||||
v_cursor <= v_cursor + 1;
|
||||
end
|
||||
|
||||
if (v_cursor == 23)
|
||||
begin
|
||||
// here we need to add the scroll, probably by moving the
|
||||
// HEAD of vram up one line
|
||||
v_cursor <= 0;
|
||||
end
|
||||
|
||||
end
|
||||
else if(~enable & ~w_en)
|
||||
char_seen <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
if (blink_clken)
|
||||
blink <= ~blink;
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
|
53
rtl/vga/vram.v
Normal file
53
rtl/vga/vram.v
Normal file
|
@ -0,0 +1,53 @@
|
|||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
// Description: Video RAM for system
|
||||
//
|
||||
// Author.....: Alan Garfield
|
||||
// Niels A. Moseley
|
||||
// Date.......: 26-1-2018
|
||||
//
|
||||
|
||||
module vram(
|
||||
input clk, // clock signal
|
||||
input [9:0] read_addr, // read address bus
|
||||
input [9:0] write_addr, // write address bus
|
||||
input r_en, // active high read enable strobe
|
||||
input w_en, // active high write enable strobe
|
||||
input [5:0] din, // 6-bit data bus (input)
|
||||
output reg [5:0] dout // 6-bit data bus (output)
|
||||
);
|
||||
|
||||
`ifdef SIM
|
||||
parameter RAM_FILENAME = "../roms/ram.hex";
|
||||
`else
|
||||
parameter RAM_FILENAME = "../../roms/vga_vram.bin";
|
||||
`endif
|
||||
|
||||
reg [5:0] ram_data[0:1023];
|
||||
|
||||
initial
|
||||
$readmemb(RAM_FILENAME, ram_data, 0, 1024);
|
||||
|
||||
always @(posedge clk)
|
||||
begin
|
||||
if (r_en) dout <= ram_data[read_addr];
|
||||
if (w_en) ram_data[write_addr] <= din;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user