Compare commits
No commits in common. "e6fa7175078aed5ebfe2989eebba3e7551a4c647" and "2efb40fa3d7db2764031f3c3b5461618f43c2135" have entirely different histories.
e6fa717507
...
2efb40fa3d
|
@ -1,152 +0,0 @@
|
||||||
// This code is derived from the video sync generator at
|
|
||||||
// https://github.com/B-Lang-org/bsc-contrib/blob/main/Libraries/FPGA/Misc/Video.bsv,
|
|
||||||
// simplified down to serve as an experiment/comparison of synthesis
|
|
||||||
// efficiency with the sibling directory that has a more imperative
|
|
||||||
// construction (and also worse, it tursn out).
|
|
||||||
|
|
||||||
package Top;
|
|
||||||
|
|
||||||
import Counter::*;
|
|
||||||
import StmtFSM::*;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Integer active;
|
|
||||||
Integer fporch;
|
|
||||||
Integer sync;
|
|
||||||
Integer bporch;
|
|
||||||
} SyncDescriptor;
|
|
||||||
|
|
||||||
SyncDescriptor horizontal = SyncDescriptor{
|
|
||||||
active: 640,
|
|
||||||
fporch: 16,
|
|
||||||
sync: 96,
|
|
||||||
bporch: 48
|
|
||||||
};
|
|
||||||
|
|
||||||
SyncDescriptor vertical = SyncDescriptor{
|
|
||||||
active: 480,
|
|
||||||
fporch: 10,
|
|
||||||
sync: 2,
|
|
||||||
bporch: 33
|
|
||||||
};
|
|
||||||
|
|
||||||
interface SyncGenerator;
|
|
||||||
method Action tick();
|
|
||||||
method Bool preedge();
|
|
||||||
method Bool out_n();
|
|
||||||
method Bool out();
|
|
||||||
method Bool active();
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
module mkSyncGenerator#(SyncDescriptor info)(SyncGenerator);
|
|
||||||
let maxActive = fromInteger(info.active - 1);
|
|
||||||
let maxFPorch = fromInteger(info.fporch - 1);
|
|
||||||
let maxSync = fromInteger(info.sync - 1);
|
|
||||||
let maxBPorch = fromInteger(info.bporch - 1);
|
|
||||||
|
|
||||||
/////////////////////
|
|
||||||
/// Design Elements
|
|
||||||
/////////////////////
|
|
||||||
Counter#(16) rCounter <- mkCounter(0);
|
|
||||||
|
|
||||||
PulseWire pwTick <- mkPulseWire;
|
|
||||||
PulseWire pwPreSyncEdge <- mkPulseWire;
|
|
||||||
Reg#(Bool) rSyncOut <- mkReg(True);
|
|
||||||
Reg#(Bool) rActive <- mkReg(False);
|
|
||||||
|
|
||||||
/////////////////////
|
|
||||||
/// Rules
|
|
||||||
/////////////////////
|
|
||||||
Stmt machine =
|
|
||||||
seq
|
|
||||||
while(True) seq
|
|
||||||
// Front Porch
|
|
||||||
while(rCounter.value < maxFPorch) action
|
|
||||||
rCounter.up;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
action
|
|
||||||
rCounter.clear;
|
|
||||||
pwPreSyncEdge.send;
|
|
||||||
rSyncOut <= False;
|
|
||||||
rActive <= False;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
// Sync Pulse
|
|
||||||
while(rCounter.value < maxSync) action
|
|
||||||
rCounter.up;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
action
|
|
||||||
rCounter.clear;
|
|
||||||
rSyncOut <= True;
|
|
||||||
rActive <= False;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
// Back Porch
|
|
||||||
while(rCounter.value < maxBPorch) action
|
|
||||||
rCounter.up;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
action
|
|
||||||
rCounter.clear;
|
|
||||||
rSyncOut <= True;
|
|
||||||
rActive <= True;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
// Active
|
|
||||||
while(rCounter.value < maxActive) action
|
|
||||||
rCounter.up;
|
|
||||||
endaction
|
|
||||||
|
|
||||||
action
|
|
||||||
rCounter.clear;
|
|
||||||
rSyncOut <= True;
|
|
||||||
rActive <= False;
|
|
||||||
endaction
|
|
||||||
endseq
|
|
||||||
endseq;
|
|
||||||
|
|
||||||
FSM fsmSyncGen <- mkFSMWithPred(machine, pwTick);
|
|
||||||
|
|
||||||
rule start_sync_generator(fsmSyncGen.done);
|
|
||||||
fsmSyncGen.start;
|
|
||||||
endrule
|
|
||||||
|
|
||||||
method Action tick = pwTick.send;
|
|
||||||
method Bool preedge = pwPreSyncEdge;
|
|
||||||
method Bool out_n = rSyncOut;
|
|
||||||
method Bool out = !rSyncOut;
|
|
||||||
method Bool active = rActive;
|
|
||||||
endmodule: mkSyncGenerator
|
|
||||||
|
|
||||||
interface ITop;
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool paint();
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool hsync();
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool vsync();
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
(* synthesize *)
|
|
||||||
module mkTop (ITop);
|
|
||||||
let horiz <- mkSyncGenerator(horizontal);
|
|
||||||
let vert <- mkSyncGenerator(vertical);
|
|
||||||
|
|
||||||
(* no_implicit_conditions, fire_when_enabled *)
|
|
||||||
rule advance_horizontal;
|
|
||||||
horiz.tick;
|
|
||||||
endrule
|
|
||||||
|
|
||||||
(* no_implicit_conditions, fire_when_enabled *)
|
|
||||||
rule advance_vertical (horiz.preedge);
|
|
||||||
vert.tick;
|
|
||||||
endrule
|
|
||||||
|
|
||||||
method Bool paint = horiz.active && vert.active;
|
|
||||||
method Bool hsync = horiz.out;
|
|
||||||
method Bool vsync = vert.out;
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
endpackage
|
|
|
@ -1,28 +0,0 @@
|
||||||
BLOCK RESETPATHS;
|
|
||||||
BLOCK ASYNCPATHS;
|
|
||||||
|
|
||||||
SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=ENABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE;
|
|
||||||
|
|
||||||
LOCATE COMP "CLK" SITE "G2";
|
|
||||||
IOBUF PORT "CLK" PULLMODE=NONE IO_TYPE=LVCMOS33;
|
|
||||||
FREQUENCY PORT "CLK" 25 MHZ;
|
|
||||||
|
|
||||||
## LED indicators "blinkey" and "gpio" sheet
|
|
||||||
LOCATE COMP "paint" SITE "H3";
|
|
||||||
LOCATE COMP "hsync" SITE "E1";
|
|
||||||
LOCATE COMP "vsync" SITE "E2";
|
|
||||||
IOBUF PORT "paint" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
IOBUF PORT "hsync" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
IOBUF PORT "vsync" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "RST_N" SITE "D6"; # BTN_PWRn (inverted logic)
|
|
||||||
IOBUF PORT "RST_N" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "uart_rx_v" SITE "M1"; # FIRE1
|
|
||||||
IOBUF PORT "uart_rx_v" PULLMODE=UP IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "uart_tx" SITE "L4"; # FPGA transmits to ftdi
|
|
||||||
IOBUF PORT "uart_tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "wifi_gpio0" SITE "L2";
|
|
||||||
IOBUF PORT "wifi_gpio0" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
|
@ -1,108 +0,0 @@
|
||||||
package Top;
|
|
||||||
|
|
||||||
import Counter::*;
|
|
||||||
import StmtFSM::*;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
Integer active;
|
|
||||||
Integer fporch;
|
|
||||||
Integer sync;
|
|
||||||
Integer bporch;
|
|
||||||
} SyncDescriptor;
|
|
||||||
|
|
||||||
SyncDescriptor horizontal = SyncDescriptor{
|
|
||||||
active: 640,
|
|
||||||
fporch: 16,
|
|
||||||
sync: 96,
|
|
||||||
bporch: 48
|
|
||||||
};
|
|
||||||
|
|
||||||
SyncDescriptor vertical = SyncDescriptor{
|
|
||||||
active: 480,
|
|
||||||
fporch: 10,
|
|
||||||
sync: 2,
|
|
||||||
bporch: 33
|
|
||||||
};
|
|
||||||
|
|
||||||
interface SyncGenerator;
|
|
||||||
method Action tick();
|
|
||||||
method Bool preedge();
|
|
||||||
method Bool out_n();
|
|
||||||
method Bool out();
|
|
||||||
method Bool active();
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
interface ITop;
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool paint();
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool hsync();
|
|
||||||
(* always_ready *)
|
|
||||||
method Bool vsync();
|
|
||||||
endinterface
|
|
||||||
|
|
||||||
(* synthesize *)
|
|
||||||
module mkTop (ITop);
|
|
||||||
Reg#(Bool) rPaint <- mkReg(False);
|
|
||||||
Reg#(Bool) rHsync <- mkReg(False);
|
|
||||||
Reg#(Bool) rVsync <- mkReg(False);
|
|
||||||
|
|
||||||
let blank_line_fsm = seq
|
|
||||||
// Sync pulse
|
|
||||||
repeat (96) rHsync <= True;
|
|
||||||
|
|
||||||
// Back porch
|
|
||||||
repeat (48) rHsync <= False;
|
|
||||||
|
|
||||||
// Visible area
|
|
||||||
repeat (640) noAction;
|
|
||||||
|
|
||||||
// Front porch
|
|
||||||
repeat (16) noAction;
|
|
||||||
endseq;
|
|
||||||
let video_line_fsm = seq
|
|
||||||
// Sync pulse
|
|
||||||
repeat (96) rHsync <= True;
|
|
||||||
|
|
||||||
// Back porch
|
|
||||||
repeat (48) rHsync <= False;
|
|
||||||
|
|
||||||
// Visible area
|
|
||||||
repeat (640) rPaint <= True;
|
|
||||||
|
|
||||||
// Front porch
|
|
||||||
repeat (16) rPaint <= False;
|
|
||||||
endseq;
|
|
||||||
let frame_fsm = seq
|
|
||||||
while (True) seq
|
|
||||||
// Sync pulse
|
|
||||||
repeat (2) par
|
|
||||||
rVsync <= True;
|
|
||||||
blank_line_fsm;
|
|
||||||
endpar
|
|
||||||
|
|
||||||
// Back porch
|
|
||||||
repeat (33) par
|
|
||||||
rVsync <= False;
|
|
||||||
blank_line_fsm;
|
|
||||||
endpar
|
|
||||||
|
|
||||||
// Visible area
|
|
||||||
repeat (480) video_line_fsm;
|
|
||||||
|
|
||||||
// Front porch
|
|
||||||
repeat (10) blank_line_fsm;
|
|
||||||
endseq
|
|
||||||
endseq;
|
|
||||||
let fsm <- mkFSM(frame_fsm);
|
|
||||||
|
|
||||||
rule run_timing (fsm.done());
|
|
||||||
fsm.start();
|
|
||||||
endrule
|
|
||||||
|
|
||||||
method Bool paint = rPaint._read;
|
|
||||||
method Bool hsync = rHsync._read;
|
|
||||||
method Bool vsync = rVsync._read;
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
endpackage
|
|
|
@ -1,28 +0,0 @@
|
||||||
BLOCK RESETPATHS;
|
|
||||||
BLOCK ASYNCPATHS;
|
|
||||||
|
|
||||||
SYSCONFIG CONFIG_IOVOLTAGE=3.3 COMPRESS_CONFIG=ON MCCLK_FREQ=62 MASTER_SPI_PORT=ENABLE SLAVE_SPI_PORT=DISABLE SLAVE_PARALLEL_PORT=DISABLE;
|
|
||||||
|
|
||||||
LOCATE COMP "CLK" SITE "G2";
|
|
||||||
IOBUF PORT "CLK" PULLMODE=NONE IO_TYPE=LVCMOS33;
|
|
||||||
FREQUENCY PORT "CLK" 25 MHZ;
|
|
||||||
|
|
||||||
## LED indicators "blinkey" and "gpio" sheet
|
|
||||||
LOCATE COMP "paint" SITE "H3";
|
|
||||||
LOCATE COMP "hsync" SITE "E1";
|
|
||||||
LOCATE COMP "vsync" SITE "E2";
|
|
||||||
IOBUF PORT "paint" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
IOBUF PORT "hsync" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
IOBUF PORT "vsync" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "RST_N" SITE "D6"; # BTN_PWRn (inverted logic)
|
|
||||||
IOBUF PORT "RST_N" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "uart_rx_v" SITE "M1"; # FIRE1
|
|
||||||
IOBUF PORT "uart_rx_v" PULLMODE=UP IO_TYPE=LVCMOS33;
|
|
||||||
|
|
||||||
LOCATE COMP "uart_tx" SITE "L4"; # FPGA transmits to ftdi
|
|
||||||
IOBUF PORT "uart_tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
||||||
|
|
||||||
LOCATE COMP "wifi_gpio0" SITE "L2";
|
|
||||||
IOBUF PORT "wifi_gpio0" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4;
|
|
9
tasks.py
9
tasks.py
|
@ -27,7 +27,7 @@ def bsc_root(c):
|
||||||
def find_verilog_modules(c, modules):
|
def find_verilog_modules(c, modules):
|
||||||
libpaths = [Path("lib"), bsc_root(c) / "Verilog"]
|
libpaths = [Path("lib"), bsc_root(c) / "Verilog"]
|
||||||
ret = []
|
ret = []
|
||||||
for module in modules:
|
for m in modules:
|
||||||
module_path = None
|
module_path = None
|
||||||
for p in libpaths:
|
for p in libpaths:
|
||||||
f = p / Path(module).with_suffix(".v")
|
f = p / Path(module).with_suffix(".v")
|
||||||
|
@ -35,7 +35,7 @@ def find_verilog_modules(c, modules):
|
||||||
module_path = f
|
module_path = f
|
||||||
break
|
break
|
||||||
if module_path is None:
|
if module_path is None:
|
||||||
raise RuntimeError(f"Cannot find verilog module {module} in {libpaths}")
|
raise RuntimeError(f"Cannot find verilog module {m} in {libpaths}")
|
||||||
ret.append(module_path)
|
ret.append(module_path)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
@ -56,13 +56,12 @@ def expand_build_target(target):
|
||||||
raise ValueError(f"Unknown target type {t}")
|
raise ValueError(f"Unknown target type {t}")
|
||||||
|
|
||||||
def resolve_synth_target(target):
|
def resolve_synth_target(target):
|
||||||
target = Path(target)
|
|
||||||
if '/' not in str(target):
|
if '/' not in str(target):
|
||||||
target = "hardware" / target
|
target = "hardware" / Path(target)
|
||||||
if target.is_dir():
|
if target.is_dir():
|
||||||
target /= "Top.bsv"
|
target /= "Top.bsv"
|
||||||
if not target.is_file():
|
if not target.is_file():
|
||||||
raise ValueError(f"Unknown target type {target}")
|
raise ArgumentError(f"Unknown target type {target}")
|
||||||
return target
|
return target
|
||||||
|
|
||||||
def expand_test_target(target):
|
def expand_test_target(target):
|
||||||
|
|
Loading…
Reference in New Issue