mirror of
				https://github.com/openhwgroup/cvw
				synced 2025-02-11 06:05:49 +00:00 
			
		
		
		
	Lots of progress on the rvvisynth to ethernet packetizer.
Almost producing axi4 commands.
This commit is contained in:
		
							parent
							
								
									d1141237ee
								
							
						
					
					
						commit
						b116c0c902
					
				
							
								
								
									
										153
									
								
								src/wally/packetizer.sv
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								src/wally/packetizer.sv
									
									
									
									
									
										Normal 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
 | 
			
		||||
 
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user