coordinator works now

fixed some off by one errors to make the screen work good
This commit is contained in:
saji 2024-05-01 16:14:32 -05:00
parent 9a4dfea4f0
commit 37dabd603a
9 changed files with 117 additions and 146 deletions

View file

@ -94,53 +94,21 @@ class Hub75Driver(Module):
class Hub75VerilogDriver(Module): class Hub75VerilogDriver(Module):
def __init__(self): def __init__(self):
clk = Signal()
self.i_write_trig = Signal() self.o_addr = Signal(5)
self.i_addr_in = Signal(5)
self.o_addr_out = Signal(5)
self.o_display_clk = Signal() self.o_display_clk = Signal()
self.o_enable = Signal()
self.o_latch = Signal() self.o_latch = Signal()
self.o_out_enable = Signal() self.o_out_enable = Signal()
self.o_done = Signal()
self.o_panel_rgb0 = Signal(3) self.o_panel_rgb0 = Signal(3)
self.o_panel_rgb1 = Signal(3) self.o_panel_rgb1 = Signal(3)
self.pixbuf_addr = Signal(9) inst = Instance("coordinator",
self.pixbuf_data = Signal(36) i_clk = ClockSignal(),
self.comb += ClockSignal().eq(clk)
# simple driver fsm
self.comb += self.pixbuf_data.eq(Replicate(self.pixbuf_addr, 3))
self.fsm = fsm = FSM()
fsm.act("start",
NextValue(self.i_write_trig, 1),
NextState("wait"),
)
fsm.act("wait",
NextValue(self.i_write_trig, 0),
If(self.o_done,
NextState("start"),
)
)
self.submodules += self.fsm
inst = Instance("hub75e",
i_clk = clk,
i_write_trig = self.i_write_trig,
i_addr_in = self.i_addr_in,
o_addr_out = self.o_addr_out,
o_panel_rgb0 = self.o_panel_rgb0, o_panel_rgb0 = self.o_panel_rgb0,
o_panel_rgb1 = self.o_panel_rgb1, o_panel_rgb1 = self.o_panel_rgb1,
o_latch = self.o_latch, o_latch = self.o_latch,
o_display_clk = self.o_display_clk, o_display_clk = self.o_display_clk,
o_done = self.o_done,
o_out_enable = self.o_out_enable, o_out_enable = self.o_out_enable,
o_pixbuf_addr = self.pixbuf_addr, o_display_addr = self.o_addr,
i_pixbuf_data = self.pixbuf_data
) )
self.specials += inst self.specials += inst

View file

@ -113,8 +113,6 @@ class _CRG(LiteXModule):
# pll.create_clkout(self.cd_sdram, sys_clk_freq, phase=180) # pll.create_clkout(self.cd_sdram, sys_clk_freq, phase=180)
pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq) pll.create_clkout(self.cd_sys2x, 2*sys_clk_freq)
pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180) pll.create_clkout(self.cd_sys2x_ps, 2*sys_clk_freq, phase=180)
pll.create_clkout(self.cd_hub, 60e6)
sdram_clk = ClockSignal("sys2x_ps") sdram_clk = ClockSignal("sys2x_ps")
# sdram_clk = ClockSignal("sdram") # sdram_clk = ClockSignal("sdram")

View file

