1
0
mirror of https://github.com/corundum/corundum.git synced 2025-01-16 08:12:53 +08:00

fpga/mqnic/fb2CG: Update led_sreg_driver to support interleaving and bit reversal

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich 2023-04-27 01:03:44 -07:00
parent d6a24d22ab
commit 462d3c3a65
4 changed files with 72 additions and 58 deletions

View File

@ -528,35 +528,20 @@ assign qsfp_1_i2c_sda = qsfp_1_i2c_sda_t_reg ? 1'bz : qsfp_1_i2c_sda_o_reg;
wire [7:0] led_red;
wire [7:0] led_green;
wire [15:0] led_merged;
assign led_merged[0] = led_red[0];
assign led_merged[1] = led_green[0];
assign led_merged[2] = led_red[1];
assign led_merged[3] = led_green[1];
assign led_merged[4] = led_red[2];
assign led_merged[5] = led_green[2];
assign led_merged[6] = led_red[3];
assign led_merged[7] = led_green[3];
assign led_merged[8] = led_red[4];
assign led_merged[9] = led_green[4];
assign led_merged[10] = led_red[5];
assign led_merged[11] = led_green[5];
assign led_merged[12] = led_red[6];
assign led_merged[13] = led_green[6];
assign led_merged[14] = led_red[7];
assign led_merged[15] = led_green[7];
led_sreg_driver #(
.COUNT(16),
.COUNT(8),
.INVERT(1),
.REVERSE(0),
.INTERLEAVE(1),
.PRESCALE(63)
)
led_sreg_driver_inst (
.clk(pcie_user_clk),
.rst(pcie_user_reset),
.led(led_merged),
.led_a(led_red),
.led_b(led_green),
.sreg_d(led_sreg_d),
.sreg_ld(led_sreg_ld),

View File

@ -36,6 +36,10 @@ module led_sreg_driver #(
parameter COUNT = 8,
// invert output
parameter INVERT = 0,
// reverse order
parameter REVERSE = 0,
// interleave A and B inputs, otherwise only use A
parameter INTERLEAVE = 0,
// clock prescale
parameter PRESCALE = 31
)
@ -43,14 +47,16 @@ module led_sreg_driver #(
input wire clk,
input wire rst,
input wire [COUNT-1:0] led,
input wire [COUNT-1:0] led_a,
input wire [COUNT-1:0] led_b,
output wire sreg_d,
output wire sreg_ld,
output wire sreg_clk
);
localparam CL_COUNT = $clog2(COUNT+1);
localparam COUNT_INT = INTERLEAVE ? COUNT*2 : COUNT;
localparam CL_COUNT = $clog2(COUNT_INT+1);
localparam CL_PRESCALE = $clog2(PRESCALE+1);
reg [CL_COUNT-1:0] count_reg = 0;
@ -59,9 +65,9 @@ reg enable_reg = 1'b0;
reg update_reg = 1'b1;
reg cycle_reg = 1'b0;
reg [COUNT-1:0] led_sync_reg_1 = 0;
reg [COUNT-1:0] led_sync_reg_2 = 0;
reg [COUNT-1:0] led_reg = 0;
reg [COUNT_INT-1:0] led_sync_reg_1 = 0;
reg [COUNT_INT-1:0] led_sync_reg_2 = 0;
reg [COUNT_INT-1:0] led_reg = 0;
reg sreg_d_reg = 1'b0;
reg sreg_ld_reg = 1'b0;
@ -71,8 +77,16 @@ assign sreg_d = INVERT ? !sreg_d_reg : sreg_d_reg;
assign sreg_ld = sreg_ld_reg;
assign sreg_clk = sreg_clk_reg;
integer i;
always @(posedge clk) begin
led_sync_reg_1 <= led;
if (INTERLEAVE) begin
for (i = 0; i < COUNT; i = i + 1) begin
led_sync_reg_1[i*2 +: 2] <= {led_b[i], led_a[i]};
end
end else begin
led_sync_reg_1 <= led_a;
end
led_sync_reg_2 <= led_sync_reg_1;
enable_reg <= 1'b0;
@ -92,10 +106,14 @@ always @(posedge clk) begin
sreg_clk_reg <= 1'b0;
sreg_ld_reg <= 1'b0;
if (count_reg < COUNT) begin
if (count_reg < COUNT_INT) begin
count_reg <= count_reg + 1;
cycle_reg <= 1'b1;
if (REVERSE) begin
sreg_d_reg <= led_reg[COUNT_INT-1-count_reg];
end else begin
sreg_d_reg <= led_reg[count_reg];
end
end else begin
count_reg <= 0;
cycle_reg <= 1'b0;
@ -111,10 +129,14 @@ always @(posedge clk) begin
count_reg <= 1;
cycle_reg <= 1'b1;
if (REVERSE) begin
sreg_d_reg <= led_reg[COUNT_INT-1];
end else begin
sreg_d_reg <= led_reg[0];
end
end
end
end
if (led_sync_reg_2 != led_reg) begin
led_reg <= led_sync_reg_2;

