Lots of progress on the rvvisynth to ethernet packetizer.

Almost producing axi4 commands.
This commit is contained in:
Rose Thompson 2024-05-21 18:23:42 -05:00
parent d1141237ee
commit b116c0c902
2 changed files with 204 additions and 0 deletions

153
src/wally/packetizer.sv Normal file
View File

@ -0,0 +1,153 @@
///////////////////////////////////////////
// packetizer.sv
//
// Written: Rose Thompson ross1728@gmail.com
// Created: 21 May 2024
// Modified: 21 May 2024
//
// Purpose: Converts the compressed RVVI format into AXI 4 burst write transactions.
//
// Documentation:
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module packetizer import cvw::*; #(parameter cvw_t P,
parameter integer MAX_CSRS)(
input logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi,
input logic valid,
input logic m_axi_aclk, m_axi_aresetn,
output logic RVVIStall,
// axi 4 write address channel
output logic [3:0] m_axi_awid,
output logic [12:0] m_axi_awaddr,
output logic [7:0] m_axi_awlen,
output logic [2:0] m_axi_awsize,
output logic [1:0] m_axi_awburst,
output logic [3:0] m_axi_awcache,
output logic m_axi_awvalid,
input logic m_axi_awready,
// axi 4 write data channel
output logic [31:0] m_axi_wdata,
output logic [3:0] m_axi_wstrb,
output logic m_axi_wlast,
output logic m_axi_wvalid,
input logic m_axi_wready,
// axi 4 write response channel
input logic [3:0] m_axi_bid,
input logic [1:0] m_axi_bresp,
input logic m_axi_bvalid,
output logic m_axi_bready,
// axi 4 read address channel
output logic [3:0] m_axi_arid,
output logic [12:0] m_axi_araddr,
output logic [7:0] m_axi_arlen,
output logic [2:0] m_axi_arsize,
output logic [1:0] m_axi_arburst,
output logic [3:0] m_axi_arcache,
output logic m_axi_arvalid,
input logic m_axi_arready,
// axi 4 read data channel
input logic [3:0] m_axi_rid,
input logic [31:0] m_axi_rdata,
input logic [1:0] m_axi_rresp,
input logic m_axi_rlast,
input logic m_axi_rvalid,
output logic m_axi_rready
);
localparam TotalFrameLengthBits = 2*48+32+16+187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12);
localparam TotalFrameLengthBytes = TotalFrameLengthBits / 8;
logic [9:0] WordCount;
logic [11:0] BytesInFrame;
logic TransReady;
logic BurstDone;
logic WordCountReset;
logic WordCountEnable;
logic [47:0] SrcMac, DstMac;
logic [31:0] Tag;
logic [15:0] Length;
logic [TotalFrameLengthBits-1:0] TotalFrame;
logic [31:0] TotalFrameWords [TotalFrameLengthBytes/4-1:0];
typedef enum {STATE_RDY, STATE_WAIT, STATE_TRANS, STATE_TRANS_DONE} statetype;
statetype CurrState, NextState;
always_ff @(posedge m_axi_aclk) begin
if(~m_axi_aresetn) CurrState <= STATE_RDY;
else CurrState <= NextState;
end
always_comb begin
case(CurrState)
STATE_RDY: if (TransReady & valid) NextState = STATE_TRANS;
else if(~TransReady & valid) NextState = STATE_WAIT;
STATE_WAIT: if(TransReady) NextState = STATE_TRANS;
else NextState = STATE_WAIT;
STATE_TRANS: if(BurstDone) NextState = STATE_RDY;
else NextState = STATE_TRANS;
default: NextState = STATE_RDY;
endcase
end
assign RVVIStall = CurrState != STATE_RDY;
assign TransReady = m_axi_awready & m_axi_wready;
assign WordCountEnable = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS & TransReady);
assign WordCountReset = CurrState == STATE_RDY;
counter #(10) WordCounter(m_axi_aclk, WordCountReset, WordCountEnable, WordCount);
// *** BUG BytesInFrame will eventually depend on the length of the data stored into the ethernet frame
// for now this will be exactly 608 bits (76 bytes, 19 words)
assign BytesInFrame = 12'd76;
assign BurstDone = WordCount == BytesInFrame[11:2];
assign m_axi_awid = '0;
assign m_axi_awaddr = '0; // *** bug update to be based on the correct address during each beat.
assign m_axi_awlen = BytesInFrame[11:2];
assign m_axi_awsize = 3'b010; // 4 bytes
assign m_axi_awburst = 2'b01; // increment
assign m_axi_awcache = '0;
assign m_axi_awvalid = (CurrState == STATE_RDY & valid) | CurrState == STATE_TRANS;
genvar index;
for (index = 0; index < TotalFrameLengthBytes/4; index++) begin
assign TotalFrameWords[index] = TotalFrame[(index*32)+32-1 : (index*32)];
end
assign TotalFrame = {rvvi, Length, Tag, DstMac, SrcMac};
// *** fix me later
assign SrcMac = '0;
assign DstMac = '0;
assign Tag = '0;
assign Length = BytesInFrame + 16'd6 + 16'd6 + 16'd4 + 16'd2;
assign m_axi_wdata = TotalFrameWords[WordCount];
assign m_axi_wstrb = '1;
assign m_axi_wlast = BurstDone;
assign m_axi_wvalid = (CurrState == STATE_RDY & valid) | (CurrState == STATE_TRANS);
assign m_axi_bready = 1'b1; // *** probably wrong.
// we aren't using the read channels. This ethernet device isn't going to read anything for now
assign {m_axi_arid, m_axi_araddr, m_axi_arlen, m_axi_arsize, m_axi_arburst, m_axi_arcache, m_axi_arvalid, m_axi_rready} = '0;
endmodule