@ -51,7 +51,7 @@ class GroovySoC(SoCCore):
self.add_spi_flash(mode="1x", module=SpiFlashModule, with_master=False) self.add_spi_flash(mode="1x", module=SpiFlashModule, with_master=False)
self.platform.add_extension(make_hub75_iodevice(0, "j8")) self.platform.add_extension(make_hub75_iodevice(0, "j8"))
hub_io = self.platform.request("hub75_iodev", 0) hub_io = self.platform.request("hub75_iodev", 0)
self.submodules.hub75 = hub75 = ClockDomainsRenamer("hub")(Hub75VerilogDriver()) self.submodules.hub75 = hub75 = Hub75VerilogDriver()
self.comb += [ self.comb += [
hub_io.r0.eq(hub75.o_panel_rgb0[0]), hub_io.r0.eq(hub75.o_panel_rgb0[0]),
hub_io.g0.eq(hub75.o_panel_rgb0[1]), hub_io.g0.eq(hub75.o_panel_rgb0[1]),
@ -60,11 +60,11 @@ class GroovySoC(SoCCore):
hub_io.g1.eq(hub75.o_panel_rgb1[1]), hub_io.g1.eq(hub75.o_panel_rgb1[1]),
hub_io.b1.eq(hub75.o_panel_rgb1[2]), hub_io.b1.eq(hub75.o_panel_rgb1[2]),
hub_io.clk.eq(hub75.o_display_clk), hub_io.clk.eq(hub75.o_display_clk),
hub_io.addr.eq(hub75.o_addr_out), hub_io.addr.eq(hub75.o_addr),
hub_io.oe.eq(hub75.o_out_enable), hub_io.oe.eq(hub75.o_out_enable),
hub_io.stb.eq(hub75.o_latch), hub_io.stb.eq(hub75.o_latch),
] ]
platform.add_source("verilog/hub75e.sv") platform.add_sources("./verilog/", "bitslicer.sv", "coordinator.sv", "hub75e.sv", "lineram.v", "pixgen.sv")
@ -85,7 +85,7 @@ def main():
trellis_args(parser.add_argument_group('Trellis options')) trellis_args(parser.add_argument_group('Trellis options'))
args = parser.parse_args() args = parser.parse_args()
platform = Groovy1Platform() platform = Groovy1Platform()
soc = GroovySoC(platform, 75e6, **soc_core_argdict(args)) soc = GroovySoC(platform, 60e6, **soc_core_argdict(args))
builder = Builder(soc, **builder_argdict(args)) builder = Builder(soc, **builder_argdict(args))

View file

