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

Subversion Repositories spacewire

[/] [spacewire/] [branches/] [ref/] [rtl/] [Transmitter.v] - Blame information for rev 27

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 btltz
//File name=Module=Transmitter  2005-2-18      btltz@mail.china.com    btltz from CASIC  
2
//Description:   Transmitter of the SpaceWire encoder-decoder.    
3
//Origin:        SpaceWire Std - Draft-1(Clause 8) of ECSS(European Cooperation for Space Standardization),ESTEC,ESA.
4
//--     TODO:   make the rtl faster
5
////////////////////////////////////////////////////////////////////////////////////
6
//
7
/*synthesis translate off*/
8
`timescale 1ns/100ps
9
/*synthesis translate on */
10
`define gFreq  80         //low frequence for fpga 
11
`define ErrorReset  6'b000001
12
`define ErrorWait   6'b000010
13
`define Ready       6'b000100
14
`define Started     6'b001000
15
`define Connecting  6'b010000
16
`define Run         6'b100000
17
`define reset  1          // WISHBONE standard reset
18
 
19
module Transmitter  //#(parameter DW=8)
20
                   (output reg Do,So,    //Transmitter data out & strobe out to LVDS driver                    
21
                          output reg err_crd_o,
22
// special input from the receiver
23
                    input gotFCT_i,   //Input from the Receiver
24
                                     //The transmitter is responsible for keeping track of the FCTs received
25
                    input nedsFCT_i,
26
                    output C_SEND_FCT_o, //output to the osd_cnt in the Rx      
27
                    input EnTx, //enable tx | disable tx
28
                    /*input Send_NULLS, Send_FCTs, Send_N_chars, Send_TIME_PATTERNs,*///Input from the PPU
29
   /***************  input AUTOSTART,   ********************/
30
//interface to the fifo
31
                    output rdbuf_o, //Output to the fifo
32
                    input empty_i,
33
                    input type_i,  //0(data) or 1(EOP or EEP)      
34
                    input [7:0] TxData_i,   //the data or control flag that need to be transmitted
35
                 //   input[7:0] Vec_Txfifo,  //the number of the vector of the Tx fifo 
36
//Time interface                   
37
                    input TICK_IN,//Only one node in a SpaceWire network should have an active TICK_IN signal.
38
                    input [1:0] CtrlFlg_i/* synthesis syn_keep=1 */, //two-bit control flag input.Reserved for future use.
39
                    input [5:0] TIMEin,
40
//Interface with register to show status or for control
41
                              output [5:0] CRD_CNT_O,
42
                                                  output [6:0]   STATE_O,
43
                                                //  input [31:0]SPE_CTL,
44
 
45
//global signal input
46
                    input[5:0] state_i,
47
                    input reset,   //this reset is from the CODEC FSM(the PPU)
48
                    input gclk /* synthesis syn_isclock = 1 */
49
                    );
50
 
51
parameter PaseW  = 14;   //The Width of the parallel-series convert register
52
                         //Reserve some to further
53
parameter True = 1;
54
parameter False = 0;
55
 
56
//Control characters.Go with a parity bit as their prefix(LSB).
57
parameter FCT  = 3'b001, ESC  = 3'b111,   //"L-Char":Link-characters. 
58
          EOP  = 3'b101, EEP  = 3'b011;   //or Data-Char are all "N-Char":Normal-characters
59
parameter NULL = 7'b0010_111;
60
parameter TIME_PATTERN = 5'b01111; //Go with a parity bit before and 8 bits time value from LSB 2 MSB after
61
 
62
               parameter StateNum = 7;
63
               parameter RESET        = 7'b0000001;
64
               parameter SEND_NULL    = 7'b0000010;
65
               parameter SEND_FCT     = 7'b0000100;
66
               parameter SEND_DATA    = 7'b0001000;
67
               parameter SEND_TIME        = 7'b0010000;
68
                                        parameter SEND_EOP     = 7'b0100000;
69
               parameter SEND_EEP     = 7'b1000000;  //EEP may be written into the transmitter interface
70
               parameter DEFLT        =    'bx;
71
 
72
               parameter CntW = 10;   //Max:1024.   This width could manipulate from 1G to 1M
73
 
74
                 parameter gFreq = `gFreq;