View File

@ -535,35 +535,20 @@ assign qsfp_1_i2c_sda = qsfp_1_i2c_sda_t_reg ? 1'bz : qsfp_1_i2c_sda_o_reg;
wire [7:0] led_red;
wire [7:0] led_green;
wire [15:0] led_merged;
assign led_merged[0] = led_red[0];
assign led_merged[1] = led_green[0];
assign led_merged[2] = led_red[1];
assign led_merged[3] = led_green[1];
assign led_merged[4] = led_red[2];
assign led_merged[5] = led_green[2];
assign led_merged[6] = led_red[3];
assign led_merged[7] = led_green[3];
assign led_merged[8] = led_red[4];
assign led_merged[9] = led_green[4];
assign led_merged[10] = led_red[5];
assign led_merged[11] = led_green[5];
assign led_merged[12] = led_red[6];
assign led_merged[13] = led_green[6];
assign led_merged[14] = led_red[7];
assign led_merged[15] = led_green[7];
led_sreg_driver #(
.COUNT(16),
.COUNT(8),
.INVERT(1),
.REVERSE(0),
.INTERLEAVE(1),
.PRESCALE(63)
)
led_sreg_driver_inst (
.clk(pcie_user_clk),
.rst(pcie_user_reset),
.led(led_merged),
.led_a(led_red),
.led_b(led_green),
.sreg_d(led_sreg_d),
.sreg_ld(led_sreg_ld),

View File

@ -36,6 +36,10 @@ module led_sreg_driver #(
parameter COUNT = 8,
// invert output
parameter INVERT = 0,
// reverse order
parameter REVERSE = 0,
// interleave A and B inputs, otherwise only use A
parameter INTERLEAVE = 0,
// clock prescale
parameter PRESCALE = 31
)
@ -43,14 +47,16 @@ module led_sreg_driver #(
input wire clk,
input wire rst,
input wire [COUNT-1:0] led,
input wire [COUNT-1:0] led_a,
input wire [COUNT-1:0] led_b,
output wire sreg_d,
output wire sreg_ld,
output wire sreg_clk
);
localparam CL_COUNT = $clog2(COUNT+1);
localparam COUNT_INT = INTERLEAVE ? COUNT*2 : COUNT;
localparam CL_COUNT = $clog2(COUNT_INT+1);
localparam CL_PRESCALE = $clog2(PRESCALE+1);
reg [CL_COUNT-1:0] count_reg = 0;
@ -59,9 +65,9 @@ reg enable_reg = 1'b0;
reg update_reg = 1'b1;
reg cycle_reg = 1'b0;
reg [COUNT-1:0] led_sync_reg_1 = 0;
reg [COUNT-1:0] led_sync_reg_2 = 0;
reg [COUNT-1:0] led_reg = 0;
reg [COUNT_INT-1:0] led_sync_reg_1 = 0;
reg [COUNT_INT-1:0] led_sync_reg_2 = 0;
reg [COUNT_INT-1:0] led_reg = 0;
reg sreg_d_reg = 1'b0;
reg sreg_ld_reg = 1'b0;
@ -71,8 +77,16 @@ assign sreg_d = INVERT ? !sreg_d_reg : sreg_d_reg;
assign sreg_ld = sreg_ld_reg;
assign sreg_clk = sreg_clk_reg;
integer i;
always @(posedge clk) begin
led_sync_reg_1 <= led;
if (INTERLEAVE) begin
for (i = 0; i < COUNT; i = i + 1) begin
led_sync_reg_1[i*2 +: 2] <= {led_b[i], led_a[i]};
end
end else begin
led_sync_reg_1 <= led_a;
end
led_sync_reg_2 <= led_sync_reg_1;
enable_reg <= 1'b0;
@ -92,10 +106,14 @@ always @(posedge clk) begin
sreg_clk_reg <= 1'b0;
sreg_ld_reg <= 1'b0;
if (count_reg < COUNT) begin
if (count_reg < COUNT_INT) begin
count_reg <= count_reg + 1;
cycle_reg <= 1'b1;
if (REVERSE) begin
sreg_d_reg <= led_reg[COUNT_INT-1-count_reg];
end else begin
sreg_d_reg <= led_reg[count_reg];
end
end else begin
count_reg <= 0;
cycle_reg <= 1'b0;
@ -111,10 +129,14 @@ always @(posedge clk) begin
count_reg <= 1;
cycle_reg <= 1'b1;
if (REVERSE) begin
sreg_d_reg <= led_reg[COUNT_INT-1];
end else begin
sreg_d_reg <= led_reg[0];
end
end
end
end
if (led_sync_reg_2 != led_reg) begin
led_reg <= led_sync_reg_2;