forked from aolofsson/oh
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathoh_par2ser.v
73 lines (58 loc) · 2.4 KB
/
oh_par2ser.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
//#############################################################################
//# Function: Parallel to Serial Converter #
//#############################################################################
//# Author: Andreas Olofsson #
//# License: MIT (see LICENSE in OH! repositpory) #
//#############################################################################
module oh_par2ser #(parameter PW = 64, // parallel packet width
parameter SW = 1, // serial packet width
parameter CW = $clog2(PW/SW) // serialization factor
)
(
input clk, // sampling clock
input nreset, // async active low reset
input [PW-1:0] din, // parallel data
output [SW-1:0] dout, // serial output data
output access_out,// output data valid
input load, // load parallel data (priority)
input shift, // shift data
input [7:0] datasize, // size of data to shift
input lsbfirst, // lsb first order
input fill, // fill bit
input wait_in, // wait input
output wait_out // wait output (wait in | serial wait)
);
// local wires
reg [PW-1:0] shiftreg;
reg [CW-1:0] count;
wire start_transfer;
wire busy;
// start serialization
assign start_transfer = load & ~wait_in & ~busy;
//transfer counter
always @ (posedge clk or negedge nreset)
if(!nreset)
count[CW-1:0] <= 'b0;
else if(start_transfer)
count[CW-1:0] <= datasize[CW-1:0]; //one "SW sized" transfers
else if(shift & busy)
count[CW-1:0] <= count[CW-1:0] - 1'b1;
//output data is valid while count > 0
assign busy = |count[CW-1:0];
//data valid while shifter is busy
assign access_out = busy;
//wait until valid data is finished
assign wait_out = wait_in | busy;
// shift register
always @ (posedge clk or negedge nreset)
if(!nreset)
shiftreg[PW-1:0] = 'b0;
else if(start_transfer)
shiftreg[PW-1:0] = din[PW-1:0];
else if(shift & lsbfirst)
shiftreg[PW-1:0] = {{(SW){fill}}, shiftreg[PW-1:SW]};
else if(shift)
shiftreg[PW-1:0] = {shiftreg[PW-SW-1:0],{(SW){fill}}};
assign dout[SW-1:0] = lsbfirst ? shiftreg[SW-1:0] :
shiftreg[PW-1:PW-SW];
endmodule // oh_par2ser