minor changes; preset changes; rotate output

This commit is contained in:
Steven Hugg 2018-02-13 19:04:52 -06:00
parent 8c3939ac6c
commit 89b1c64ac8
7 changed files with 134 additions and 46 deletions

View File

@ -1,19 +1,23 @@
module LFSR8_11D(
input clk,
output reg [7:0] LFSR = 255 // put here the initial value
);
wire feedback = LFSR[7];
module LFSR(clk,reset,enable,lfsr);
parameter NBITS = 8;
parameter TAPS = 8'b11101;
parameter INVERT = 0;
input clk, reset;
input enable;
output reg [NBITS-1:0] lfsr;
wire feedback = lfsr[NBITS-1] ^ INVERT;
always @(posedge clk)
begin
if (reset) // initialize to 1
lfsr <= {lfsr[NBITS-2:1], 1'b0, 1'b1};
else if (enable)
lfsr <= {lfsr[NBITS-2:0], 1'b0} ^ (feedback ? TAPS : 0);
end
endmodule;
always @(posedge clk)
begin
LFSR[0] <= feedback;
LFSR[1] <= LFSR[0];
LFSR[2] <= LFSR[1] ^ feedback;
LFSR[3] <= LFSR[2] ^ feedback;
LFSR[4] <= LFSR[3] ^ feedback;
LFSR[5] <= LFSR[4];
LFSR[6] <= LFSR[5];
LFSR[7] <= LFSR[6];
end
endmodule

View File

@ -13,10 +13,11 @@ module sound_psg(clk, reset, out, reg_sel, reg_data, reg_write);
reg outputs[NVOICES];
reg [17:0] count[NVOICES];
reg [7:0] register[16];
integer i;
always @(posedge clk) begin
out = 0;
for (int i=0; i<NVOICES; i++) begin
for (i=0; i<NVOICES; i++) begin
if (count[i][17:6] == {register[i*2+1][3:0], register[i*2]}) begin
outputs[i] <= outputs[i] ^ 1;
count[i] <= 0;
@ -33,7 +34,7 @@ module sound_psg(clk, reset, out, reg_sel, reg_data, reg_write);
end
end
endmodule;
endmodule
module music_player(clk, reset, advance,
psg_sel, psg_data, psg_write);

View File

@ -0,0 +1,39 @@
`include "hvsync_generator.v"
`include "lfsr.v"
module 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;
wire [15:0] lfsr;
hvsync_generator hvsync_gen(
.clk(clk),
.reset(reset),
.hsync(hsync),
.vsync(vsync),
.display_on(display_on),
.hpos(hpos),
.vpos(vpos)
);
wire star_enable = !hpos[8] & !vpos[8];
// LFSR with period = 2^16-1 = 256*256-1
LFSR #(16,16'b1000000001011,0) lfsr_gen(
.clk(clk),
.reset(reset),
.enable(star_enable),
.lfsr(lfsr));
wire star_on = &lfsr[15:9];
wire r = display_on && star_on && lfsr[0];
wire g = display_on && star_on && lfsr[1];
wire b = display_on && star_on && lfsr[2];
assign rgb = {b,g,r};
endmodule

View File

