generated from saji/litex-overlay
wip: basic pixel generator + coordinator module
coordinator is a high level hub75 controller. It drives multiple panels by generating the x/y coordinates that would be displayed on each, then converting those into the BRAM format to be written quickly.
This commit is contained in:
parent
bd2fa51f2d
commit
9a4dfea4f0
10
Makefile
10
Makefile
|
@ -1,9 +1,11 @@
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.PHONY all clean test
|
.PHONY all clean test
|
||||||
|
|
||||||
|
VERILOG_SOURCES := $(join $(wildcard verilog/*.v), $(wildcard verilog/*.sv))
|
||||||
|
TESTBENCH_SOURCES := $(wildcard verilog/tb/*.sv)
|
||||||
|
ICARUS_ARGS := "-g2012"
|
||||||
|
|
||||||
|
%.vcd: %.vvp
|
||||||
|
vvp $^
|
||||||
|
|
||||||
|
%.vvp: %.sv
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
module bitslicer (
|
module bitslicer (
|
||||||
input clk,
|
input clk,
|
||||||
input [23:0] rgb[2],
|
input [23:0] rgb[2],
|
||||||
input [7:0] pixnum, // x-value of the pixels we are being fed.
|
input [8: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,
|
||||||
|
@ -9,8 +9,16 @@ module bitslicer (
|
||||||
output reg done
|
output reg done
|
||||||
);
|
);
|
||||||
|
|
||||||
reg [3:0] bitplane_bit = 0;
|
reg [2:0] bitplane_bit = 0;
|
||||||
assign bitplane_addr = (pixnum << 3) + bitplane_bit;
|
assign bitplane_addr = (pixnum << 3) + bitplane_bit;
|
||||||
|
assign bitplane_data = {
|
||||||
|
rgb[1][bitplane_bit],
|
||||||
|
rgb[1][bitplane_bit+8],
|
||||||
|
rgb[1][bitplane_bit+16],
|
||||||
|
rgb[0][bitplane_bit],
|
||||||
|
rgb[0][bitplane_bit+8],
|
||||||
|
rgb[0][bitplane_bit+16]
|
||||||
|
};
|
||||||
|
|
||||||
reg [3:0] state = StateInit;
|
reg [3:0] state = StateInit;
|
||||||
localparam integer StateInit = 0;
|
localparam integer StateInit = 0;
|
||||||
|
@ -26,27 +34,27 @@ module bitslicer (
|
||||||
bitplane_wren <= 0;
|
bitplane_wren <= 0;
|
||||||
if (start_write) begin
|
if (start_write) begin
|
||||||
state <= StateWriteout;
|
state <= StateWriteout;
|
||||||
|
bitplane_wren <= 1;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
StateWriteout: begin
|
StateWriteout: begin
|
||||||
bitplane_data <= {
|
// bitplane_data <= {
|
||||||
rgb[1][bitplane_bit],
|
// rgb[1][bitplane_bit],
|
||||||
rgb[1][bitplane_bit+8],
|
// rgb[1][bitplane_bit+8],
|
||||||
rgb[1][bitplane_bit+16],
|
// rgb[1][bitplane_bit+16],
|
||||||
rgb[0][bitplane_bit],
|
// rgb[0][bitplane_bit],
|
||||||
rgb[0][bitplane_bit+8],
|
// rgb[0][bitplane_bit+8],
|
||||||
rgb[0][bitplane_bit+16]
|
// rgb[0][bitplane_bit+16]
|
||||||
};
|
// };
|
||||||
bitplane_wren <= 1;
|
|
||||||
bitplane_bit <= bitplane_bit + 1;
|
bitplane_bit <= bitplane_bit + 1;
|
||||||
|
|
||||||
if (bitplane_bit == 7) begin
|
if (bitplane_bit == 7) begin
|
||||||
state <= StateDone;
|
state <= StateDone;
|
||||||
|
bitplane_wren <= 0;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
StateDone: begin
|
StateDone: begin
|
||||||
bitplane_wren <= 0;
|
done <= 1; // strobe
|
||||||
done <= 1; // strobe
|
|
||||||
state <= StateInit;
|
state <= StateInit;
|
||||||
end
|
end
|
||||||
default: begin
|
default: begin
|
||||||
|
|
144
verilog/coordinator.sv
Normal file
144
verilog/coordinator.sv
Normal file
|
@ -0,0 +1,144 @@
|
||||||
|
module coordinator (
|
||||||
|
input clk
|
||||||
|
);
|
||||||
|
|
||||||
|
// pixgen signals
|
||||||
|
reg pixgen_start;
|
||||||
|
reg [8:0] x;
|
||||||
|
reg [8:0] y;
|
||||||
|
wire [23:0] pix_rgb[2];
|
||||||
|
wire [1:0] pix_done;
|
||||||
|
|
||||||
|
pixgen pix0 (
|
||||||
|
.clk(clk),
|
||||||
|
.start(pixgen_start),
|
||||||
|
.x(x),
|
||||||
|
.y(y),
|
||||||
|
.rgb(pix_rgb[0]),
|
||||||
|
.done(pix_done[0])
|
||||||
|
);
|
||||||
|
pixgen pix1 (
|
||||||
|
.clk(clk),
|
||||||
|
.start(pixgen_start),
|
||||||
|
.x(x),
|
||||||
|
.y(y + 9'd32),
|
||||||
|
.rgb(pix_rgb[1]),
|
||||||
|
.done(pix_done[1])
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
// slicer signals
|
||||||
|
wire bitslice_start;
|
||||||
|
wire [5:0] bitplane_data;
|
||||||
|
wire [10:0] bitplane_addr;
|
||||||
|
wire bitplane_wren;
|
||||||
|
wire bitplane_done;
|
||||||
|
|
||||||
|
bitslicer bslice (
|
||||||
|
.clk(clk),
|
||||||
|
.rgb(pix_rgb),
|
||||||
|
.pixnum(x),
|
||||||
|
.start_write(bitslice_start),
|
||||||
|
.bitplane_data(bitplane_data),
|
||||||
|
.bitplane_addr(bitplane_addr),
|
||||||
|
.bitplane_wren(bitplane_wren),
|
||||||
|
.done(bitplane_done)
|
||||||
|
);
|
||||||
|
|
||||||
|
// bram signals
|
||||||
|
|
||||||
|
wire [8:0] din;
|
||||||
|
wire [10:0] addr_w;
|
||||||
|
wire [8:0] dout;
|
||||||
|
wire [10:0] addr_r;
|
||||||
|
wire read_clk;
|
||||||
|
wire write_clk;
|
||||||
|
|
||||||
|
lineram bram (
|
||||||
|
.write_clk(clk),
|
||||||
|
.read_clk(clk),
|
||||||
|
.addr_w(bitplane_addr),
|
||||||
|
.din({3'b000, bitplane_data}),
|
||||||
|
.write_en(bitplane_wren),
|
||||||
|
.addr_r(addr_r),
|
||||||
|
.dout(dout)
|
||||||
|
);
|
||||||
|
|
||||||
|
// driver
|
||||||
|
reg write_line;
|
||||||
|
wire line_done;
|
||||||
|
wire [2:0] panel_rgb0;
|
||||||
|
wire [2:0] panel_rgb1;
|
||||||
|
wire display_clk;
|
||||||
|
wire out_enable;
|
||||||
|
wire latch;
|
||||||
|
|
||||||
|
hub75e driver (
|
||||||
|
.clk(clk),
|
||||||
|
.write_trig(write_line),
|
||||||
|
.panel_rgb0(panel_rgb0),
|
||||||
|
.panel_rgb1(panel_rgb1),
|
||||||
|
.display_clk(display_clk),
|
||||||
|
.out_enable(out_enable),
|
||||||
|
.latch(latch),
|
||||||
|
.done(line_done),
|
||||||
|
.pixbuf_addr(addr_r),
|
||||||
|
.pixbuf_data(dout)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
reg [4:0] state = 0;
|
||||||
|
|
||||||
|
localparam unsigned StateInit = 0;
|
||||||
|
localparam unsigned StateStartFrame = 1;
|
||||||
|
localparam unsigned StateGenerateLine = 2;
|
||||||
|
localparam unsigned StateShowLine = 3;
|
||||||
|
localparam unsigned StateIncrementLine = 4;
|
||||||
|
// we're gonna try this
|
||||||
|
assign bitslice_start = pix_done[0] & pix_done[1]; // bitslice start when both pix done.
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
case (state)
|
||||||
|
StateInit: begin
|
||||||
|
x <= 0;
|
||||||
|
y <= 0;
|
||||||
|
state <= StateStartFrame;
|
||||||
|
end
|
||||||
|
StateStartFrame: begin
|
||||||
|
pixgen_start <= 1;
|
||||||
|
state <= StateGenerateLine;
|
||||||
|
end
|
||||||
|
StateGenerateLine: begin
|
||||||
|
pixgen_start <= 0;
|
||||||
|
if (bitplane_done) begin
|
||||||
|
if (x < 127) begin
|
||||||
|
x <= x + 1;
|
||||||
|
pixgen_start <= 1;
|
||||||
|
// generate next
|
||||||
|
end else begin
|
||||||
|
write_line <= 1;
|
||||||
|
state <= StateShowLine;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
StateShowLine: begin
|
||||||
|
write_line <= 0;
|
||||||
|
if (line_done) begin
|
||||||
|
state <= StateIncrementLine;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
StateIncrementLine: begin
|
||||||
|
x <= 0;
|
||||||
|
y <= y + 1;
|
||||||
|
if (y == 31) begin
|
||||||
|
state <= StateInit;
|
||||||
|
end else begin
|
||||||
|
state <= StateStartFrame;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
default: state <= StateInit;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
endmodule
|
|
@ -1,8 +1,6 @@
|
||||||
module hub75e (
|
module hub75e (
|
||||||
input clk,
|
input clk,
|
||||||
input write_trig,
|
input write_trig,
|
||||||
input [4:0] addr_in, // only latched in during init.
|
|
||||||
output reg [4:0] addr_out,
|
|
||||||
output reg [2:0] panel_rgb0,
|
output reg [2:0] panel_rgb0,
|
||||||
output reg [2:0] panel_rgb1,
|
output reg [2:0] panel_rgb1,
|
||||||
output reg display_clk = 0,
|
output reg display_clk = 0,
|
||||||
|
@ -30,7 +28,6 @@ module hub75e (
|
||||||
reg [7:0] state = StateInit; // our state
|
reg [7:0] state = StateInit; // our state
|
||||||
|
|
||||||
|
|
||||||
assign addr = 5'b10101;
|
|
||||||
|
|
||||||
// initial begin
|
// initial begin
|
||||||
// state <= StateInit;
|
// state <= StateInit;
|
||||||
|
|
24
verilog/pixgen.sv
Normal file
24
verilog/pixgen.sv
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module pixgen #(
|
||||||
|
parameter integer X_DEPTH = 9,
|
||||||
|
parameter integer Y_DEPTH = 9,
|
||||||
|
parameter integer RGB_DEPTH = 24
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input start,
|
||||||
|
input [X_DEPTH-1:0] x,
|
||||||
|
input [Y_DEPTH-1:0] y,
|
||||||
|
output reg [RGB_DEPTH-1:0] rgb,
|
||||||
|
output reg done
|
||||||
|
);
|
||||||
|
|
||||||
|
// given x and y inputs, create an rgb output
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (start) begin
|
||||||
|
done <= 1;
|
||||||
|
rgb <= { x[8:0], y[8:0] };
|
||||||
|
end
|
||||||
|
else done <= 0;
|
||||||
|
end
|
||||||
|
|
||||||
|
endmodule
|
|
@ -0,0 +1,43 @@
|
||||||
|
`timescale 1ns / 100ps // 1 ns time unit, 100 ps resolution
|
||||||
|
|
||||||
|
module bitslicer_tb;
|
||||||
|
reg clk = 0;
|
||||||
|
|
||||||
|
reg [23:0] rgb_in [2];
|
||||||
|
reg start_write = 0;
|
||||||
|
reg [7:0] pixnum = 0;
|
||||||
|
wire [5:0] bitplane_data;
|
||||||
|
wire [10:0] bitplane_addr;
|
||||||
|
wire bitplane_wren;
|
||||||
|
wire done;
|
||||||
|
|
||||||
|
bitslicer dut(
|
||||||
|
.clk(clk),
|
||||||
|
.rgb(rgb_in),
|
||||||
|
.pixnum(pixnum),
|
||||||
|
.start_write(start_write),
|
||||||
|
.bitplane_data(bitplane_data),
|
||||||
|
.bitplane_addr(bitplane_addr),
|
||||||
|
.done(done)
|
||||||
|
);
|
||||||
|
|
||||||
|
always #5 clk = !clk;
|
||||||
|
initial begin
|
||||||
|
$dumpfile("bitslicer_tb.vcd");
|
||||||
|
$dumpvars(0, bitslicer_tb);
|
||||||
|
rgb_in[0] <= 24'hEE8833;
|
||||||
|
rgb_in[1] <= 24'hDD7722;
|
||||||
|
pixnum <= 3;
|
||||||
|
@(posedge clk);
|
||||||
|
start_write <= 1;
|
||||||
|
@(posedge clk);
|
||||||
|
start_write <= 0;
|
||||||
|
@(done);
|
||||||
|
repeat (10) @(posedge clk);
|
||||||
|
$finish();
|
||||||
|
end
|
||||||
|
initial begin
|
||||||
|
repeat (100000) @(posedge clk);
|
||||||
|
$finish();
|
||||||
|
end
|
||||||
|
endmodule
|
14
verilog/tb/coordinator_tb.sv
Normal file
14
verilog/tb/coordinator_tb.sv
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
`timescale 1ns / 100ps // 1 ns time unit, 100 ps resolution
|
||||||
|
|
||||||
|
module coordinator_tb();
|
||||||
|
reg clk = 0;
|
||||||
|
coordinator dut(.clk(clk));
|
||||||
|
always #8 clk = !clk;
|
||||||
|
initial begin
|
||||||
|
$dumpfile("coordinator.vcd");
|
||||||
|
$dumpvars(0, coordinator_tb);
|
||||||
|
repeat (10000) @(posedge clk);
|
||||||
|
$finish;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
Loading…
Reference in a new issue