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

Subversion Repositories socgen

[/] [socgen/] [trunk/] [common/] [opencores.org/] [cde/] [ip/] [serial/] [rtl/] [verilog/] [serial_xmit.v] - Blame information for rev 131

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 131 jt_eaton
module
2
cde_serial_xmit
3
#(parameter   WIDTH=8,   // Number of data bits
4
  parameter   SIZE=4     // binary size of shift_cnt, must be able to hold  WIDTH + 4 states       
5
 )
6
 
7
 
8
(
9
input  wire              clk,
10
input  wire              reset,
11
input  wire              edge_enable,                 // one pulse per bit time for data rate timing
12
input  wire              parity_enable,               // 0 = no parity bit sent, 1= parity bit sent
13
input  wire              parity_type,                 // 0= odd,1=even
14
input  wire              parity_force,                // force parity_type
15
input  wire              load,                        // start transmiting data
16
input  wire              start_value,                 // value out at start bit time
17
input  wire              stop_value,                  // value out for stop bit also used for break
18
input  wire [WIDTH-1:0]  data,                        // data byte
19
 
20
output  reg              buffer_empty,                // ready for next byte
21
output  reg              ser_out                      // to pad_ring
22
                         );
23
 
24
reg [SIZE-1:0]            shift_cnt;
25
reg [WIDTH-1:0]   shift_buffer;
26
reg                      parity_calc;
27
reg                      delayed_edge_enable;
28
 
29
 
30
//
31
//   shift_cnt controls the serial bit out
32
//  
33
//   0           Start bit  
34
//   1-> WIDTH   Data bit lsb first
35
//   WIDTH+1     Parity bit if enabled
36
//   2^SIZE-1    Last stop bit and idle
37
 
38
always@(posedge clk)
39
  if(reset || buffer_empty)                                        shift_cnt   <= {SIZE{1'b1}};
40
  else
41
  if(!edge_enable)                                                 shift_cnt   <= shift_cnt;
42
  else
43
  if(( shift_cnt ==  {SIZE{1'b1}}  ) &&  ! buffer_empty )          shift_cnt   <= {SIZE{1'b0}};
44
  else
45
  if ( shift_cnt == WIDTH)
46
    case(parity_enable)
47
      (1'b0):                                                      shift_cnt   <= {SIZE{1'b1}};
48
      (1'b1):                                                      shift_cnt   <= shift_cnt + 1'b1;
49
    endcase // case ({two_stop_enable,parity_enable})
50
  else
51
  if ( shift_cnt == (WIDTH+1))                                     shift_cnt   <= {SIZE{1'b1}};
52
  else                                                             shift_cnt   <= shift_cnt + 1'b1;
53
 
54
//
55
//    
56
//   Clear buffer_empty upon load pulse
57
//   set it back at the start of the final stop pulse
58
//   if load happens BEFORE the next edge_enable then data transfer will have no pauses 
59
//   logic ensures that having load happen on a edge_enable will work
60
//   
61
 
62
always@(posedge clk)
63
   if(reset)                                                       delayed_edge_enable <= 1'b0;
64
   else                                                            delayed_edge_enable <= edge_enable && ! load;
65
 
66
 
67
always@(posedge clk)
68
if(reset)                                                          buffer_empty <= 1'b1;
69
else
70
if(load)                                                           buffer_empty <= 1'b0;
71
else
72
if((shift_cnt == {SIZE{1'b1}}) && delayed_edge_enable)
73
                                                                   buffer_empty <= 1'b1;
74
else                                                               buffer_empty <= buffer_empty;
75
 
76
 
77
 
78
 
79
 
80
//
81
//
82
//   load shift_buffer during start_bit
83
//   shift down every bit
84
//   
85
//   
86
always@(posedge clk)
87
  if(reset)                                                        shift_buffer <= {WIDTH{1'b0}};
88
  else
89
  if(load)                                                         shift_buffer <= data;
90
  else
91
  if(!edge_enable)                                                 shift_buffer <= shift_buffer;
92
  else
93
  if(shift_cnt == {SIZE{1'b1}})                                    shift_buffer <= shift_buffer;
94
  else
95
  if(shift_cnt == {SIZE{1'b0}})                                    shift_buffer <= shift_buffer;
96
  else                                                             shift_buffer <= {1'b0,shift_buffer[WIDTH-1:1]};
97
 
98
 
99
 
100
 
101
 
102
 
103
//
104
//
105
//   calculate parity on the fly
106
//   seed reg with 0 for odd and 1 for even
107
//   force reg to 0 or 1 if needed  
108
//   
109
always@(posedge clk)
110
  if(reset)                                                        parity_calc <= 1'b0;
111
  else
112
  if(!edge_enable)                                                 parity_calc <= parity_calc;
113
  else
114
  if(parity_force || (shift_cnt == {SIZE{1'b0}}))                  parity_calc <= parity_type;
115
  else                                                             parity_calc <= parity_calc ^ shift_buffer[0];
116
 
117
 
118
//   send start_bit,data,parity and stop  based on shift_cnt
119
 
120
 
121
   always@(posedge clk)
122
     if(reset)                                                     ser_out <= stop_value;
123
     else
124
     if( shift_cnt == {SIZE{1'b0}} )                               ser_out <= start_value;
125
     else
126
     if( shift_cnt == {SIZE{1'b1}} )                               ser_out <= stop_value;
127
     else
128
     if( shift_cnt == ({SIZE{1'b1}}+1'b1) )                        ser_out <= stop_value;
129
     else
130
     if( shift_cnt == (WIDTH+1) )                                  ser_out <= parity_calc;
131
     else                                                          ser_out <= shift_buffer[0];
132
 
133
 
134
endmodule
135
 
136
 
137
 

powered by: WebSVN 2.1.0

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