blob: 9b126d35fe7636521a4d95014a30609c849aca81 [file] [log] [blame]
module SPIMaster_341450853309219412(
input clock,
input reset,
output tx_ready,
input tx_valid,
input [7:0] tx_byte,
// whether or not to reset CS after sending data
input tx_clear_cs,
output sclk,
output mosi,
output n_cs
);
localparam STATE_IDLE = 2'd0,
STATE_CS_ASSERT = 2'd1,
STATE_TX = 2'd2,
STATE_CS_DEASSERT = 2'd3;
localparam TX_COUNTER_MAX = 3'h7;
reg [1:0] state;
reg [7:0] tx_byte_reg;
reg sclk_mask;
reg mosi_mask;
reg tx_ready_reg;
reg [2:0] tx_counter_reg;
reg n_cs_reg;
reg tx_clear_cs_reg;
assign tx_ready = tx_ready_reg;
assign sclk = ~clock & sclk_mask;
assign mosi = tx_byte_reg[7] & mosi_mask;
assign n_cs = n_cs_reg;
always @(posedge clock) begin
if (reset) begin
state <= STATE_IDLE;
tx_byte_reg <= 8'h0;
sclk_mask <= 1'b0;
mosi_mask <= 1'b0;
tx_ready_reg <= 1'b0;
tx_counter_reg <= 3'd0;
n_cs_reg <= 1'b1;
tx_clear_cs_reg <= 1'b1;
end else begin
if (state == STATE_IDLE) begin
tx_ready_reg <= 1'b1;
if (tx_valid == 1'b1) begin
tx_byte_reg <= tx_byte;
tx_clear_cs_reg <= tx_clear_cs;
tx_ready_reg <= 1'b0;
n_cs_reg <= 1'b0;
if (n_cs_reg == 1'b1) begin
// CS is not asserted: assert it first
state <= STATE_CS_ASSERT;
end else begin
// CS is already asserted: transition to TX
state <= STATE_TX;
sclk_mask <= 1'b1;
mosi_mask <= 1'b1;
end
end
end else if (state == STATE_CS_ASSERT) begin
// assert CS for one cycle before transitioning to TX
state <= STATE_TX;
sclk_mask <= 1'b1;
mosi_mask <= 1'b1;
end else if (state == STATE_TX) begin
tx_byte_reg <= {tx_byte_reg[6:0], 1'b0};
if (tx_counter_reg == TX_COUNTER_MAX) begin
tx_counter_reg <= 3'd0;
sclk_mask <= 1'b0;
mosi_mask <= 1'b0;
// check if CS needs to be reset
if (tx_clear_cs_reg == 1'b1) begin
state <= STATE_CS_DEASSERT;
end else begin
state <= STATE_IDLE;
end
end else begin
tx_counter_reg <= tx_counter_reg + 3'd1;
end
end else if (state == STATE_CS_DEASSERT) begin
// wait one cycle before deasserting CS and transitioning to idle
state <= STATE_IDLE;
n_cs_reg <= 1'b1;
end
end
end
endmodule
module LEDMatrix_341450853309219412(
input clock,
input reset,
output sclk,
output mosi,
output n_cs
);
localparam STATE_RESET_FRAME_INDEX = 1'd0,
STATE_SEND_PIXELS = 1'd1;
// command to reset frame index
localparam CMD_RESET_FRAME_INDEX = 8'h26;
localparam PIXEL_MAX = 6'h3f;
reg [0:0] state;
reg [1:0] state_rfi;
reg [1:0] state_sp;
reg [5:0] pixel_counter;
reg [5:0] pixel_offset;
reg tx_valid;
reg [7:0] tx_byte;
reg tx_clear_cs;
wire tx_ready;
SPIMaster_341450853309219412 spi_master_inst(
.clock(clock),
.reset(reset),
.tx_ready(tx_ready),
.tx_valid(tx_valid),
.tx_byte(tx_byte),
.tx_clear_cs(tx_clear_cs),
.sclk(sclk),
.mosi(mosi),
.n_cs(n_cs)
);
always @(posedge clock) begin
if (reset) begin
state <= STATE_RESET_FRAME_INDEX;
pixel_counter <= 6'h0;
pixel_offset <= 6'h0;
tx_valid <= 1'b0;
tx_byte <= 8'h0;
tx_clear_cs <= 1'b0;
end else begin
if (state == STATE_RESET_FRAME_INDEX) begin
if (tx_ready == 1'b1) begin
// send command to reset frame index
tx_valid <= 1'b1;
tx_byte <= CMD_RESET_FRAME_INDEX;
tx_clear_cs <= 1'b1;
end else if (tx_valid == 1'b1) begin
// TX accepted, transition to next state
state <= STATE_SEND_PIXELS;
tx_valid <= 1'b0;
end
end else if (state == STATE_SEND_PIXELS) begin
if (tx_ready == 1'b1) begin
// send pixel data
tx_valid <= 1'b1;
tx_byte <= {2'b0, pixel_counter + pixel_offset};
if (pixel_counter == PIXEL_MAX) begin
// sending last pixel, so clear CS after
tx_clear_cs <= 1'b1;
end else begin
tx_clear_cs <= 1'b0;
end
end else if (tx_valid == 1'b1) begin
// TX accepted, transition to next state
tx_valid <= 1'b0;
if (pixel_counter == PIXEL_MAX) begin
// sending last pixel
state <= STATE_RESET_FRAME_INDEX;
pixel_counter <= 6'h0;
pixel_offset <= pixel_offset + 6'h1;
end else begin
pixel_counter <= pixel_counter + 6'h1;
end
end
end
end
end
endmodule
module user_module_341450853309219412(
input [7:0] io_in,
output [7:0] io_out
);
wire clock;
wire reset;
wire sclk;
wire mosi;
wire n_cs;
assign clock = io_in[0];
assign reset = io_in[1];
assign sclk = io_out[0];
assign mosi = io_out[1];
assign n_cs = io_out[2];
LEDMatrix_341450853309219412 ledmatrix_inst(
.clock(clock),
.reset(reset),
.sclk(sclk),
.mosi(mosi),
.n_cs(n_cs)
);
endmodule