Pārlūkot izejas kodu

Создан SPIm модуль

Anatoliy Chigirinskiy 1 gadu atpakaļ
vecāks
revīzija
c65083b537
4 mainītis faili ar 345 papildinājumiem un 0 dzēšanām
  1. 0 0
      src/src/SPI/SPIm.docx
  2. 100 0
      src/src/SPI/SPIm.v
  3. 150 0
      src/src/SPI/SPIm_tb.sv
  4. 95 0
      src/src/SPI/SPIs.v

+ 0 - 0
src/src/SPI/SPIm.docx


+ 100 - 0
src/src/SPI/SPIm.v

@@ -0,0 +1,100 @@
+module SPIm #(
+    parameter ssNum = 24
+)(
+    input Clk_i,
+    input Rst_i,
+    input Val_i,
+    input [ssNum-1:0] SpiData_i,
+
+    output Ss_o,
+    output Mosi_o,
+    output Sck_o,
+    output Busy_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+reg [6:0] ssCnt;
+reg [ssNum-1:0] mosiReg;
+reg             ssReg;
+
+reg startFlag;
+reg ssR;
+
+
+//================================================================================
+//  ASSIGNMENTS
+//================================================================================
+assign Ss_o = ssReg;
+assign Mosi_o = (!Ss_o) ? mosiReg[ssNum-1] : 1'b0;
+assign Sck_o = (!Ss_o) ? Clk_i : 1'b0;
+assign Busy_o = !Ss_o;
+
+//================================================================================
+//	CODING
+//================================================================================
+
+always @(negedge Clk_i) begin 
+    if (Rst_i) begin 
+        ssCnt <= 7'h0;
+    end
+    else begin 
+        if (ssCnt < ssNum && startFlag) begin
+            ssCnt <= ssCnt + 1;
+        end
+        else begin 
+            ssCnt <= 7'h0;
+        end
+    end
+end
+
+always @(posedge Clk_i) begin 
+    ssR <= ssReg;
+end
+
+always @(negedge Clk_i) begin 
+    if (Rst_i) begin 
+        mosiReg <= 0;
+    end
+    else begin 
+        if (!Ss_o) begin 
+            mosiReg <= mosiReg << 1;
+        end
+        else begin
+            if (Val_i) begin
+                mosiReg <= SpiData_i;
+            end
+        end
+    end
+end
+
+always @(*) begin 
+    if (Rst_i) begin 
+        startFlag <= 1'b0;
+    end
+    else begin 
+        if (Val_i) begin 
+            startFlag = 1'b1;
+        end
+        else if (ssReg && !ssR) begin 
+            startFlag = 1'b0;
+        end
+    end
+end
+
+always @(negedge Clk_i) begin 
+    if (Rst_i) begin 
+        ssReg <= 1'b1;
+    end
+    else begin 
+        if (ssCnt < ssNum && startFlag) begin 
+            ssReg <= 1'b0;
+        end
+        else begin 
+            ssReg <= 1'b1;
+        end
+    end
+end
+
+endmodule

+ 150 - 0
src/src/SPI/SPIm_tb.sv

@@ -0,0 +1,150 @@
+`timescale 1ns / 1ps
+module SPIm_tb;
+
+
+
+logic Clk_i;
+logic Rst_i;
+
+
+logic [23:0] spiData;
+
+
+localparam N = 16;
+
+
+
+logic [23:0] randData;
+
+logic [23:0] spiQueue [N-1:0];
+logic busyFromSpi;
+logic valToSpi;
+logic [4:0] numOfWords;
+
+logic sck;
+logic ss;
+logic mosi;
+
+//***********************************************
+//	            CLASSES
+//***********************************************
+
+class Packet;
+    rand bit [23:0] data;
+endclass
+
+Packet pkt;
+
+//***********************************************
+//	           CLOCK GENERATION
+//***********************************************
+
+always begin
+    #5 Clk_i = ~Clk_i;
+end
+
+
+
+
+//***********************************************
+//	           INITIALIZATION
+//***********************************************
+
+initial begin 
+    Clk_i =1'b1;
+    pkt = new();
+    Rst_i = 1'b1;
+    #50 Rst_i = 1'b0;
+    foreach(spiQueue[i]) begin
+        spiQueue[i] = $urandom();
+    end
+end
+
+always_ff @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        randData<=0;
+    end
+    else begin 
+        randData <= pkt.randomize(data);
+    end
+end
+
+always_ff @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        numOfWords<=5'h10;
+    end
+    else begin 
+        if (valToSpi) begin 
+            numOfWords <= numOfWords - 1;
+        end
+    end
+end
+
+always_ff @(posedge Clk_i) begin 
+    if (Rst_i) begin 
+        valToSpi <= 1'b0;
+    end
+    else begin 
+        if (!busyFromSpi && numOfWords != 0) begin 
+            valToSpi <= 1'b1;
+        end
+        else begin 
+            valToSpi <= 1'b0;
+        end
+    end
+end
+
+
+
+
+
+always_ff @(*) begin 
+    if (Rst_i) begin 
+        spiData=0;
+    end
+    else begin 
+        if (valToSpi) begin 
+            spiData = spiQueue[numOfWords-1];
+        end
+    end
+end
+
+
+
+//***********************************************
+//	           DUT INSTANTIATION
+//***********************************************
+
+SPIm DUT (
+    .Clk_i(Clk_i),
+    .Rst_i(Rst_i),
+    .SpiData_i(spiData),
+    .Val_i(valToSpi),
+    .Sck_o(sck),
+    .Ss_o(ss),
+    .Mosi_o(mosi),
+    .Busy_o(busyFromSpi)
+);
+
+
+SPIs SPIs_inst (
+    .Clk_i(Clk_i),
+    .Rst_i(Rst_i),
+    .Sck_i(sck),
+    .Ss_i(ss),
+    .Mosi0_i(mosi),
+    .DataToRxFifo_o(spiDataFromDUT),
+    .Val_o(valFromDUT)
+);
+
+
+
+
+
+
+
+
+
+
+
+endmodule

+ 95 - 0
src/src/SPI/SPIs.v

@@ -0,0 +1,95 @@
+module SPIs (
+    input Clk_i,
+    input Rst_i,
+
+    input Sck_i,
+    input Ss_i,
+    input Mosi0_i,
+
+    output reg [17:0] Data_o,
+    output reg [5:0] Addr_o,
+    output [23:0] DataToRxFifo_o,
+    output reg Val_o
+);
+
+//================================================================================
+//	REG/WIRE
+//================================================================================
+
+    reg ssReg;
+    reg ssRegR;  
+    reg [23:0] shiftReg;
+    
+ 
+
+//===============================================================================
+//  ASSIGNMENTS
+
+
+    assign DataToRxFifo_o = {Addr_o, Data_o};
+
+//================================================================================
+//	CODING
+//================================================================================
+
+    always	@(posedge	Clk_i)	begin
+    	ssReg	<=	Ss_i;
+    	ssRegR	<=	ssReg;
+    end
+
+
+
+
+    always @(posedge Clk_i) begin 
+        if (Rst_i) begin 
+            Data_o <= 18'h0;
+        end
+        else begin
+            if (ssReg && !ssRegR) begin 
+                Data_o <= shiftReg[17:0];
+            end
+        end
+    end
+
+    always @(posedge Clk_i) begin 
+        if (Rst_i) begin 
+            Addr_o <= 8'h0;
+        end
+        else begin 
+            if (ssReg && !ssRegR) begin 
+                Addr_o <= shiftReg[23:18];
+            end
+        end
+    end
+
+
+    always @(posedge Sck_i or posedge Rst_i) begin 
+        if (Rst_i) begin 
+            shiftReg<= 24'h0;
+        end
+        else begin  
+            if (!Ss_i) begin 
+                shiftReg<= {shiftReg[22:0], Mosi0_i};
+            end
+            else begin 
+                shiftReg<= 24'h0;
+            end
+        end
+    end
+    
+        
+
+
+    always @(posedge Clk_i) begin
+        if (ssReg && !ssRegR) begin 
+            Val_o <= 1'b1;
+        end
+        else begin 
+            Val_o <= 1'b0;
+        end
+    end
+
+
+
+
+    endmodule