forked from ianhchuang/EPC-Gen2-RFID-Tag-Baseband-Processor
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfm0_enc.v
129 lines (102 loc) · 2.98 KB
/
fm0_enc.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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/*
* FM0 Encoder
*
* By our algorithm, FM0 Encoder can operate in the lowest frequency
*
* The common way to encode FM0 is using clock in double BLF to determine the output sigal of each period
* Our Algorithm does not use the double-BLF clock, it only needs the clock in BLF
*
* The same concept is applied to design Miller Encoder
* The lowest operation frequency makes the Encoding save power dissipation
*
* If enable FM0 Encoder, disable Miller Encoder and vice versa
*/
`timescale 1us / 1ns
module fm0_enc
(
output fm0_data,
output fm0_complete,
input clk_fm0,
input rst_for_new_package,
input send_data,
input en_fm0,
input trext,
input st_enc,
input fg_complete
);
parameter GetData = 3'b000;
parameter Data0p = 3'b001;
parameter Data0n = 3'b010;
parameter Data1p = 3'b011;
parameter Data1n = 3'b100;
reg [2:0]ps; // present state
reg [2:0]ns; // next state
wire clk_fm0_n;
wire en_vcnt; // enable V counter
wire start_enc; // start FM0 encoding
wire send_v; // send V
wire m2o; // output of MUX 2
reg [1:0]data_select;
reg m1o; // output of MUX 1
reg [4:0]v_cnt; // V coumter
reg [1:0]fg_comp_cnt;
assign clk_fm0_n = ~clk_fm0;
assign start_enc = (ps != GetData)? 1'b1 : 1'b0;
assign en_vcnt = (start_enc & (v_cnt != 5'h11))? 1'b1 : 1'b0;
assign send_v = (~trext & (v_cnt == 5'h04))? 1'b1 :
(trext & (v_cnt == 5'h10))? 1'b1 : 1'b0;
assign m2o = send_v? 1'b0 : m1o;
assign fm0_data = (en_fm0 & ~fm0_complete)? m2o : 1'b0;
always@(posedge clk_fm0 or negedge rst_for_new_package) begin
if(~rst_for_new_package) ps <= GetData;
else if(st_enc) ps <= ns;
end
always@(*) begin
case(ps)
GetData : if(~en_fm0) ns = GetData;
else if(en_fm0 & (~send_data)) ns = Data0p;
else ns = Data1p;
Data0p : if(~send_data) ns = Data0p;
else ns = Data1p;
Data0n : if(~send_data) ns = Data0n;
else ns = Data1n;
Data1p : if(~send_data) ns = Data0n;
else ns = Data1n;
Data1n : if(~send_data) ns = Data0p;
else ns = Data1p;
default : ns = GetData;
endcase
end
always@(*) begin
case(ps)
GetData : data_select = 2'h0;
Data0p : data_select = 2'h3;
Data0n : data_select = 2'h2;
Data1p : data_select = 2'h1;
Data1n : data_select = 2'h0;
default : data_select = 2'h0;
endcase
end
always@(*) begin
case(data_select)
2'h0 : m1o = 1'b0;
2'h1 : m1o = 1'b1;
2'h2 : m1o = clk_fm0_n;
2'h3 : m1o = clk_fm0;
endcase
end
always@(posedge clk_fm0 or negedge rst_for_new_package) begin
if(~rst_for_new_package) v_cnt <= 5'h00;
else begin
if(st_enc & en_vcnt) v_cnt <= v_cnt + 5'h01;
end
end
always@(posedge clk_fm0 or negedge rst_for_new_package) begin
if(~rst_for_new_package) fg_comp_cnt <= 2'b0;
else begin
if(fg_comp_cnt == 2'b10) fg_comp_cnt <= fg_comp_cnt;
else if(en_fm0 & fg_complete) fg_comp_cnt <= fg_comp_cnt + 2'b1;
end
end
assign fm0_complete = (fg_comp_cnt == 2'b10)? 1'b1 : 1'b0;
endmodule