OpenCores
URL https://opencores.org/ocsvn/yifive/yifive/trunk

Subversion Repositories yifive

[/] [yifive/] [trunk/] [caravel_yifive/] [verilog/] [rtl/] [spi_master/] [src/] [spim_tx.sv] - Blame information for rev 21

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 18 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  SPI TX  Module                                              ////
4
////                                                              ////
5
////  This file is part of the YIFive cores project               ////
6
////  http://www.opencores.org/cores/yifive/                      ////
7
////                                                              ////
8
////  Description                                                 ////
9
////    This is SPI Master Transmit Word control logic.           ////
10
////    This logic transmit data upto 32 bit in bit or Quad spi   ////
11
////    mode                                                      ////
12
////                                                              ////
13
////  To Do:                                                      ////
14
////    nothing                                                   ////
15
////                                                              ////
16
////  Author(s):                                                  ////
17
////      - Dinesh Annayya, dinesha@opencores.org                 ////
18
////                                                              ////
19
////  Revision:                                                   ////
20
////       0.1 - 16th Feb 2021, Dinesh A                          ////
21
////             Initial version                                  ////
22
////       0.2 - 24th Mar 2021, Dinesh A                          ////
23
////             1. Comments are added                            ////
24
////             2. RTL clean-up done and the output are registred////
25
////                                                              ////
26
//////////////////////////////////////////////////////////////////////
27
////                                                              ////
28
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
29
////                                                              ////
30
//// This source file may be used and distributed without         ////
31
//// restriction provided that this copyright statement is not    ////
32
//// removed from the file and that any derivative work contains  ////
33
//// the original copyright notice and the associated disclaimer. ////
34
////                                                              ////
35
//// This source file is free software; you can redistribute it   ////
36
//// and/or modify it under the terms of the GNU Lesser General   ////
37
//// Public License as published by the Free Software Foundation; ////
38
//// either version 2.1 of the License, or (at your option) any   ////
39
//// later version.                                               ////
40
////                                                              ////
41
//// This source is distributed in the hope that it will be       ////
42
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
43
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
44
//// PURPOSE.  See the GNU Lesser General Public License for more ////
45
//// details.                                                     ////
46
////                                                              ////
47
//// You should have received a copy of the GNU Lesser General    ////
48
//// Public License along with this source; if not, download it   ////
49
//// from http://www.opencores.org/lgpl.shtml                     ////
50
////                                                              ////
51
//////////////////////////////////////////////////////////////////////
52
 
53
module spim_tx
54
(
55
    // General Input
56
    input  logic        clk,            // SPI clock
57
    input  logic        rstn,           // Active low Reset
58
    input  logic        en,             // Transmit Enable
59
    input  logic        tx_edge,        // Transmiting Edge
60
    output logic        tx_done,        // Transmission completion
61
    output logic        sdo0,           // SPI Dout0
62
    output logic        sdo1,           // SPI Dout1
63
    output logic        sdo2,           // SPI Dout2
64
    output logic        sdo3,           // SPI Dout3
65
    input  logic        en_quad_in,     // SPI quad mode indication
66
    input  logic [15:0] counter_in,     // Transmit counter
67
    input  logic [31:0] txdata,         // 32 bit tranmsit data
68
    input  logic        data_valid,     // Input data valid
69
    output logic        data_ready,     // Data in acepted, this for txfifo
70
    output logic        clk_en_o        // Enable Tx clock
71
);
72
 
73
  logic [31:0]          data_int       ; // Data Input
74
  logic [31:0]          data_int_next  ; // Next Data Input
75
  logic [15:0]          counter        ; // Tx Counter
76
  logic [15:0]          counter_next   ; // tx next counter
77
  logic [15:0]          counter_trgt   ; // counter exit counter
78
  logic                 tx32b_done     ;  // 32 bit Transmit done
79
  logic                 en_quad;
80
 
81
  enum logic [0:0] { IDLE, TRANSMIT } tx_CS, tx_NS;
82
 
83
 
84
  // Indicate 32 bit data done, usefull for readining next 32b from txfifo
85
  assign tx32b_done  = (!en_quad && (counter[4:0] == 5'b11111)) || (en_quad && (counter[2:0] == 3'b111)) && tx_edge;
86
 
87
 
88
 
89
  always_comb
90
  begin
91
    tx_NS         = tx_CS;
92
    data_int_next = data_int;
93
    data_ready    = 1'b0;
94
    counter_next  = counter;
95
 
96
    case (tx_CS)
97
      IDLE: begin
98
        data_int_next = txdata;
99 21 dinesha
        counter_next  = '0;
100 18 dinesha
 
101
        if (en && data_valid) begin
102
          data_ready    = 1'b1;
103
          tx_NS         = TRANSMIT;
104
        end
105
      end
106
 
107
      TRANSMIT: begin
108 21 dinesha
       counter_next = counter + 1;
109
       data_int_next = (en_quad) ? {data_int[27:0],4'b0000} : {data_int[30:0],1'b0};
110 18 dinesha
 
111 21 dinesha
      if (tx_done) begin
112 18 dinesha
            counter_next = 0;
113 21 dinesha
            // Check if there is next data
114 18 dinesha
            if (en && data_valid) begin
115
              data_int_next = txdata;
116
              data_ready    = 1'b1;
117
              tx_NS         = TRANSMIT;
118
            end else begin
119
              tx_NS    = IDLE;
120
            end
121 21 dinesha
      end else if (tx32b_done) begin
122 18 dinesha
            if (data_valid) begin
123
              data_int_next = txdata;
124
              data_ready    = 1'b1;
125
            end else begin
126
              tx_NS    = IDLE;
127
            end
128
        end
129
      end
130
    endcase
131
  end
132
 
133
  always_ff @(posedge clk, negedge rstn)
134
  begin
135
    if (~rstn)
136
    begin
137
      counter      <= 0;
138
      data_int     <= 'h0;
139
      tx_CS        <= IDLE;
140
      en_quad      <= 0;
141 21 dinesha
      tx_done      <= '0;
142
      clk_en_o     <= '0;
143
      sdo0         <= '0;
144
      sdo1         <= '0;
145
      sdo2         <= '0;
146
      sdo3         <= '0;
147
      counter_trgt <= '0;
148 18 dinesha
    end
149
    else
150
    begin
151
       if(tx_edge) begin
152
          counter      <= counter_next;
153
          data_int     <= data_int_next;
154
          sdo0         <= (en_quad_in) ? data_int_next[28] : data_int_next[31];
155 21 dinesha
          sdo1         <= (en_quad_in) ? data_int_next[29] : 1'b0;
156
          sdo2         <= (en_quad_in) ? data_int_next[30] : 1'b0;
157
          sdo3         <= (en_quad_in) ? data_int_next[31] : 1'b0;
158 18 dinesha
          tx_CS        <= tx_NS;
159
          en_quad      <= en_quad_in;
160 21 dinesha
          tx_done      <= (counter_next == (counter_trgt -1)) && (tx_NS == TRANSMIT);
161
          clk_en_o     <= (tx_NS == TRANSMIT);
162 18 dinesha
       end
163 21 dinesha
       // Counter Exit condition, quad mode div-4 , else actual counter
164
       if (en && data_valid) begin
165
          counter_trgt <= (en_quad_in) ? {2'b00,counter_in[15:2]} : counter_in;
166
       end
167
    end
168 18 dinesha
  end
169
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.