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
|
||||
- recording video indicator
|
||||
- verilog: support VGA/multisync monitor?
|
||||
- stego shareable images (http://pico-8.wikia.com/wiki/P8PNGFileFormat)
|
||||
- https://makecode.com/language?
|
||||
|
||||
|
||||
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.shadowOffsetX = 0;
|
||||
}
|
||||
|
||||
|
||||
// inner Platform class
|
||||
|
||||
class _VerilogPlatform extends BasePlatform implements WaveformProvider {
|
||||
@ -308,6 +308,13 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
|
||||
getPresets() { return VERILOG_PRESETS; }
|
||||
|
||||
setVideoParams(width:number, height:number, clock:number) {
|
||||
videoWidth = width;
|
||||
videoHeight = height;
|
||||
cyclesPerFrame = clock;
|
||||
maxVideoLines = height+40;
|
||||
}
|
||||
|
||||
start() {
|
||||
video = new RasterVideo(mainElement,videoWidth,videoHeight,{overscan:true});
|
||||
video.create();
|
||||
@ -751,24 +758,21 @@ var VerilogPlatform = function(mainElement, options) {
|
||||
|
||||
////////////////
|
||||
|
||||
var VERILOG_SIM_PRESETS = [
|
||||
{id:'clock_divider.v', name:'Clock Divider'},
|
||||
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
|
||||
var VERILOG_VGA_PRESETS = [
|
||||
{id:'hvsync_generator.v', name:'Video Sync Generator'},
|
||||
{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.getPresets = function() { return VERILOG_SIM_PRESETS; }
|
||||
this.getPresets = function() { return VERILOG_VGA_PRESETS; }
|
||||
|
||||
this.setVideoParams(800-64, 520, 25000000);
|
||||
}
|
||||
|
||||
////////////////
|
||||
|
||||
PLATFORMS['verilog'] = VerilogPlatform;
|
||||
PLATFORMS['verilog.sim'] = VerilogSimulatorPlatform;
|
||||
PLATFORMS['verilog-vga'] = VerilogVGAPlatform;
|
||||
|
Loading…
Reference in New Issue
Block a user