////////////////////////////////////////////////////////// //CS150 Fall 2002 //Check Point 1 Solution // //Warning: //All copies of the code or subsections of the code in this file //which was not contained in the original skeleton file for use //in CS150 class must contain this header ////////////////////////////////////////////////////////// `include "phy_const.v" /////////////////////////////////////////////////////////// //Bytes come M.S.B. first, but the nibbles with in a byte //come L.S.Nibble first. Use this module to reverse the //nibble order. //Note: be aware that the last nibble within this "reordering" // shift register is not valid until both nibble of a byte // has been shifted in. /////////////////////////////////////////////////////////// module rx_shift(I, O, C, R); input [3:0] I; output [63:0] O; input C, R; reg [63:0] O; reg [3:0] tmp; reg lowerNibble; always @(posedge C) if (R) begin lowerNibble <= 1; O <= 0; tmp <= 0; end else if (lowerNibble) begin {O, tmp} <= {O[59:0], tmp, I}; lowerNibble <= 0; end else begin O <= {O[59:4] ,I ,tmp}; lowerNibble <= 1; end endmodule // rx_shift ////////////////////////////////////////////////////////// //the Receiver module ////////////////////////////////////////////////////////// module receiver (RX_DV, RX_ER, RX_CLK, RX_D, CHANNEL, MSG, RESET, DEBUG); input RX_DV, RX_ER, RX_CLK; input [3:0] RX_D; input [7:0] CHANNEL; output [63:0] MSG; input RESET; inout [31:0] DEBUG; ////////////////////////////////////////////////// //wire and reg declarations reg latchMsg; wire [63:0] result; wire latchResult; reg [63:0] accumData; wire accumRst; wire accumEn; wire [63:0] shiftRegData; reg shiftRegRst; wire [10:0] nibbleCnt; reg nibbleCntRst; reg crcRst; wire crcError; wire [3:0] crcDin; wire invalidMacType; wire invalidRtpType; wire invalidChannel; //////////////////////////////////////////////////// //packet cycle timing parameter parameter cycleMacType=28, cycleRtpType=32, cycleSSRC=52, cycleRstAccum=52, cycleEndOfPayLoad=1076, accumPeriodOffset=4; assign invalidMacType = (cycleMacType == nibbleCnt) & (shiftRegData[15:0] != `eTvMacType); assign invalidRtpType = (cycleRtpType == nibbleCnt) & (shiftRegData[6:0] != `ChkptRtpType); assign invalidChannel = (cycleSSRC == nibbleCnt) & (shiftRegData[7:0] != CHANNEL); assign accumEn = (accumPeriodOffset == nibbleCnt[3:0]); assign latchResult = (cycleEndOfPayLoad == nibbleCnt); assign accumRst = (cycleRstAccum == nibbleCnt); ///////////////////////////////////////////////////// //Datapath: rx_shift shft_reg(.I(RX_D), .O(shiftRegData), .C(RX_CLK), .R(RESET | shiftRegRst)); register #(64) msg_reg(.I(result), .O(MSG), .E(latchMsg), .R(RESET), .C(RX_CLK)); register #(64) result_reg(.I(accumData), .O(result), .E(latchResult), .R(RESET), .C(RX_CLK)); always @ (posedge RX_CLK) if (accumRst) accumData <= 0; else if (accumEn) accumData <= accumData + shiftRegData; counter #(11) nibbleCounter (.OUT(nibbleCnt), .CLK(RX_CLK), .ENABLE(1'b1), .RESET(nibbleCntRst | RESET)); eth_crc crc_inst(.Clk(RX_CLK), .Reset(crcRst | RESET), .Data({RX_D[0],RX_D[1],RX_D[2],RX_D[3]}), .Enable(1'b1), .Crc(crc), .CrcError(crcError)); ///////////////////////////////////////////////////// //FSM: //state parameters parameter [1:0] idle=0, receiving=1, receivingInvalid=2; reg [1:0] CS, NS; always @ (posedge RX_CLK) if (RESET) CS <= idle; else CS <= NS; /////////////////////////////////////////////// //next state logic always @ (/*AUTOSENSE*/CS or RX_D or RX_DV or crcError or invalidChannel or invalidMacType or invalidRtpType) begin //default FSM output//////////////////////// shiftRegRst <= 0; nibbleCntRst <= 0; crcRst <= 0; latchMsg <= 0; NS <= idle; ///////////////////////////////////////////// case (CS) /* synthesis full_case */ idle: begin if ((RX_D == `SFD) & RX_DV) begin NS <= receiving; crcRst <= 1; nibbleCntRst <= 1; shiftRegRst <= 1; end else NS <= idle; end receiving: begin if (~RX_DV) begin NS <= idle; if (~crcError) latchMsg <= 1; end else if (invalidMacType | invalidRtpType | invalidChannel) NS <= receivingInvalid; else NS <= receiving; end receivingInvalid: begin if (~RX_DV) NS <= idle; else NS <= receivingInvalid; end endcase // case(CS) end // always @ (... endmodule // receiver