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
|
||||
|
||||
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 (
|
||||
input clk,
|
||||
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,
|
||||
output reg [5:0] bitplane_data,
|
||||
output [10:0] bitplane_addr,
|
||||
|
@ -9,8 +9,16 @@ module bitslicer (
|
|||
output reg done
|
||||
);
|
||||
|
||||
reg [3:0] bitplane_bit = 0;
|
||||
reg [2:0] bitplane_bit = 0;
|
||||
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;
|
||||
localparam integer StateInit = 0;
|
||||
|
@ -26,27 +34,27 @@ module bitslicer (
|
|||
bitplane_wren <= 0;
|
||||
if (start_write) begin
|
||||
state <= StateWriteout;
|
||||
bitplane_wren <= 1;
|
||||
end
|
||||
end
|
||||
StateWriteout: begin
|
||||
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]
|
||||
};
|
||||
bitplane_wren <= 1;
|
||||
// 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]
|
||||
// };
|
||||
bitplane_bit <= bitplane_bit + 1;
|
||||
|
||||
if (bitplane_bit == 7) begin
|
||||
state <= StateDone;
|
||||
bitplane_wren <= 0;
|
||||
end
|
||||
end
|
||||
StateDone: begin
|
||||
bitplane_wren <= 0;
|
||||
done <= 1; // strobe
|
||||
done <= 1; // strobe
|
||||
state <= StateInit;
|
||||
end
|
||||
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 (
|
||||
input clk,
|
||||
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_rgb1,
|
||||
output reg display_clk = 0,
|
||||
|
@ -30,7 +28,6 @@ module hub75e (
|
|||
reg [7:0] state = StateInit; // our state
|
||||
|
||||
|
||||
assign addr = 5'b10101;
|
||||
|
||||
// initial begin
|
||||
// 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