mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-22 14:33:51 +00:00
verilog-vga
This commit is contained in:
parent
3ecaa57b9a
commit
e44a0734dd
@ -91,6 +91,8 @@ TODO:
|
|||||||
- Safari: scope doesn't show while CRT in use
|
- Safari: scope doesn't show while CRT in use
|
||||||
- recording video indicator
|
- recording video indicator
|
||||||
- verilog: support VGA/multisync monitor?
|
- verilog: support VGA/multisync monitor?
|
||||||
|
- stego shareable images (http://pico-8.wikia.com/wiki/P8PNGFileFormat)
|
||||||
|
- https://makecode.com/language?
|
||||||
|
|
||||||
|
|
||||||
WEB WORKER FORMAT
|
WEB WORKER FORMAT
|
||||||
|
69
presets/verilog-vga/hvsync_generator.v
Normal file
69
presets/verilog-vga/hvsync_generator.v
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
|
||||||
|
`ifndef HVSYNC_GENERATOR_H
|
||||||
|
`define HVSYNC_GENERATOR_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
Video sync generator, used to drive a simulated CRT.
|
||||||
|
To use:
|
||||||
|
- Wire the hsync and vsync signals to top level outputs
|
||||||
|
- Add a 3-bit (or more) "rgb" output to the top level
|
||||||
|
*/
|
||||||
|
|
||||||
|
module hvsync_generator(clk, reset, hsync, vsync, display_on, hpos, vpos);
|
||||||
|
|
||||||
|
input clk;
|
||||||
|
input reset;
|
||||||
|
output reg hsync, vsync;
|
||||||
|
output display_on;
|
||||||
|
output reg [8:0] hpos;
|
||||||
|
output reg [8:0] vpos;
|
||||||
|
|
||||||
|
// declarations for TV-simulator sync parameters
|
||||||
|
// horizontal constants
|
||||||
|
parameter H_DISPLAY = 256; // horizontal display width
|
||||||
|
parameter H_BACK = 23; // horizontal left border (back porch)
|
||||||
|
parameter H_FRONT = 7; // horizontal right border (front porch)
|
||||||
|
parameter H_SYNC = 23; // horizontal sync width
|
||||||
|
// vertical constants
|
||||||
|
parameter V_DISPLAY = 240; // vertical display height
|
||||||
|
parameter V_TOP = 5; // vertical top border
|
||||||
|
parameter V_BOTTOM = 14; // vertical bottom border
|
||||||
|
parameter V_SYNC = 3; // vertical sync # lines
|
||||||
|
// derived constants
|
||||||
|
parameter H_SYNC_START = H_DISPLAY + H_FRONT;
|
||||||
|
parameter H_SYNC_END = H_DISPLAY + H_FRONT + H_SYNC - 1;
|
||||||
|
parameter H_MAX = H_DISPLAY + H_BACK + H_FRONT + H_SYNC - 1;
|
||||||
|
parameter V_SYNC_START = V_DISPLAY + V_BOTTOM;
|
||||||
|
parameter V_SYNC_END = V_DISPLAY + V_BOTTOM + V_SYNC - 1;
|
||||||
|
parameter V_MAX = V_DISPLAY + V_TOP + V_BOTTOM + V_SYNC - 1;
|
||||||
|
|
||||||
|
wire hmaxxed = (hpos == H_MAX) || reset; // set when hpos is maximum
|
||||||
|
wire vmaxxed = (vpos == V_MAX) || reset; // set when vpos is maximum
|
||||||
|
|
||||||
|
// horizontal position counter
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
hsync <= (hpos>=H_SYNC_START && hpos<=H_SYNC_END);
|
||||||
|
if(hmaxxed)
|
||||||
|
hpos <= 0;
|
||||||
|
else
|
||||||
|
hpos <= hpos + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// vertical position counter
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
vsync <= (vpos>=V_SYNC_START && vpos<=V_SYNC_END);
|
||||||
|
if(hmaxxed)
|
||||||
|
if (vmaxxed)
|
||||||
|
vpos <= 0;
|
||||||
|
else
|
||||||
|
vpos <= vpos + 1;
|
||||||
|
end
|
||||||
|
|
||||||
|
// display_on is set when beam is in "safe" visible frame
|
||||||
|
assign display_on = (hpos<H_DISPLAY) && (vpos<V_DISPLAY);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
31
presets/verilog-vga/lfsr.v
Normal file
31
presets/verilog-vga/lfsr.v
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
|
||||||
|
`ifndef LFSR_V
|
||||||
|
`define LFSR_V
|
||||||
|
|
||||||
|
/*
|
||||||
|
Configurable Linear Feedback Shift Register.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module LFSR(clk, reset, enable, lfsr);
|
||||||
|
|
||||||
|
parameter TAPS = 8'b11101; // bitmask for taps
|
||||||
|
parameter INVERT = 0; // invert feedback bit?
|
||||||
|
localparam NBITS = $size(TAPS); // bit width (derived from TAPS)
|
||||||
|
|
||||||
|
input clk, reset;
|
||||||
|
input enable; // only perform shift when enable=1
|
||||||
|
output reg [NBITS-1:0] lfsr; // shift register
|
||||||
|
|
||||||
|
wire feedback = lfsr[NBITS-1] ^ INVERT;
|
||||||
|
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
if (reset)
|
||||||
|
lfsr <= {lfsr[NBITS-2:0], 1'b1}; // reset loads with all 1s
|
||||||
|
else if (enable)
|
||||||
|
lfsr <= {lfsr[NBITS-2:0], 1'b0} ^ (feedback ? TAPS : 0);
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
80
presets/verilog-vga/ram.v
Normal file
80
presets/verilog-vga/ram.v
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
|
||||||
|
`ifndef RAM_H
|
||||||
|
`define RAM_H
|
||||||
|
|
||||||
|
/*
|
||||||
|
RAM_sync - Synchronous RAM module.
|
||||||
|
RAM_async - Asynchronous RAM module.
|
||||||
|
RAM_async_tristate - Async RAM module with bidirectional data bus.
|
||||||
|
|
||||||
|
Module parameters:
|
||||||
|
|
||||||
|
A - number of address bits (default = 10)
|
||||||
|
D - number of data bits (default = 8)
|
||||||
|
*/
|
||||||
|
|
||||||
|
module RAM_sync(clk, addr, din, dout, we);
|
||||||
|
|
||||||
|
parameter A = 10; // # of address bits
|
||||||
|
parameter D = 8; // # of data bits
|
||||||
|
|
||||||
|
input clk; // clock
|
||||||
|
input [A-1:0] addr; // address
|
||||||
|
input [D-1:0] din; // data input
|
||||||
|
output [D-1:0] dout; // data output
|
||||||
|
input we; // write enable
|
||||||
|
|
||||||
|
reg [D-1:0] mem [0:(1<<A)-1]; // (1<<A)xD bit memory
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (we) // if write enabled
|
||||||
|
mem[addr] <= din; // write memory from din
|
||||||
|
dout <= mem[addr]; // read memory to dout (sync)
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module RAM_async(clk, addr, din, dout, we);
|
||||||
|
|
||||||
|
parameter A = 10; // # of address bits
|
||||||
|
parameter D = 8; // # of data bits
|
||||||
|
|
||||||
|
input clk; // clock
|
||||||
|
input [A-1:0] addr; // address
|
||||||
|
input [D-1:0] din; // data input
|
||||||
|
output [D-1:0] dout; // data output
|
||||||
|
input we; // write enable
|
||||||
|
|
||||||
|
reg [D-1:0] mem [0:(1<<A)-1]; // (1<<A)xD bit memory
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (we) // if write enabled
|
||||||
|
mem[addr] <= din; // write memory from din
|
||||||
|
end
|
||||||
|
|
||||||
|
assign dout = mem[addr]; // read memory to dout (async)
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module RAM_async_tristate(clk, addr, data, we);
|
||||||
|
|
||||||
|
parameter A = 10; // # of address bits
|
||||||
|
parameter D = 8; // # of data bits
|
||||||
|
|
||||||
|
input clk; // clock
|
||||||
|
input [A-1:0] addr; // address
|
||||||
|
inout [D-1:0] data; // data in/out
|
||||||
|
input we; // write enable
|
||||||
|
|
||||||
|
reg [D-1:0] mem [0:(1<<A)-1]; // (1<<A)xD bit memory
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (we) // if write enabled
|
||||||
|
mem[addr] <= data; // write memory from data
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data = !we ? mem[addr] : {D{1'bz}}; // read memory to data (async)
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
32
presets/verilog-vga/test_hvsync.v
Normal file
32
presets/verilog-vga/test_hvsync.v
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
|
||||||
|
`include "hvsync_generator.v"
|
||||||
|
|
||||||
|
/*
|
||||||
|
A simple test pattern using the hvsync_generator module.
|
||||||
|
*/
|
||||||
|
|
||||||
|
module test_hvsync_top(clk, reset, hsync, vsync, rgb);
|
||||||
|
|
||||||
|
input clk, reset;
|
||||||
|
output hsync, vsync;
|
||||||
|
output [2:0] rgb;
|
||||||
|
wire display_on;
|
||||||
|
wire [8:0] hpos;
|
||||||
|
wire [8:0] vpos;
|
||||||
|
|
||||||
|
hvsync_generator hvsync_gen(
|
||||||
|
.clk(clk),
|
||||||
|
.reset(0),
|
||||||
|
.hsync(hsync),
|
||||||
|
.vsync(vsync),
|
||||||
|
.display_on(display_on),
|
||||||
|
.hpos(hpos),
|
||||||
|
.vpos(vpos)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire r = display_on && (((hpos&7)==0) || ((vpos&7)==0));
|
||||||
|
wire g = display_on && vpos[4];
|
||||||
|
wire b = display_on && hpos[4];
|
||||||
|
assign rgb = {b,g,r};
|
||||||
|
|
||||||
|
endmodule
|
@ -295,7 +295,7 @@ var VerilogPlatform = function(mainElement, options) {
|
|||||||
ctx.fillText(txt, x, y);
|
ctx.fillText(txt, x, y);
|
||||||
ctx.shadowOffsetX = 0;
|
ctx.shadowOffsetX = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// inner Platform class
|
// inner Platform class
|
||||||
|
|
||||||
class _VerilogPlatform extends BasePlatform implements WaveformProvider {
|
class _VerilogPlatform extends BasePlatform implements WaveformProvider {
|
||||||
@ -308,6 +308,13 @@ var VerilogPlatform = function(mainElement, options) {
|
|||||||
|
|
||||||
getPresets() { return VERILOG_PRESETS; }
|
getPresets() { return VERILOG_PRESETS; }
|
||||||
|
|
||||||
|
setVideoParams(width:number, height:number, clock:number) {
|
||||||
|
videoWidth = width;
|
||||||
|
videoHeight = height;
|
||||||
|
cyclesPerFrame = clock;
|
||||||
|
maxVideoLines = height+40;
|
||||||
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
video = new RasterVideo(mainElement,videoWidth,videoHeight,{overscan:true});
|
video = new RasterVideo(mainElement,videoWidth,videoHeight,{overscan:true});
|
||||||
video.create();
|
video.create();
|
||||||
@ -751,24 +758,21 @@ var VerilogPlatform = function(mainElement, options) {
|
|||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
var VERILOG_SIM_PRESETS = [
|
var VERILOG_VGA_PRESETS = [
|
||||||
{id:'clock_divider.v', name:'Clock Divider'},
|
|
||||||
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
|
|
||||||
{id:'hvsync_generator.v', name:'Video Sync Generator'},
|
{id:'hvsync_generator.v', name:'Video Sync Generator'},
|
||||||
{id:'test_hvsync.v', name:'Test Pattern'},
|
{id:'test_hvsync.v', name:'Test Pattern'},
|
||||||
{id:'starfield.v', name:'Scrolling Starfield'},
|
|
||||||
{id:'chardisplay.v', name:'RAM Text Display'},
|
|
||||||
{id:'sound_generator.v', name:'Sound Generator'},
|
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
var VerilogSimulatorPlatform = function(mainElement, options) {
|
var VerilogVGAPlatform = function(mainElement, options) {
|
||||||
this.__proto__ = new (VerilogPlatform as any)(mainElement, options);
|
this.__proto__ = new (VerilogPlatform as any)(mainElement, options);
|
||||||
|
|
||||||
this.getPresets = function() { return VERILOG_SIM_PRESETS; }
|
this.getPresets = function() { return VERILOG_VGA_PRESETS; }
|
||||||
|
|
||||||
|
this.setVideoParams(800-64, 520, 25000000);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
|
|
||||||
PLATFORMS['verilog'] = VerilogPlatform;
|
PLATFORMS['verilog'] = VerilogPlatform;
|
||||||
PLATFORMS['verilog.sim'] = VerilogSimulatorPlatform;
|
PLATFORMS['verilog-vga'] = VerilogVGAPlatform;
|
||||||
|
Loading…
Reference in New Issue
Block a user