View File

@ -95,5 +95,56 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
logic valid;
logic [187+(3*P.XLEN) + MAX_CSRS*(P.XLEN+12)-1:0] rvvi;
rvvisynth #(P, MAX_CSRS) rvvisynth(.clk, .reset, .valid, .rvvi);
logic [3:0] m_axi_awid;
logic [12:0] m_axi_awaddr;
logic [7:0] m_axi_awlen;
logic [2:0] m_axi_awsize;
logic [1:0] m_axi_awburst;
logic [3:0] m_axi_awcache;
logic m_axi_awvalid;
logic m_axi_awready;
// axi 4 write data channel
logic [31:0] m_axi_wdata;
logic [3:0] m_axi_wstrb;
logic m_axi_wlast;
logic m_axi_wvalid;
logic m_axi_wready;
// axi 4 write response channel
logic [3:0] m_axi_bid;
logic [1:0] m_axi_bresp;
logic m_axi_bvalid;
logic m_axi_bready;
// axi 4 read address channel
logic [3:0] m_axi_arid;
logic [12:0] m_axi_araddr;
logic [7:0] m_axi_arlen;
logic [2:0] m_axi_arsize;
logic [1:0] m_axi_arburst;
logic [3:0] m_axi_arcache;
logic m_axi_arvalid;
logic m_axi_arready;
// axi 4 read data channel
logic [3:0] m_axi_rid;
logic [31:0] m_axi_rdata;
logic [1:0] m_axi_rresp;
logic m_axi_rlast;
logic m_axi_rvalid;
logic m_axi_rready;
logic RVVIStall;
packetizer #(P, MAX_CSRS) packetizer(.rvvi, .valid, .m_axi_aclk(clk), .m_axi_aresetn(~reset), .RVVIStall,
.m_axi_awid, .m_axi_awaddr, .m_axi_awlen, .m_axi_awsize, .m_axi_awburst, .m_axi_awcache, .m_axi_awvalid,
.m_axi_awready, .m_axi_wdata, .m_axi_wstrb, .m_axi_wlast, .m_axi_wvalid, .m_axi_wready, .m_axi_bid,
.m_axi_bresp, .m_axi_bvalid, .m_axi_bready, .m_axi_arid, .m_axi_araddr, .m_axi_arlen, .m_axi_arsize,
.m_axi_arburst, .m_axi_arcache, .m_axi_arvalid, .m_axi_arready, .m_axi_rid, .m_axi_rdata, .m_axi_rresp,
.m_axi_rlast, .m_axi_rvalid, .m_axi_rready);
// *** finally fake the axi4 interface
assign m_axi_awready = '1;
assign m_axi_wready = '1;
endmodule