75
                 parameter RQ = 10;  //Required frequence for transmitting.
76
                 parameter divNum =  (gFreq==80 && RQ==10) ? 7  :
77
                                                              ( (gFreq==100 && RQ==10) ? 9  :
78
                                                                                                  ( (gFreq==120 && RQ==10) ? 11  :
79
                                                                                                   ( (gFreq==50  && RQ==10) ?  4 : 'bx  )))  ;
80
 
81
reg [PaseW-1:0] Pase;     //the parallel-series convert register
82
//reg [PaseW-1:0] Pase_;  //defined as reg for assignment.Synthesised as wire.Output of combinatorial logic
83
 
84
reg C_SEND_TIME;  //pulse command for sending a time code(2 byte)
85
reg C_SEND_FCT;   //pulse command for sending a FCT(1 byte)
86
reg C_SEND_DATA;  //pulse command for sending a DATA(read from fifo,1 byte)
87
reg C_SEND_EOP;   //pulse command for sending a EOP with a type indication from host "type_i"
88
reg C_SEND_EEP;   //pulse command for sending a EEP with a type indication from host "type_i"
89
reg C_SEND_NULL;  //pulse command for sending a NULL for link activation(1 byte)
90
assign C_SEND_FCT_o = C_SEND_FCT;
91
 
92
reg [5:0] crd_cnt; //a credit count of the number of characters it has been given permission to send.
93
                   //indicates the buffer space of the opposite Rx buffer in annother node 
94
reg p;             //The parity bit
95
reg StartSend;
96
reg [StateNum-1:0] state, next_state/* synthesis syn_encoding="safe,onhot" */;
97
assign STATE_O = state;
98
 
99
wire Sending = StartSend && ( (state_i == `Run)||(state == `Connecting)||(state == `Started ));
100
wire C_SEND_Nchar = C_SEND_DATA || C_SEND_EOP || C_SEND_EEP;
101
//................................................................................................
102
////////////////////////
103
//The Tx clk generator: 
104
// Responsible for producing the variable data signalling clock signals used by the transmitter.    
105
// Due to the use of a global clock in FPGAs , this block is really generating pulse for operation.
106
//
107
reg strobe;  //output pulse to the internal of this transmitter  
108
reg [CntW-1:0] divcnt;
109
 
110
//After a reset or disconnect initially commence operating at (10¡À1) Mb/s.
111
//Once in the Run state the transmitter operating rate can be set at any rate between max and min
112
always @(posedge gclk)
113
begin
114
 if(reset)
115
   begin {divcnt,strobe} <= 0; end
116
 else if(state_i==`Run || state_i==`Connecting || state_i==`Started)
117
        begin
118
                      if(divcnt == divNum)
119
               begin   divcnt <= 0;  strobe <= 1;   end
120
            else
121
               begin   divcnt <= divcnt + 1; strobe <= 0;  end
122
        end
123
end
124
/*...............................................................................................
125
///////////////////////////
126
// Input Signal Processing
127
//
128
wire gotFCT;                             //wire is output of this Unit
129
reg Pro_gotFCT;
130
always @(posedge gclk)
131
begin
132
if(reset) begin
133
  Pro_gotFCT <= 1'b0;
134
  Pro_nedsFCT <= 1'b1;  end
135
else
136
  begin
137
  Pro_gotFCT <= gotFCT_i;
138
  Pro_nedsFCT <= nedsFCT_i;
139
  end
140
assign nedsFCT = nedsFCT_i && !Pro_ceasFCT;
141
assign gotFCT  = got_FCT_i && !Pro_gotFCT; */
142
wire gotFCT = gotFCT_i;             //gotFCT_i is a pulse
143
wire nedsFCT = nedsFCT_i;                //nedsFCT_i is a level 
144
 
145
/////////////////////////////
146
//Send model control counter
147
//all data send behavior is controlled 
148
//
149
reg [3:0] mccnt;
150
reg scover_pre;  //overflow of the model control counter
151
always @(posedge gclk)
152
begin
153
  if (reset)
154
      begin
155
                mccnt <= 0;
156
                scover_pre <= 0;
157
                end
158
  else    begin
159
          scover_pre <= 0;
160
                         if  (strobe &&
161
                               mccnt==(     (state==SEND_TIME) ?  12   :   //14 bit time-code
162
                           ( (state==SEND_FCT)  ?   2   :   //4 bit FCT
163
                           ( (state==SEND_NULL) ?   6   :   //8 bit NULL
164
                           ( (state==SEND_DATA) ?   8   :
165
                                                              ( (state==SEND_EOP || state==SEND_EEP) ? 2  : 'bx  //4 bit EOP/EEP or 10 bit data 
166
                           ))))) )
167
          scover_pre <= 1;  //this overflow signal is just 1 gclk width
168
                         //else
169
                         //scover_pre <= 0;
170
 
171
         if(strobe && (state_i != `ErrorWait || state_i != `ErrorReset || state_i != `Ready) ) //if strobe ,count
172
                            begin
173
                                 if( mccnt==( (state==SEND_TIME) ?  13   :   //14 bit time-code
174
                     ( (state==SEND_FCT)  ?   3   :   //4 bit FCT
175
                     ( (state==SEND_NULL) ?   7   :   //8 bit NULL
176
                     ( (state==SEND_DATA) ?   9   :     3 )      //4 bit EOP/EEP or 10 bit data 
177
                                                          //(state==SEND_EOP || state==SEND_EEP) 9  
178
                      ))) )
179
             mccnt <= 0;
180
             else
181
             mccnt <= mccnt + 1'b1;
182
                                 end
183
         end
184
end
185
 
186
//////////////////////////////
187
// Read synfifo synchronously
188
//
189
wire BUF_HAS_NCHAR = !empty_i;
190
assign rdbuf_o = (state_i==`Run &&  !TICK_IN && crd_cnt==0 && BUF_HAS_NCHAR) ? scover_pre : 0;
191
 
192
///////////////////////////
193
// DS Output and DS Encode 
194
//
195
reg Do_;
196
always @(posedge gclk)
197
begin
198
if(reset || state==RESET)
199
StartSend <=0;
200
else if(C_SEND_NULL)
201
StartSend <= 1'b1;
202
end
203
 
204
wire Do_gen = (scover_pre==True)  ? p : omux(mccnt,Pase);
205
 
206
always @(posedge gclk)
207
 if(reset) begin
208
          Do <= 1'b0;//After reset or link error the Data and Strobe signals shall be set to zero.
209
                    //avoiding simultaneous transitions of Data and Strobe signals.
210
          So <= 1'b0;    end
211
 else  begin
212
       Do_ <= Do;    //Do_ is a IMMEDIATE trace of Do 
213
       if(EnTx && StartSend && strobe)   //to avoid send unwritten "Pase"(blank "Pase")
214
         begin
215
                        Do <= Do_gen;   //ref the function at bottom 
216
                   if(Do_gen==Do_)
217
         So <= !So;   //Data-Strobe (DS) encoding.The Strobe signal.Change state whenever the Data does not change from one bit to the next.
218
         end
219
                 end
220
/////////////////////
221
//Parity Gen
222
//                
223
always @(posedge gclk)
224
if(reset) // fisrt p is 0
225
 p <= 1'b0;
226
else if(  (state_i==`Started || state_i==`Connecting || state_i==`Run) && scover_pre)
227
 p <= 1'b1;
228
//if(C_SEND_TIME || C_SEND_FCT || C_SEND_Nchar || C_SEND_NULL) 
229
else if(strobe && Sending)
230
 p <= p ^ Pase[mccnt];  // <- |0|1|2|3|4|5|6|7|
231
 
232
   /////////////////////////////
233
  // crd_cnt:   Credit Counter
234
 //        and err_crd_o made
235
////////////////////////////////
236
//If the credit error occurs in the Run state then the credit error shall be flagged up to the Network Level as a "link error"
237
wire ceasNchar = (crd_cnt==0);          //cease sending Normal char if the opsite Rx has no space any more
238
always @(posedge gclk)
239
begin
240
if(reset)
241
  begin
242
  crd_cnt <= 0; //In PPUstate== ErrorReset the credit count shall be set to zero
243
  err_crd_o <= 0;
244
  end                    //And if PPUstate==ErrorWait   or Started,a FCT also reset the PPU and Tx 
245
else begin
246
     if(gotFCT)
247
     begin
248
       err_crd_o <= 0;
249
       if(crd_cnt>48) /*48+8=56*/ //because 56+8>63
250
       err_crd_o <= 1;
251
       else
252
       crd_cnt <= crd_cnt + 8;//..receives an FCT the transmitter shall increment the credit count by eight.
253
     end
254
     else if(crd_cnt != 0 && ( C_SEND_Nchar ) )
255
          begin
256
          crd_cnt <= crd_cnt - 1;  //If the credit count reaches zero the transmitter shall cease sending N_char(and the cnt keep on zero)
257
          err_crd_o <= 0;
258
               end
259
     end
260
end
261
assign CRD_CNT_O = crd_cnt;
262
 
263
///////////////////////////////
264
//Parallelly write Pase 
265
//
266
always@(posedge gclk)
267
begin:WRT_Pase
268
if(reset || state==RESET)
269
   Pase <= 0;//after reset the first bit that is sent shall be a parity bit, this bit shall be set to zero
270
else if(EnTx && (C_SEND_TIME || C_SEND_FCT || C_SEND_Nchar || C_SEND_NULL)  )
271
  begin //When writing to the transmit interface the remaining data bits should be set to zero.
272
         case(1'b1)   /* synthesis parallel_case*/
273
   C_SEND_TIME    :  Pase[13:0] <= {CtrlFlg_i,TIMEin[5:0],TIME_PATTERN,p};  //send system time. TIME = ESC + time code
274
                  //The MSB two bits of the time input are the two control-flag inputs and are reserved for future use.
275
   C_SEND_DATA    :  Pase[9:0] <= {TxData_i,1'b0,p};     //10 bit
276
        C_SEND_FCT     :  Pase[3:0] <= {FCT,p};  //4 bit "L-Char":
277
        C_SEND_EEP     :  Pase[3:0] <= {EOP,p};  //4 bit
278
   C_SEND_EOP     :  Pase[3:0] <= {EEP,p};  //4 bit
279
   C_SEND_NULL    :  Pase[7:0] <= {NULL,p}; //4 bit + 4 bit = 7+1; a NULL = a ESC + a FCT
280
    default       :  Pase[13:0] <=  'bx;    //for simulation 
281
    endcase
282
  end
283
end //end WRT_Pase              
284
 
285
////////////////////////
286
//Fsm for control
287
//          Moore style
288
always @(posedge gclk)
289
if(reset==`reset)
290
  state <= RESET;   //Initialized state
291
else if(scover_pre)     // Too fast     state gen will cause problems
292
  state <= next_state;
293
//------ next_state assignment
294
always @(*)
295
begin:NEXT_ASSIGN
296
  //Default Values for FSM outputs:
297
    C_SEND_TIME = 0;
298
         C_SEND_DATA = 0;
299
    C_SEND_FCT = 0;
300
    C_SEND_EOP = 0;
301
    C_SEND_EEP = 0;
302
         C_SEND_NULL = 0;
303
   //rdbuf_o = 0;
304
  //Use "Default next_state" style ->
305
    next_state = state;
306
      case(state)   /* synthesis parallel_case */
307
  RESET        :     begin
308
                       if(state_i==`Started)
309
                         next_state = SEND_NULL;
310
                      end
311
  SEND_NULL/*4th*/: begin  //This state only send NULL on the link and doing nothing else
312
          /*output*/ C_SEND_NULL = 1'b0;
313
                                   if(scover_pre)
314
                       C_SEND_NULL = 1'b1;  //when has sended 8, send another NULL
315
   /*state control*/if(state_i==`Run)
316
                       begin
317
                          if(TICK_IN==True)
318
                             next_state = SEND_TIME;  //1st                                          
319
                                                                  else if(nedsFCT)
320
                             next_state = SEND_FCT;   //2nd     
321
                          else if( empty_i==False && ceasNchar==False )
322
                                                                       begin
323
                                                                                 if(type_i==0)
324
                                  next_state = SEND_DATA;
325
                               else if(TxData_i[0]==0)
326
                                  next_state = SEND_EOP;
327
                               else if(TxData_i[0]==1)
328
                                                                                         next_state = SEND_EEP;
329
                                                                                 end
330
                          //else  no time,no fct,no data, keep send "NULL"
331
                       end//end "state_i==Run"
332
                     else if(state_i==`Connecting && nedsFCT)
333
                             next_state = SEND_FCT;  //higher priority 
334
                                                                          //else no FCT,keep send "NULL" to wait a "FCT" coming  
335
                     else if(state_i==`Ready || state_i==`ErrorWait)
336
                             next_state = RESET;  //err recovery                   
337
                     end
338
  SEND_FCT/*2nd*/:   begin   //each FCT = 8 N_char   
339
                     C_SEND_FCT = 1'b0;
340
          /*output*/ if(scover_pre)  //***
341
                        C_SEND_FCT = 1'b1;  //command for wrt reg "Pase"
342
   /*state control*/ if(state_i==`Run)
343
                             begin
344
                        if(TICK_IN==True)
345
                             next_state = SEND_TIME; //1st                        
346
                        else if(nedsFCT==False)
347
                                                                     begin
348
                                                                     if(ceasNchar || empty_i==True)
349
                                                                     next_state = SEND_NULL;
350
                                                                     else if(type_i==0)  //empty_i==False
351
                             next_state = SEND_DATA;
352
                                                                     else if(TxData_i[0]==0)  //type_i==1                                                                                                                                                         
353
                             next_state = SEND_EOP;
354
                             else //TxData_i[0]==1                                                                                                       
355
                                                                     next_state = SEND_EEP;
356
                                                                          end
357
                                                                end
358
                      else if(state_i==`Connecting)
359
                                                              begin
360
                                                                        if(nedsFCT==False)//needn't to send FCT any more 
361
                                                                     next_state = SEND_NULL;
362
                                                                        end
363
                      else      //state != Run or Connecting 
364
                           next_state = RESET; //if not in Run || Connecting and enter this state,there must be a err
365
                     end
366
  SEND_TIME/*1st*/:    begin
367
             /*output*/if(scover_pre)  //***
368
                            C_SEND_TIME = 1'b1;   //command for wrt reg "PaSe".priority 1
369
   /*state control*/   if(state_i == `Run)
370
                       begin
371
                         if(TICK_IN == False)
372
                           begin
373
                             if( nedsFCT )   //needn't send FCTs or data any more
374
                               next_state = SEND_FCT;    //2nd  
375
                             else if (ceasNchar || empty_i==True)
376
                                                                          next_state = SEND_NULL;
377
                             else if(type_i==0)   //crd_cnt==0 && empty_i==False 
378
                                                                          next_state = SEND_DATA;
379
                             else if(TxData_i[0]==0)//type_i==1 
380
                             next_state = SEND_EOP;
381
                             else //(TxData_i[0]==1)                                                                                                     
382
                                                                          next_state = SEND_EEP;
383
                            end
384
                          //else if TICK_IN==True, keep send time
385
                       end //end  state_i == Run
386
                       else //if not in Run state and enter this state,return to RESET
387
                           next_state = RESET;
388
                     end
389
  SEND_DATA/*3rd*/: begin  //data or EOP or EEP from host interface 
390
          /*output*/C_SEND_DATA = 1'b0;
391
                                        if(scover_pre)
392
                    C_SEND_DATA = 1'b1;
393
      /*state control*/if(state_i==`Run)
394
                          begin
395
                             if(TICK_IN==True)
396
                                next_state = SEND_TIME;  //1st
397
                             else if(nedsFCT)
398
                             next_state = SEND_FCT;  //higher priority
399
                             else if ( ceasNchar || empty_i==True)
400
                                                                          next_state = SEND_NULL;
401
                             else if(type_i==1)
402
                                                                               begin
403
                                  if(TxData_i[0]==0)  //if not TICK_IN and crd_cnt==0 and empty
404
                                    next_state = SEND_EOP;
405
                                  else //(TxData_i[0]==1)                                                                                                        
406
                                                                                      next_state = SEND_EEP;
407
                                                                                         end
408
                             //else,keep                          
409
                           end //end state_i==Run
410
                        else  //if not in Run and enter this state, there must be a error
411
                           next_state = RESET;
412
                     end
413
  SEND_EOP               :  begin
414
            /*output*/ C_SEND_EOP = 1'b0;
415
                                           if(scover_pre)
416
                           C_SEND_EOP = 1'b1;
417
      /*state control*/if(state_i==`Run)
418
                          begin
419
                             if(TICK_IN==True)
420
                             next_state = SEND_TIME;  //1st
421
                             else if(nedsFCT)
422
                             next_state = SEND_FCT;  //higher priority
423
                             else if(ceasNchar || empty_i==True)
424
                                                                          next_state = SEND_NULL;
425
                             else if(type_i==0)
426
                                                                             next_state = SEND_DATA;
427
                             else if(TxData_i[0]==1)
428
                                                                             next_state = SEND_EEP;
429
                             //else,keep                          
430
                           end  //end state_i == Run
431
                        else  //if not in Run and enter this state, there must be a error
432
                           next_state = RESET;
433
                   end
434
  SEND_EEP      :  begin
435
                      C_SEND_EEP = 1'b0;
436
                     if(scover_pre)
437
                                                            C_SEND_EEP = 1'b1;
438
      /*state control*/if(state_i==`Run)
439
                          begin
440
                             if(TICK_IN==True)
441
                                next_state = SEND_TIME;  //1st
442
                             else if(nedsFCT)
443
                                next_state = SEND_FCT;  //2nd
444
                             else if(ceasNchar || empty_i==True) //if not TICK_IN and crd_cnt==0 and empty
445
                                next_state = SEND_NULL;
446
                             else if(type_i==0)
447
                                                                             next_state = SEND_DATA;
448
                             else if(TxData_i[0]==0)
449
                                                                             next_state = SEND_EOP;
450
                             //else,keep                          
451
                           end  //end state_i == Run
452
                        else  //if not in Run and enter this state, there must be a error
453
                           next_state = RESET;
454
                   end
455
 
456
    default     :    next_state = DEFLT;
457
   endcase
458
end //end combinatorial block "NEXT_ASSIGN"
459
 
460
 
461
function omux; //parellel to serial conversion,use a mux
462
   input [3:0] mccnt;
463
   input [PaseW-1:0] Pase;
464
begin
465
   omux = Pase[mccnt];
466
end
467
endfunction
468
 
469
/*
470
                 //   //1. Time-Code, highest priority;
471
                //   //2. FCTs, high priority;
472
                   //   //3. N-Chars,low priority;
473
                  //   //4. NULL, lowest priority.         */
474
endmodule
475
 
476
`undef gFreq
477
`undef ErrorReset
478
`undef ErrorWait
479
`undef Ready
480
`undef Started
481
`undef Connecting
482
`undef Run
483
`undef reset

powered by: WebSVN 2.1.0

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