diff --git a/verilog/hub75e.sv b/verilog/hub75e.sv index 49b865c..46eefb4 100644 --- a/verilog/hub75e.sv +++ b/verilog/hub75e.sv @@ -1,14 +1,17 @@ module hub75e ( input clk, input write_trig, - input [1:0][BIT_DEPTH - 1:0] rgb_row[ROW_DEPTH], output reg [4:0] addr, output reg [2:0] panel_rgb0, output reg [2:0] panel_rgb1, output reg display_clk = 0, output reg out_enable = 1, output reg latch = 0, - output reg done = 0 + output reg done = 0, + + // bram interface (using clk) + output reg [8:0] pixbuf_addr, + input [35:0] pixbuf_data ); parameter integer ROW_DEPTH = 128, BIT_DEPTH = 8; @@ -27,8 +30,6 @@ module hub75e ( assign addr = 5'b10101; - assign panel_rgb0 = 3'b101; - assign panel_rgb1 = 3'b010; // initial begin // state <= StateInit; @@ -55,11 +56,12 @@ module hub75e ( counter <= counter + 1; case (state) StateInit: begin + bcm_shift <= 7; + counter <= 0; + done <= 0; + pixbuf_addr <= 0; // wait for the signal to write out our lines. if (write_trig) begin - bcm_shift <= 7; - counter <= 0; - done <= 0; state <= StateWriteRow; end end @@ -68,20 +70,31 @@ module hub75e ( if (should_clock) begin // we have data to clock display_clk <= counter[0]; - if (counter[0]) begin - // load the next pixel data. this is the falling edge since the - // previous value is 1. + if (~counter[0]) begin + // the data from the previous cycle is now ready. + panel_rgb0 <= { + (pixbuf_data[bcm_shift]), + (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! + end else begin + // update the bram address so it's ready at the next clock cycle. + pixbuf_addr <= pixbuf_addr + 1; end end if (should_expose) begin - // we are still in our expose state, and our bcm shift is not the - // first one, so we should expose. out_enable <= 0; end else begin out_enable <= 1; end // if we're done with our data clock out and also done with exposing - // the previous frame, go next. + // the previous line, go to the latchout stage. if (~should_clock && ~should_expose) begin counter <= 0; state <= StateLatchout; @@ -92,10 +105,11 @@ module hub75e ( // raise latch high; compute next bcm. latch <= 1; out_enable <= 1; + pixbuf_addr <= 0; counter <= counter + 1; if (counter > 3) begin if (bcm_shift == 0) begin - // done with the line. do the last (short) expose + // we've reached the lsb of this data, go to the next one! state <= StateFinishExpose; latch <= 0; end else begin diff --git a/verilog/lineram.v b/verilog/lineram.v new file mode 100644 index 0000000..564b4ed --- /dev/null +++ b/verilog/lineram.v @@ -0,0 +1,28 @@ +module lineram #( + parameter DATA_WIDTH = 36, + parameter ADDR_WIDTH = 9 +) ( + input [DATA_WIDTH - 1:0] din, + input [ADDR_WIDTH - 1:0] addr_w, + output reg [DATA_WIDTH - 1:0] dout, + input [ADDR_WIDTH - 1:0] addr_r, + input write_en, + input read_clk, + input write_clk +); + + reg [DATA_WIDTH - 1] ram[2**ADDR_WIDTH]; + + initial begin + for(int i=0; i < 2**ADDR_WIDTH; i=i+1) begin + ram[i] = 0; + end + end + + always @(posedge write_clk) begin + if (write_en) ram[addr_w] <= din; + end + always @(posedge read_clk) begin + dout <= ram[addr_r]; + end +endmodule diff --git a/verilog/tb/hub75e_tb.sv b/verilog/tb/hub75e_tb.sv index 146f6d5..ae6dc2e 100644 --- a/verilog/tb/hub75e_tb.sv +++ b/verilog/tb/hub75e_tb.sv @@ -4,8 +4,6 @@ module hub75e_tb; reg clk; reg write_trig; - reg [1:0][7:0] rgb_row[128]; - wire [4:0] addr_out; wire [2:0] rgb0; wire [2:0] rgb1; @@ -15,27 +13,58 @@ module hub75e_tb; wire done; + // block ram inputs + reg [35:0] bram_data_in; + reg [8:0] bram_addr_w; + reg bram_write_en; + + + wire [8:0] bram_addr_r; + wire [35:0] bram_data_out; + + + lineram bram ( + .din(bram_data_in), + .addr_w(bram_addr_w), + .dout(bram_data_out), + .addr_r(bram_addr_r), + .write_en(bram_write_en), + .read_clk(clk), + .write_clk(clk) + ); + hub75e dut ( .clk(clk), .write_trig(write_trig), - .rgb_row(rgb_row), .addr(addr_out), .panel_rgb0(rgb0), .panel_rgb1(rgb1), .display_clk(display_clk), .out_enable(out_enable), .latch(latch), - .done(done) + .done(done), + + .pixbuf_addr(bram_addr_r), + .pixbuf_data(bram_data_out) ); always #5 clk = !clk; initial begin $dumpfile("wave.vcd"); $dumpvars(0, hub75e_tb); - clk = 0; - write_trig = 1; + clk <= 0; + bram_addr_w <= 0; + bram_write_en <= 1; + repeat (1) @(posedge clk); + for (int i=0; i < 128; i=i+1) begin + bram_data_in <= $urandom % 'hFFFFFF; + bram_addr_w <= i; + repeat (1) @(posedge clk); + end + bram_write_en <= 1; + write_trig <= 1; repeat (2) @(posedge clk); - write_trig = 0; + write_trig <= 0; @(done); repeat (20) @(posedge clk);