`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 01.09.2022 15:03:04 // Design Name: // Module Name: DspModel // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // // // 2BYTES ADDRESING // 0->2->4->6 // ////////////////////////////////////////////////////////////////////////////////// module DspSmcModel #( parameter DwordsNum = 5, parameter DataToClkRate = 4, //data changes every 4th clk negedge parameter SmcWrBaseAddr = 4, //data changes every 4th clk negedge parameter SmcRdBaseAddr = 1, //data changes every 4th clk negedge parameter [15:0] SmcBaseData = 16'h5, //data changes every 4th clk negedge parameter Offset = 2, //data changes every 4th clk negedge parameter WordsNum = 10 //data changes every 4th clk negedge ) ( input Clk120MHz_i, input RstN_i, inout [15:0] SmcD_o, output [10:0] SmcA_o, output SmcAwe_o, output SmcAmsN_o, output SmcAoe_o, output SmcAre_o, output [1:0] SmcBe_o, input Start_i ); //================================================================================ // REG/WIRE reg smcAmsN; reg smcAoe; reg smcAwe; reg smcAre; reg [1:0] smcBe; reg [1:0] writeSetupDelay; reg [1:0] writeAccessDelay; reg [1:0] writeHoldDelay; reg [1:0] transTurnDelay; reg [1:0] readSetupDelay; reg [1:0] readAccessDelay; reg [24:0] smcAddr; reg [15:0] smcData; reg [3:0] currState; reg [3:0] wordsCnt; wire txDone; //================================================================================ // LOCALPARAM localparam IDLE = 3'h0; localparam WriteSetup = 3'h1; localparam WriteAccess = 3'h2; localparam WriteHold = 3'h3; localparam TramsTurn = 3'h4; localparam ReadSetup = 3'h5; localparam ReadAccess = 3'h6; localparam ReadHold = 3'h7; //================================================================================ // ASSIGNMENTS assign SmcA_o = smcAddr; assign SmcD_o = (!SmcAre_o)? 15'bz:smcData; assign SmcAwe_o = smcAwe; assign SmcAmsN_o = smcAmsN; assign SmcAoe_o = smcAoe; assign SmcAre_o = smcAre; assign SmcBe_o = smcBe; assign txDone = wordsCnt==WordsNum-1; //================================================================================ // CODING always @(posedge Clk120MHz_i or negedge RstN_i) begin if (!RstN_i) begin wordsCnt <= 0; end else begin if (currState == TramsTurn) begin if (smcAmsN) begin if (wordsCnt!=WordsNum-1) begin wordsCnt <= wordsCnt+4'd1; end else begin wordsCnt <= 0; end end end end end always @(negedge Clk120MHz_i or negedge RstN_i) begin if (!RstN_i) begin currState <= 0; smcAddr <= 0; smcData <= 0; smcAmsN <= 1'b1; smcAoe <= 1'b1; smcAwe <= 1'b1; smcAre <= 1'b1; smcBe <= 2'b00; writeSetupDelay <= 2'b01; writeAccessDelay<= 4'b01; writeHoldDelay <= 2'b01; transTurnDelay <= 2'b01; readSetupDelay <= 3'b01; readAccessDelay <= 5'b01; end else begin case(currState) IDLE: begin if (Start_i) begin currState <= WriteSetup; smcAmsN <= 1'b0; smcAddr <= wordsCnt; smcData <= wordsCnt; smcAmsN <= 1'b0; smcAoe <= 1'b1; smcAre <= 1'b1; smcAwe <= 1'b1; smcBe <= 2'b00; end else begin currState <= IDLE; end end WriteSetup: begin if (writeSetupDelay[0]) begin currState <= WriteAccess; smcAwe <= 1'b0; writeSetupDelay <= 2'b01; end else begin currState <= WriteSetup; writeSetupDelay <= writeSetupDelay<<1; end end WriteAccess:begin if (writeAccessDelay[0]) begin currState <= WriteHold; writeAccessDelay<= 4'b0001; smcAwe <= 1'b1; end else begin currState <= WriteAccess; writeAccessDelay<= writeAccessDelay<<1; end end WriteHold :begin if (writeHoldDelay[0]) begin currState <= TramsTurn; writeHoldDelay<= 2'b01; smcAmsN <= 1'b1; end else begin currState <= WriteHold; writeHoldDelay<= writeHoldDelay<<1; end end TramsTurn :begin if (transTurnDelay[0]) begin if (!txDone) begin currState <= WriteSetup; smcAmsN <= 1'b0; smcAddr <= wordsCnt; smcData <= wordsCnt; smcAmsN <= 1'b0; smcAoe <= 1'b1; smcAre <= 1'b1; smcAwe <= 1'b1; smcBe <= 2'b00; end else begin currState <= ReadSetup; transTurnDelay<= 2'b01; smcAmsN <= 1'b0; smcAoe <= 1'b0; smcAddr <= SmcRdBaseAddr; end end else begin currState <= TramsTurn; transTurnDelay<= transTurnDelay<<1; end end ReadSetup :begin if (readSetupDelay[0]) begin currState <= ReadAccess; readSetupDelay<= 3'b001; smcAre <= 1'b0; end else begin currState <= ReadSetup; readSetupDelay <= readSetupDelay<<1; end end ReadAccess :begin if (readAccessDelay[0]) begin currState <= ReadHold; readAccessDelay<= 5'b00001; smcAre <= 1'b1; end else begin currState <= ReadAccess; readAccessDelay <= readAccessDelay<<1; end end ReadHold :begin currState <= IDLE; smcAmsN <=1'b1; smcAoe <= 1'b1; end endcase end end endmodule