@ -312,6 +312,7 @@ var SampleAudio = function(clockfreq) {
var sfrac, sinc, accum;
var buffer, bufpos, bufferlist;
var idrain, ifill;
var nbuffers = 3;
function mix(ape) {
var buflen=ape.outputBuffer.length;
@ -381,7 +382,7 @@ var SampleAudio = function(clockfreq) {
bufferlist = [];
idrain = 1;
ifill = 0;
for (var i=0; i<3; i++) {
for (var i=0; i<nbuffers; i++) {
var arrbuf = new ArrayBuffer(self.bufferlen*4);
bufferlist[i] = new Float32Array(arrbuf);
}

View File

@ -31,15 +31,22 @@ var RasterVideo = function(mainElement, width, height, options) {
var canvas, ctx;
var imageData, arraybuf, buf8, datau32;
this.setRotate = function(rotate) {
if (rotate) {
// TODO: aspect ratio?
canvas.style.transform = "rotate("+rotate+"deg)";
if (canvas.width < canvas.height)
canvas.style.paddingLeft = canvas.style.paddingRight = "10%";
} else {
canvas.style.transform = null;
canvas.style.paddingLeft = canvas.style.paddingRight = null;
}
}
this.create = function() {
self.canvas = canvas = __createCanvas(mainElement, width, height);
if (options && options.rotate) {
// TODO: aspect ratio?
canvas.style.transform = "rotate("+options.rotate+"deg)";
if (canvas.width < canvas.height)
canvas.style.paddingLeft = canvas.style.paddingRight = "10%";
//else
// canvas.style.paddingTop = canvas.style.paddingBottom = "10%";
self.setRotate(options.rotate);
}
ctx = canvas.getContext('2d');
imageData = ctx.createImageData(width, height);

View File

@ -4,7 +4,6 @@ var VERILOG_PRESETS = [
{id:'clock_divider.v', name:'Clock Divider'},
{id:'hvsync_generator.v', name:'Video Sync Generator'},
{id:'test_hvsync.v', name:'Test Pattern'},
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
{id:'digits10.v', name:'Bitmapped Digits'},
{id:'7segment.v', name:'7-Segment Decoder'},
{id:'scoreboard.v', name:'Scoreboard'},
@ -17,6 +16,10 @@ var VERILOG_PRESETS = [
{id:'sprite_rotation.v', name:'Sprite Rotation'},
{id:'tank.v', name:'Tank Game'},
{id:'cpu8.v', name:'Simple 8-Bit CPU'},
{id:'race_game_cpu.v', name:'Race Game With CPU'},
{id:'music.v', name:'3-Voice Music'},
{id:'lfsr.v', name:'Linear Feedback Shift Register'},
{id:'starfield.v', name:'Scrolling Starfield'},
];
var VERILOG_KEYCODE_MAP = makeKeycodeMap([
@ -62,16 +65,16 @@ var vl_stopped = false;
var VL_NEGATE_I = this.VL_NEGATE_I = function(x) { return -x; }
var VL_LTS_III = this.VL_LTS_III = function(x,lbits,y,lhs,rhs) {
return VL_EXTENDS_II(x,lbits,lhs) < VL_EXTENDS_II(x,lbits,rhs); }
return 0 | (VL_EXTENDS_II(x,lbits,lhs) < VL_EXTENDS_II(x,lbits,rhs)); }
var VL_GTS_III = this.VL_GTS_III = function(x,lbits,y,lhs,rhs) {
return VL_EXTENDS_II(x,lbits,lhs) > VL_EXTENDS_II(x,lbits,rhs); }
return 0 | (VL_EXTENDS_II(x,lbits,lhs) > VL_EXTENDS_II(x,lbits,rhs)); }
var VL_LTES_III = this.VL_LTES_III = function(x,lbits,y,lhs,rhs) {
return VL_EXTENDS_II(x,lbits,lhs) <= VL_EXTENDS_II(x,lbits,rhs); }
return 0 | (VL_EXTENDS_II(x,lbits,lhs) <= VL_EXTENDS_II(x,lbits,rhs)); }
var VL_GTES_III = this.VL_GTES_III = function(x,lbits,y,lhs,rhs) {
return VL_EXTENDS_II(x,lbits,lhs) >= VL_EXTENDS_II(x,lbits,rhs); }
return 0 | (VL_EXTENDS_II(x,lbits,lhs) >= VL_EXTENDS_II(x,lbits,rhs)); }
var VL_MODDIV_III = this.VL_MODDIV_III = function(lbits,lhs,rhs) {
return (((rhs)==0)?0:(lhs)%(rhs)); }
@ -92,7 +95,7 @@ var vl_stopped = false;
vl_stopped = true;
}
var VL_RAND_RESET_I = this.VL_RAND_RESET_I = function(bits) { return Math.floor(Math.random() * (1<<bits)); }
var VL_RAND_RESET_I = this.VL_RAND_RESET_I = function(bits) { return 0 | Math.floor(Math.random() * (1<<bits)); }
//
@ -131,11 +134,10 @@ function VerilatorBase() {
this.eval();
}
var vlSymsp = {TOPp:this};
var vlSymsp = this; //{TOPp:this};
var maxVclockLoop = 1;
this.eval = function() {
vlSymsp.TOPp = this;
// Initialize
if (!vlSymsp.__Vm_didInit)
this._eval_initial_loop(vlSymsp);
@ -158,6 +160,7 @@ function VerilatorBase() {
}
this._eval_initial_loop = function(vlSymsp) {
vlSymsp.TOPp = this;
vlSymsp.__Vm_didInit = true;
this._eval_initial(vlSymsp);
vlSymsp.__Vm_activity = true;
@ -175,8 +178,9 @@ function VerilatorBase() {
var VerilogPlatform = function(mainElement, options) {
var self = this;
var video, audio;
var videoWidth = 304;
var videoHeight = 248;
var useAudio = false;
var videoWidth = 256+16;
var videoHeight = 240+16;
var maxVideoBlankLines = 80;
var idata, timer;
var gen;
@ -219,11 +223,14 @@ var VerilogPlatform = function(mainElement, options) {
function vidtick() {
gen.tick2();
audio.feedSample((gen.spkr&255)*(1.0/255.0), 1);
if (debugCond && debugCond()) debugCond = null;
if (useAudio)
audio.feedSample(gen.spkr*(1.0/255.0), 1);
if (debugCond && debugCond())
debugCond = null;
}
function updateInspectionFrame() {
useAudio = false;
if (inspect_obj && inspect_sym) {
var COLOR_BIT_OFF = 0xffff3333;
var COLOR_BIT_ON = 0xffffffff;
@ -251,8 +258,9 @@ var VerilogPlatform = function(mainElement, options) {
}
function updateVideoFrame() {
useAudio = gen.spkr !== 'undefined';
debugCond = self.getDebugCallback();
var i=4; // TODO, start @ 0?
var i=videoWidth-10;
var trace=inspect_obj && inspect_sym;
gen.switches_p1 = switches[0];
gen.switches_p2 = switches[1];
@ -265,7 +273,7 @@ var VerilogPlatform = function(mainElement, options) {
if (trace) {
inspect_data[i] = inspect_obj[inspect_sym];
}
idata[i++] = RGBLOOKUP[gen.rgb];
idata[i++] = RGBLOOKUP[gen.rgb & 7];
}
var z=0;
while (!gen.hsync && z++<videoWidth) vidtick();
@ -321,14 +329,12 @@ var VerilogPlatform = function(mainElement, options) {
fillTraceBuffer(Math.floor(videoWidth/4) * arr.length);
if (!dirty) return;
dirty = false;
for (var i=0; i<idata.length; i++) {
if (idata[i])
idata[i] = 0; //<<= 1;
}
var COLOR_BLACK = 0xff000000;
var COLOR_SIGNAL = 0xff22ff22;
var COLOR_BORDER = 0xff662222;
var COLOR_TRANS_SIGNAL = 0xff226622;
var COLOR_BLIP_SIGNAL = 0xff226622;
idata.fill(COLOR_BLACK);
var jstart = scope_x_offset * arr.length;
var j = jstart;
for (var x=0; x<videoWidth; x++) {
@ -419,12 +425,12 @@ var VerilogPlatform = function(mainElement, options) {
$(video.canvas).mousedown(function(e) {
scope_time_x = Math.floor(e.offsetX * video.canvas.width / $(video.canvas).width() - 16);
mouse_pressed = true;
e.target.setCapture();
if (e.target.setCapture) e.target.setCapture();
dirty = true;
});
$(video.canvas).mouseup(function(e) {
mouse_pressed = false;
e.target.releaseCapture();
if (e.target.setCapture) e.target.releaseCapture();
});
audio = new SampleAudio(AUDIO_FREQ);
idata = video.getFrameData();
@ -492,6 +498,8 @@ var VerilogPlatform = function(mainElement, options) {
trace_index = scope_x_offset = 0;
trace_buffer.fill(0);
dirty = true;
console.log(gen.rotate);
video.setRotate(gen.rotate ? -90 : 0);
}
this.tick = function() {
gen.tick2();

28
tools/lfsrcalc.py Executable file
View File

@ -0,0 +1,28 @@
#!/usr/bin/python
print "Period,nbits,feedback,mask"
for n in range(1,18):
mask = (1<<n)-1
hibit = (1<<(n-1))
for i in range(0,1<<n):
for invert in [0,1]:
x = 1
seq = []
seen = set()
while x and not x in seen:
seq.append(x)
seen.add(x)
feedback = x & hibit
x = ((x << 1) & mask)
if invert:
if not feedback:
x ^= i
else:
if feedback:
x ^= i
if x:
seqindex = seq.index(x)
seqlen = len(seq) - seqindex
if seqlen>1:
print seqlen, "#(%d,%d'%s,%d)" % (n,n,bin(i)[1:],invert), seqindex