Skip to content

Commit

Permalink
VGA adapter added
Browse files Browse the repository at this point in the history
  • Loading branch information
menotti committed May 29, 2021
1 parent e5b5733 commit 6b0a52c
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 42 deletions.
18 changes: 11 additions & 7 deletions assembler/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@ Example syntax:

```
# text
label:
LOAD a
ADD b
STORE c
JUMP label
loop:
LDV
SUB a
STVI
delay:
SUB a
JNZ delay
LOAD a
JNZ loop
# video (special label to initialize video data, no spaces allowed)
.video 0x00,0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0A,0x0B,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F,0x10,0x11,0x12,0x13,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19,0x1A,0x1B,0x1B,0x1C,0x1D,0x1E,0x1F,0x1F,0x20,0x21,0x22,0x23,0x23,0x24,0x25,0x26,0x27,0x27,0x28,0x29,0x2A,0x2B,0x2B,0x2C,0x2D,0x2E,0x2F,0x2F,0x30,0x31,0x32,0x33,0x33,0x34,0x35,0x36,0x37,0x37,0x38,0x39,0x3A,0x3B,0x3B,0x3C,0x3D,0x3E,0x3F
# data
.a 1
.b 2
.c 3
```

Based on the code from https://github.com/dmjio/Assembler.py
33 changes: 28 additions & 5 deletions assembler/assembler.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import sys
import time

atable, ltable, dtable = {}, {}, {} #initialize global tables
atable, ltable, dtable, vtable = {}, {}, {}, [] #initialize global tables
address_size = 4
jump_size = 7

Expand Down Expand Up @@ -33,10 +33,11 @@ def prepare_file(filename):
return a

def translate(a):
global vtable
f = []
code = 0
for i in a:
if not is_l_command(i) and not is_d_command(i):
if not is_l_command(i) and not is_d_command(i):
f.append(atable[i])
code += 1
if code > space_table["code"]:
Expand All @@ -45,8 +46,22 @@ def translate(a):
elif code < space_table["code"]:
for i in range(space_table["code"] - code):
f.append(to_b(0, 8))
video = len(vtable)
if video > space_table["video"]:
print "Warning: video data truncated", video
vtable = vtable[0:space_table["video"]]
for i in vtable:
if is_hex(i):
f.append(to_b(try_parse_int(i, 16),8))
else:
f.append(to_b(try_parse_int(i),8))
if video < space_table["video"]:
for i in range(space_table["video"] - video):
f.append(to_b(63, 8)) # white fill
print "Video:", len(vtable), "/", space_table["video"]
for i in range(space_table["unused"]):
f.append(to_b(255, 8))
print "Unused:", space_table["unused"]
data = [to_b(0, 8) for i in xrange(space_table["data"])]
for i in dtable:
data[try_parse_int(dtable[i][0], base=2)] = dtable[i][1]
Expand All @@ -62,8 +77,10 @@ def make_ltable(a):
if is_l_command(i): #find a label, add line number to it
x -= 1
ltable[i[0:-1]] = to_b(x, jump_size) #use binary helper with 0's padding
print "Label:", i[0:-1], "address", x

def make_dtable(a):
global vtable
space = 0
for i in a: # add to symbols table
if is_d_command(i):
Expand All @@ -76,9 +93,13 @@ def make_dtable(a):
if var in dtable.keys():
print "Error: redefinition of variable '" + var + "'!"
sys.exit(7)
elif var == "video":
print "Video data declaration"
vtable = val.split(",")
elif try_parse_int(val) is not None:
dtable[var] = [to_b(space, address_size), to_b(int(val))]
space += 1
print "Data declaration", var
else:
dtable[var] = [to_b(space, address_size), to_b(0)] # unable to parse
space += 1
Expand All @@ -91,7 +112,11 @@ def make_atable(a):
for i in a:
if not is_d_command(i) and not is_l_command(i):
mnemo = i.split(' ')[0]
param = i.split(' ')[1]
if mnemo != 'LDV' and mnemo != 'STVI':
param = i.split(' ')[1]
else:
atable[i] = inst_table[mnemo] + "1111"
continue
if mnemo in inst_table.keys():
if mnemo[0] == 'J':
if param in ltable:
Expand Down Expand Up @@ -123,5 +148,3 @@ def write_file(a):
main()
print "Time: ", time.time()-t0, "s"