@ -1,7 +1,8 @@
module bitslicer ( module bitslicer (
input clk, input clk,
input [23:0] rgb[2], input [23:0] rgb0,
input [8:0] pixnum, // x-value of the pixels we are being fed. input [23:0] rgb1,
input [7:0] pixnum, // x-value of the pixels we are being fed.
input start_write, input start_write,
output reg [5:0] bitplane_data, output reg [5:0] bitplane_data,
output [10:0] bitplane_addr, output [10:0] bitplane_addr,
@ -10,14 +11,14 @@ module bitslicer (
); );
reg [2:0] bitplane_bit = 0; reg [2:0] bitplane_bit = 0;
assign bitplane_addr = (pixnum << 3) + bitplane_bit; assign bitplane_addr = {bitplane_bit, pixnum};
assign bitplane_data = { assign bitplane_data = {
rgb[1][bitplane_bit], rgb1[bitplane_bit],
rgb[1][bitplane_bit+8], rgb1[bitplane_bit+8],
rgb[1][bitplane_bit+16], rgb1[bitplane_bit+16],
rgb[0][bitplane_bit], rgb0[bitplane_bit],
rgb[0][bitplane_bit+8], rgb0[bitplane_bit+8],
rgb[0][bitplane_bit+16] rgb0[bitplane_bit+16]
}; };
reg [3:0] state = StateInit; reg [3:0] state = StateInit;

View file

@ -1,12 +1,19 @@
module coordinator ( module coordinator (
input clk input clk,
output display_clk,
output out_enable,
output latch,
output [2:0] panel_rgb0,
output [2:0] panel_rgb1,
output reg [4:0] display_addr
); );
// pixgen signals // pixgen signals
reg pixgen_start; reg pixgen_start;
reg [8:0] x; reg [8:0] x;
reg [8:0] y; reg [8:0] y;
wire [23:0] pix_rgb[2]; wire [23:0] pix_rgb0;
wire [23:0] pix_rgb1;
wire [1:0] pix_done; wire [1:0] pix_done;
pixgen pix0 ( pixgen pix0 (
@ -14,7 +21,7 @@ module coordinator (
.start(pixgen_start), .start(pixgen_start),
.x(x), .x(x),
.y(y), .y(y),
.rgb(pix_rgb[0]), .rgb(pix_rgb0),
.done(pix_done[0]) .done(pix_done[0])
); );
pixgen pix1 ( pixgen pix1 (
@ -22,7 +29,7 @@ module coordinator (
.start(pixgen_start), .start(pixgen_start),
.x(x), .x(x),
.y(y + 9'd32), .y(y + 9'd32),
.rgb(pix_rgb[1]), .rgb(pix_rgb1),
.done(pix_done[1]) .done(pix_done[1])
); );
@ -36,7 +43,8 @@ module coordinator (
bitslicer bslice ( bitslicer bslice (
.clk(clk), .clk(clk),
.rgb(pix_rgb), .rgb0(pix_rgb0),
.rgb1(pix_rgb1),
.pixnum(x), .pixnum(x),
.start_write(bitslice_start), .start_write(bitslice_start),
.bitplane_data(bitplane_data), .bitplane_data(bitplane_data),
@ -48,7 +56,6 @@ module coordinator (
// bram signals // bram signals
wire [8:0] din; wire [8:0] din;
wire [10:0] addr_w;
wire [8:0] dout; wire [8:0] dout;
wire [10:0] addr_r; wire [10:0] addr_r;
wire read_clk; wire read_clk;
@ -67,11 +74,6 @@ module coordinator (
// driver // driver
reg write_line; reg write_line;
wire line_done; wire line_done;
wire [2:0] panel_rgb0;
wire [2:0] panel_rgb1;
wire display_clk;
wire out_enable;
wire latch;
hub75e driver ( hub75e driver (
.clk(clk), .clk(clk),
@ -102,6 +104,8 @@ module coordinator (
StateInit: begin StateInit: begin
x <= 0; x <= 0;
y <= 0; y <= 0;
display_addr <= 0;
write_line <= 0;
state <= StateStartFrame; state <= StateStartFrame;
end end
StateStartFrame: begin StateStartFrame: begin
@ -111,7 +115,7 @@ module coordinator (
StateGenerateLine: begin StateGenerateLine: begin
pixgen_start <= 0; pixgen_start <= 0;
if (bitplane_done) begin if (bitplane_done) begin
if (x < 127) begin if (x < 128) begin
x <= x + 1; x <= x + 1;
pixgen_start <= 1; pixgen_start <= 1;
// generate next // generate next
@ -129,8 +133,9 @@ module coordinator (
end end
StateIncrementLine: begin StateIncrementLine: begin
x <= 0; x <= 0;
display_addr <= display_addr + 1;
y <= y + 1; y <= y + 1;
if (y == 31) begin if (display_addr == 31) begin
state <= StateInit; state <= StateInit;
end else begin end else begin
state <= StateStartFrame; state <= StateStartFrame;

View file

@ -9,7 +9,7 @@ module hub75e (
output reg done = 0, output reg done = 0,
// bram interface (using clk) // bram interface (using clk)
output reg [10:0] pixbuf_addr, output [10:0] pixbuf_addr,
input [ 8:0] pixbuf_data input [ 8:0] pixbuf_data
); );
@ -47,9 +47,12 @@ module hub75e (
// short! // short!
wire should_clock, should_expose; wire should_clock, should_expose;
assign should_clock = counter < ROW_DEPTH * 2; assign should_clock = (counter < ROW_DEPTH * 2 + 1); // the plus 1 is for the falling edge!
assign should_expose = (counter < (16 << bcm_shift + 1)) && (bcm_shift != 7); assign should_expose = (counter < (16 << bcm_shift + 1)) && (bcm_shift != 7);
reg [7:0] pixnum;
assign pixbuf_addr = {bcm_shift, pixnum};
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
counter <= counter + 1; counter <= counter + 1;
case (state) case (state)
@ -57,7 +60,7 @@ module hub75e (
bcm_shift <= 7; bcm_shift <= 7;
counter <= 0; counter <= 0;
done <= 0; done <= 0;
pixbuf_addr <= 0; pixnum <= ROW_DEPTH - 1;
// wait for the signal to write out our lines. // wait for the signal to write out our lines.
if (write_trig) begin if (write_trig) begin
state <= StateWriteRow; state <= StateWriteRow;
@ -70,20 +73,12 @@ module hub75e (
display_clk <= counter[0]; display_clk <= counter[0];
if (~counter[0]) begin if (~counter[0]) begin
// the data from the previous cycle is now ready. // the data from the previous cycle is now ready.
panel_rgb0 <= { panel_rgb0 <= pixbuf_data[2:0];
(pixbuf_data[bcm_shift]), panel_rgb1 <= pixbuf_data[5:3];
(pixbuf_data[bcm_shift + 8]),
(pixbuf_data[bcm_shift + 16])
};
panel_rgb1 <= {
(pixbuf_data[bcm_shift]),
(pixbuf_data[bcm_shift + 8]),
(pixbuf_data[bcm_shift + 16])
};
// write it out! // write it out!
end else begin end else begin
// update the bram address so it's ready at the next clock cycle. // update the bram address so it's ready at the next clock cycle.
pixbuf_addr <= pixbuf_addr + 1; pixnum <= pixnum - 1;
end end
end end
if (should_expose) begin if (should_expose) begin
@ -95,7 +90,9 @@ module hub75e (
// the previous line, go to the latchout stage. // the previous line, go to the latchout stage.
if (~should_clock && ~should_expose) begin if (~should_clock && ~should_expose) begin
counter <= 0; counter <= 0;
pixnum <= 0;
state <= StateLatchout; state <= StateLatchout;
display_clk <= 0;
end end
end end
@ -103,9 +100,10 @@ module hub75e (
// raise latch high; compute next bcm. // raise latch high; compute next bcm.
latch <= 1; latch <= 1;
out_enable <= 1; out_enable <= 1;
pixbuf_addr <= 0; pixnum <= ROW_DEPTH - 1;
counter <= counter + 1; counter <= counter + 1;
if (counter > 3) begin if (counter > 3) begin
counter <= 0;
if (bcm_shift == 0) begin if (bcm_shift == 0) begin
// we've reached the lsb of this data, go to the next one! // we've reached the lsb of this data, go to the next one!
state <= StateFinishExpose; state <= StateFinishExpose;

View file

@ -71,13 +71,14 @@ module lineram #(
// // // //
// // ); // // );
// `else // `else
reg [DATA_WIDTH - 1] ram[2**ADDR_WIDTH]; reg [DATA_WIDTH - 1:0] ram[2**ADDR_WIDTH];
`ifndef YOSYS
initial begin initial begin
for (int i = 0; i < 2 ** ADDR_WIDTH; i = i + 1) begin for (int i = 0; i < 2 ** ADDR_WIDTH; i = i + 1) begin
ram[i] = 0; ram[i] = 0;
end end
end end
`endif
always @(posedge write_clk) begin always @(posedge write_clk) begin
if (write_en) ram[addr_w] <= din; if (write_en) ram[addr_w] <= din;

View file

@ -16,7 +16,7 @@ module pixgen #(
always @(posedge clk) begin always @(posedge clk) begin
if (start) begin if (start) begin
done <= 1; done <= 1;
rgb <= { x[8:0], y[8:0] }; rgb <= { 8'b0, x[7:0], y[7:0] };
end end
else done <= 0; else done <= 0;
end end

View file

@ -7,7 +7,7 @@ coordinator dut(.clk(clk));
initial begin initial begin
$dumpfile("coordinator.vcd"); $dumpfile("coordinator.vcd");
$dumpvars(0, coordinator_tb); $dumpvars(0, coordinator_tb);
repeat (10000) @(posedge clk); repeat (100000) @(posedge clk);
$finish; $finish;
end end
endmodule endmodule