mirror of
https://github.com/corundum/corundum.git
synced 2025-01-30 08:32:52 +08:00
Fix unaligned operation handling in AXI to AXIL adapter
Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
parent
211f674603
commit
7b2c99e731
@ -388,11 +388,11 @@ always @* begin
|
|||||||
burst_size_next = s_axi_arsize;
|
burst_size_next = s_axi_arsize;
|
||||||
if (s_axi_arsize > AXIL_BURST_SIZE) begin
|
if (s_axi_arsize > AXIL_BURST_SIZE) begin
|
||||||
// need to adjust burst size
|
// need to adjust burst size
|
||||||
if ({s_axi_arlen, {AXI_BURST_SIZE-AXIL_BURST_SIZE{1'b1}}} >> (AXI_BURST_SIZE-s_axi_arsize) > 255) begin
|
if (s_axi_arlen >> (8+AXIL_BURST_SIZE-s_axi_arsize) != 0) begin
|
||||||
// limit burst length to max
|
// limit burst length to max
|
||||||
master_burst_next = 8'd255;
|
master_burst_next = (8'd255 << (s_axi_arsize-AXIL_BURST_SIZE)) | ((~s_axi_araddr & (8'hff >> (8-s_axi_arsize))) >> AXIL_BURST_SIZE);
|
||||||
end else begin
|
end else begin
|
||||||
master_burst_next = {s_axi_arlen, {AXI_BURST_SIZE-AXIL_BURST_SIZE{1'b1}}} >> (AXI_BURST_SIZE-s_axi_arsize);
|
master_burst_next = (s_axi_arlen << (s_axi_arsize-AXIL_BURST_SIZE)) | ((~s_axi_araddr & (8'hff >> (8-s_axi_arsize))) >> AXIL_BURST_SIZE);
|
||||||
end
|
end
|
||||||
master_burst_size_next = AXIL_BURST_SIZE;
|
master_burst_size_next = AXIL_BURST_SIZE;
|
||||||
end else begin
|
end else begin
|
||||||
@ -422,13 +422,21 @@ always @* begin
|
|||||||
s_axi_rlast_next = 1'b0;
|
s_axi_rlast_next = 1'b0;
|
||||||
s_axi_rvalid_next = 1'b0;
|
s_axi_rvalid_next = 1'b0;
|
||||||
master_burst_next = master_burst_reg - 1;
|
master_burst_next = master_burst_reg - 1;
|
||||||
addr_next = addr_reg + (1 << master_burst_size_reg);
|
addr_next = (addr_reg + (1 << master_burst_size_reg)) & ({ADDR_WIDTH{1'b1}} << master_burst_size_reg);
|
||||||
|
m_axil_araddr_next = addr_next;
|
||||||
if (addr_next[burst_size_reg] != addr_reg[burst_size_reg]) begin
|
if (addr_next[burst_size_reg] != addr_reg[burst_size_reg]) begin
|
||||||
data_next = {DATA_WIDTH{1'b0}};
|
data_next = {DATA_WIDTH{1'b0}};
|
||||||
burst_next = burst_reg - 1;
|
burst_next = burst_reg - 1;
|
||||||
s_axi_rvalid_next = 1'b1;
|
s_axi_rvalid_next = 1'b1;
|
||||||
end
|
end
|
||||||
if (master_burst_reg == 0) begin
|
if (master_burst_reg == 0) begin
|
||||||
|
if (burst_next >> (8+AXIL_BURST_SIZE-burst_size_reg) != 0) begin
|
||||||
|
// limit burst length to max
|
||||||
|
master_burst_next = 8'd255;
|
||||||
|
end else begin
|
||||||
|
master_burst_next = (burst_next << (burst_size_reg-AXIL_BURST_SIZE)) | (8'hff >> (8-burst_size_reg) >> AXIL_BURST_SIZE);
|
||||||
|
end
|
||||||
|
|
||||||
if (burst_reg == 0) begin
|
if (burst_reg == 0) begin
|
||||||
m_axil_rready_next = 1'b0;
|
m_axil_rready_next = 1'b0;
|
||||||
s_axi_rlast_next = 1'b1;
|
s_axi_rlast_next = 1'b1;
|
||||||
@ -436,28 +444,11 @@ always @* begin
|
|||||||
s_axi_arready_next = !m_axil_arvalid;
|
s_axi_arready_next = !m_axil_arvalid;
|
||||||
state_next = STATE_IDLE;
|
state_next = STATE_IDLE;
|
||||||
end else begin
|
end else begin
|
||||||
// start new burst
|
|
||||||
m_axil_araddr_next = addr_next;
|
|
||||||
if (burst_size_reg > AXIL_BURST_SIZE) begin
|
|
||||||
// need to adjust burst size
|
|
||||||
if ({burst_next, {AXI_BURST_SIZE-AXIL_BURST_SIZE{1'b1}}} >> (AXI_BURST_SIZE-burst_size_reg) > 255) begin
|
|
||||||
// limit burst length to max
|
|
||||||
master_burst_next = 8'd255;
|
|
||||||
end else begin
|
|
||||||
master_burst_next = {burst_next, {AXI_BURST_SIZE-AXIL_BURST_SIZE{1'b1}}} >> (AXI_BURST_SIZE-burst_size_reg);
|
|
||||||
end
|
|
||||||
master_burst_size_next = AXIL_BURST_SIZE;
|
|
||||||
end else begin
|
|
||||||
// pass through narrow (enough) burst
|
|
||||||
master_burst_next = burst_next;
|
|
||||||
master_burst_size_next = burst_size_reg;
|
|
||||||
end
|
|
||||||
m_axil_arvalid_next = 1'b1;
|
m_axil_arvalid_next = 1'b1;
|
||||||
m_axil_rready_next = 1'b0;
|
m_axil_rready_next = 1'b0;
|
||||||
state_next = STATE_DATA;
|
state_next = STATE_DATA;
|
||||||
end
|
end
|
||||||
end else begin
|
end else begin
|
||||||
m_axil_araddr_next = addr_next;
|
|
||||||
m_axil_arvalid_next = 1'b1;
|
m_axil_arvalid_next = 1'b1;
|
||||||
m_axil_rready_next = 1'b0;
|
m_axil_rready_next = 1'b0;
|
||||||
state_next = STATE_DATA;
|
state_next = STATE_DATA;
|
||||||
|
@ -456,7 +456,7 @@ always @* begin
|
|||||||
m_axil_wvalid_next = 1'b1;
|
m_axil_wvalid_next = 1'b1;
|
||||||
burst_next = burst_reg - 1;
|
burst_next = burst_reg - 1;
|
||||||
burst_active_next = burst_reg != 0;
|
burst_active_next = burst_reg != 0;
|
||||||
addr_next = addr_reg + (1 << master_burst_size_reg);
|
addr_next = (addr_reg + (1 << master_burst_size_reg)) & ({ADDR_WIDTH{1'b1}} << master_burst_size_reg);
|
||||||
last_segment_next = addr_next[burst_size_reg] != addr_reg[burst_size_reg];
|
last_segment_next = addr_next[burst_size_reg] != addr_reg[burst_size_reg];
|
||||||
s_axi_wready_next = 1'b0;
|
s_axi_wready_next = 1'b0;
|
||||||
m_axil_bready_next = !s_axi_bvalid && !m_axil_awvalid;
|
m_axil_bready_next = !s_axi_bvalid && !m_axil_awvalid;
|
||||||
@ -472,7 +472,7 @@ always @* begin
|
|||||||
m_axil_wdata_next = data_reg >> (addr_reg[AXI_ADDR_BIT_OFFSET-1:AXIL_ADDR_BIT_OFFSET] * AXIL_DATA_WIDTH);
|
m_axil_wdata_next = data_reg >> (addr_reg[AXI_ADDR_BIT_OFFSET-1:AXIL_ADDR_BIT_OFFSET] * AXIL_DATA_WIDTH);
|
||||||
m_axil_wstrb_next = strb_reg >> (addr_reg[AXI_ADDR_BIT_OFFSET-1:AXIL_ADDR_BIT_OFFSET] * AXIL_STRB_WIDTH);
|
m_axil_wstrb_next = strb_reg >> (addr_reg[AXI_ADDR_BIT_OFFSET-1:AXIL_ADDR_BIT_OFFSET] * AXIL_STRB_WIDTH);
|
||||||
m_axil_wvalid_next = 1'b1;
|
m_axil_wvalid_next = 1'b1;
|
||||||
addr_next = addr_reg + (1 << master_burst_size_reg);
|
addr_next = (addr_reg + (1 << master_burst_size_reg)) & ({ADDR_WIDTH{1'b1}} << master_burst_size_reg);
|
||||||
last_segment_next = addr_next[burst_size_reg] != addr_reg[burst_size_reg];
|
last_segment_next = addr_next[burst_size_reg] != addr_reg[burst_size_reg];
|
||||||
s_axi_wready_next = 1'b0;
|
s_axi_wready_next = 1'b0;
|
||||||
m_axil_bready_next = !s_axi_bvalid && !m_axil_awvalid;
|
m_axil_bready_next = !s_axi_bvalid && !m_axil_awvalid;
|
||||||
@ -487,6 +487,7 @@ always @* begin
|
|||||||
|
|
||||||
if (m_axil_bready && m_axil_bvalid) begin
|
if (m_axil_bready && m_axil_bvalid) begin
|
||||||
first_transfer_next = 1'b0;
|
first_transfer_next = 1'b0;
|
||||||
|
m_axil_awaddr_next = addr_reg;
|
||||||
m_axil_bready_next = 1'b0;
|
m_axil_bready_next = 1'b0;
|
||||||
s_axi_bid_next = id_reg;
|
s_axi_bid_next = id_reg;
|
||||||
if (first_transfer_reg || m_axil_bresp != 0) begin
|
if (first_transfer_reg || m_axil_bresp != 0) begin
|
||||||
@ -494,7 +495,6 @@ always @* begin
|
|||||||
end
|
end
|
||||||
if (burst_active_reg || !last_segment_reg) begin
|
if (burst_active_reg || !last_segment_reg) begin
|
||||||
// burst on slave interface still active; start new burst
|
// burst on slave interface still active; start new burst
|
||||||
m_axil_awaddr_next = addr_reg;
|
|
||||||
m_axil_awvalid_next = 1'b1;
|
m_axil_awvalid_next = 1'b1;
|
||||||
if (last_segment_reg) begin
|
if (last_segment_reg) begin
|
||||||
s_axi_wready_next = !m_axil_wvalid;
|
s_axi_wready_next = !m_axil_wvalid;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user