1 change: 1 addition & 0 deletions assembler/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
is_l_command = lambda i : i.find(':') != -1 # labels ends with ':'
is_a_command = lambda i : i.find(' ') == 0 or i.find('\t') == 0 # assembly commands must be indented (further removed)
is_d_command = lambda i : i.find('.') == 0 # data variables starts with '.'
is_hex = lambda i : i.find('0x') == 0 # Hexadecimal

#attempts to parse an integer
def try_parse_int(s, base=10, val=None):
Expand Down
7 changes: 5 additions & 2 deletions assembler/tables.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
inst_table = {
"LDV" : "0000",
"STVI" : "0001",
"ADD" : "0101",
"SUB" : "0110",
"LOAD" : "0100",
"STORE" : "0011",
"JUMP" : "1"
"JNZ" : "1"
}

space_table = {
"code" : 128,
"unused" : 112,
"video" : 80,
"unused" : 32,
"data" : 16
}
12 changes: 12 additions & 0 deletions assembler/vga.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
loop:
LDV
SUB a
STVI
delay:
SUB a
JNZ delay
LOAD a
JNZ loop

.video 0x00,0x00,0x01,0x02,0x03,0x03,0x04,0x05,0x06,0x07,0x07,0x08,0x09,0x0A,0x0B,0x0B,0x0C,0x0D,0x0E,0x0F,0x0F,0x10,0x11,0x12,0x13,0x13,0x14,0x15,0x16,0x17,0x17,0x18,0x19,0x1A,0x1B,0x1B,0x1C,0x1D,0x1E,0x1F,0x1F,0x20,0x21,0x22,0x23,0x23,0x24,0x25,0x26,0x27,0x27,0x28,0x29,0x2A,0x2B,0x2B,0x2C,0x2D,0x2E,0x2F,0x2F,0x30,0x31,0x32,0x33,0x33,0x34,0x35,0x36,0x37,0x37,0x38,0x39,0x3A,0x3B,0x3B,0x3C,0x3D,0x3E,0x3F
.a 1
4 changes: 4 additions & 0 deletions processor/clk_wiz_1.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
// Substitutes Xilinx IP core for simulation purposes
module clk_wiz_1(output clk_out, input clk_in);
assign clk_out = clk_in;
endmodule
26 changes: 20 additions & 6 deletions processor/cpu.sv
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module uP(
module cpu(
input clock, reset,
inout [7:0] mbr,
output logic we,
Expand All @@ -7,12 +7,13 @@ module uP(
typedef enum logic [1:0] {FETCH, DECODE, EXECUTE} statetype;
statetype state, nextstate;

logic [7:0] acc;
logic [7:0] acc, vaddr;

always @(posedge clock or posedge reset)
begin
if (reset) begin
pc = 'b0;
pc <= 'b0;
vaddr <= 8'b10000000; // 128
state <= FETCH;
end
else begin
Expand All @@ -24,17 +25,31 @@ module uP(
end
DECODE: begin
ir = mbr;
mar <= {4'b1111, ir[3:0]};
if (ir[7:5] == 3'b000) // load/store video
mar <= vaddr;
else
mar <= {4'b1111, ir[3:0]};
end
EXECUTE: begin
if (ir[7] == 1'b1) // jump
if (ir[7] == 1'b1 && acc != 8'b00000000) // jnz
pc <= {1'b0, ir[6:0]};
else if (ir[7:4] == 4'b0100) // indirect load
acc <= mbr;
else if (ir[7:4] == 4'b0101) // add acc + data
acc <= acc + mbr;
else if (ir[7:4] == 4'b0110) // sub acc - data
acc <= acc - mbr;
else if (ir[7:4] == 4'b0011) // store
we <= 1'b1;
else if (ir[7:4] == 4'b0000) // load video
acc <= mbr;
else if (ir[7:4] == 4'b0001) // store video
begin
we <= 1'b1;
vaddr <= vaddr + 1;
if (vaddr > 207)
vaddr <= 8'b10000000; // 128
end
end
endcase
state <= nextstate;
Expand All @@ -51,4 +66,3 @@ module uP(

assign mbr = we ? acc : 'bz;
endmodule

8 changes: 5 additions & 3 deletions processor/mem.sv
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
module mem #(parameter filename = "ram.hex")
(input clock, we,
input [7:0] address,
inout [7:0] data);
inout [7:0] data,
input [7:0] vaddr,
output [7:0] vdata);

logic [7:0] RAM[255:0];

initial
// $readmemh(filename, RAM); //Hex file
$readmemb(filename, RAM); //Bin file
$readmemb(filename, RAM);

assign data = we ? 'bz : RAM[address];
assign vdata = RAM[vaddr];

always @(posedge clock)
if (we) RAM[address] <= data;
Expand Down
18 changes: 18 additions & 0 deletions processor/por.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module power_on_reset(
input clk,
output reset);

reg q0 = 1'b0;
reg q1 = 1'b0;
reg q2 = 1'b0;

always@(posedge clk)
begin
q0 <= 1'b1;
q1 <= q0;
q2 <= q1;
end

assign reset = !(q0 & q1 & q2);
endmodule

16 changes: 16 additions & 0 deletions processor/tb.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module tb;
reg clock;

top dut(clock);

initial
begin
$dumpfile("dump.vcd"); $dumpvars(0);
#50000; $stop;
end

always
begin
clock <= 1; #5; clock <= 0; #5;
end
endmodule
34 changes: 15 additions & 19 deletions processor/top.sv
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
module up_tb;
logic clock, reset, we;
logic [7:0] address, ir, pc;
wire [7:0] data;

uP proc(clock, reset, data, we, address, pc, ir);
// mem #("fibo.hex") ram(clock, we, address, data);
mem #("fibo.bin") ram(clock, we, address, data);

initial
begin
$dumpfile("dump.vcd"); $dumpvars(0);
reset <= 1; #22; reset <= 0;
#5000; $stop;
end
module top(
input sysclk, // 125MHz
output [3:0] led,
output led5_r, led5_g, led5_b, led6_r, led6_g, led6_b,
output [3:0] VGA_R, VGA_G, VGA_B,
output VGA_HS_O, VGA_VS_O);

always
begin
clock <= 1; #5; clock <= 0; #5;
end
wire pixel_clk, reset, we;
wire [7:0] address, data, vaddr, vdata;

power_on_reset por(sysclk, reset);
clk_wiz_1 clockdiv(pixel_clk, sysclk); // 25MHz
cpu proc(sysclk, reset, data, we, address);
mem #("vga.bin") ram(sysclk, we, address, data, vaddr, vdata);
vga video(pixel_clk, reset, vdata, vaddr, VGA_R, VGA_G, VGA_B, VGA_HS_O, VGA_VS_O);
endmodule

52 changes: 52 additions & 0 deletions processor/vga.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
module vga(
input clk, reset,
input [7:0] vdata,
output [7:0] vaddr,
output [3:0] VGA_R, VGA_G, VGA_B,
output VGA_HS_O, VGA_VS_O);

reg [9:0] CounterX, CounterY;
reg inDisplayArea;
reg vga_HS, vga_VS;

wire CounterXmaxed = (CounterX == 800); // 16 + 48 + 96 + 640
wire CounterYmaxed = (CounterY == 525); // 10 + 2 + 33 + 480
wire [3:0] row, col;

always @(posedge clk or posedge reset)
if (reset)
CounterX <= 0;
else
if (CounterXmaxed)
CounterX <= 0;
else
CounterX <= CounterX + 1;

always @(posedge clk or posedge reset)
if (reset)
CounterY <= 0;
else
if (CounterXmaxed)
if(CounterYmaxed)
CounterY <= 0;
else
CounterY <= CounterY + 1;

assign row = (CounterY>>6);
assign col = (CounterX>>6);
assign vaddr = {1'b1,col[3:0],row[2:0]};

always @(posedge clk)
begin
vga_HS <= (CounterX > (640 + 16) && (CounterX < (640 + 16 + 96))); // active for 96 clocks
vga_VS <= (CounterY > (480 + 10) && (CounterY < (480 + 10 + 2))); // active for 2 clocks
inDisplayArea <= (CounterX < 640) && (CounterY < 480);
end

assign VGA_HS_O = ~vga_HS;
assign VGA_VS_O = ~vga_VS;

assign VGA_R = inDisplayArea ? {vdata[5:4], 2'b00} : 4'b0000;
assign VGA_G = inDisplayArea ? {vdata[3:2], 2'b00} : 4'b0000;
assign VGA_B = inDisplayArea ? {vdata[1:0], 2'b00} : 4'b0000;
endmodule

0 comments on commit 6b0a52c

Please sign in to comment.