本(běn)文(wén)为(wèi)明(míng)德揚原創文(wén)章(zhāng),轉(zhuǎn)载請注明(míng)出(chū)处!
本(běn)模块(kuài)的(de)功能(néng),是(shì)從一(yī)串輸入(rù)的(de)數據(jù)中(zhōng),檢测出(chū)指令头(tóu)55D5,檢测出(chū)包(bāo)文(wén)头(tóu)後(hòu),獲取(qǔ)到(dào)緊接着的(de)4个(gè)數據(jù)(2字(zì)节(jié)),并按字(zì)节(jié)为(wèi)單位送給(gěi)下(xià)遊模块(kuài)。指令头(tóu)和(hé)无效數據(jù)則丢棄。
輸入(rù)的(de)包(bāo)文(wén)指令格式:
輸入(rù)的(de)數據(jù)din为(wèi)4比特(tè),假設其依次(cì)輸入(rù):
5、5、d、5、0、2、9、9、1、5、5、d、5、0、1、0、3
其中(zhōng)前(qián)两(liǎng)个(gè)字(zì)节(jié)55d5就(jiù)表(biǎo)示指令头(tóu),後(hòu)一(yī)个(gè)字(zì)节(jié)02表(biǎo)示地(dì)址,再一(yī)个(gè)字(zì)节(jié)99表(biǎo)示數據(jù)。緊跟着後(hòu)面(miàn)的(de)1为(wèi)无效數據(jù),往後(hòu)又檢测到(dào)55d5,則01为(wèi)地(dì)址,03为(wèi)數據(jù)。把指令头(tóu)、无效的(de)數據(jù)过(guò)濾掉(即dout_vld为(wèi)0),最(zuì)終(zhōng)輸出(chū)以(yǐ)字(zì)节(jié)为(wèi)單位的(de)02、99、01、03。
一(yī)、設計(jì)架構
檢测出(chū)指令头(tóu)的(de)方(fāng)法如(rú)下(xià):
檢测出(chū)包(bāo)文(wén)头(tóu)後(hòu),需要(yào)对(duì)後(hòu)面(miàn)的(de)4个(gè)數據(jù)進(jìn)行計(jì)數。每2个(gè)數據(jù)組成(chéng)1个(gè)字(zì)节(jié),一(yī)共(gòng)有(yǒu)2个(gè)字(zì)节(jié)。所(suǒ)以(yǐ)指令檢测模块(kuài)采用(yòng)两(liǎng)个(gè)計(jì)數器的(de)結構,这(zhè)两(liǎng)个(gè)計(jì)數器分(fēn)别对(duì)應(yìng)接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)的(de)數據(jù)个(gè)數和(hé)接收(shōu)字(zì)节(jié)數,其結構图(tú)如(rú)下(xià)所(suǒ)示:
計(jì)數器cnt0:數據(jù)个(gè)數計(jì)數器。对(duì)接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)的(de)數據(jù)進(jìn)行計(jì)數,接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)2个(gè)數據(jù)。該計(jì)數器的(de)計(jì)數周期(qī)为(wèi)2。
計(jì)數器cnt1:字(zì)节(jié)數計(jì)數器。对(duì)接收(shōu)的(de)字(zì)节(jié)數進(jìn)行計(jì)數,地(dì)址加上(shàng)數據(jù)共(gòng)两(liǎng)个(gè)字(zì)节(jié)。該計(jì)數器的(de)計(jì)數周期(qī)为(wèi)2。
二(èr)、信(xìn)号(hào)的(de)意(yì)義
|
信(xìn)号(hào)
|
類(lèi)型
|
意(yì)義
|
|
clk
|
輸入(rù)信(xìn)号(hào)
|
时(shí)鐘(zhōng)信(xìn)号(hào)。
|
|
rst_n
|
輸入(rù)信(xìn)号(hào)
|
複位信(xìn)号(hào),低電(diàn)平有(yǒu)效。
|
|
din
|
輸入(rù)信(xìn)号(hào)
|
輸入(rù)的(de)數據(jù),位宽(kuān)为(wèi)4bit
|
|
din_vld
|
輸入(rù)信(xìn)号(hào)
|
輸入(rù)數據(jù)有(yǒu)效指示信(xìn)号(hào)。當其为(wèi)1时(shí),表(biǎo)示輸入(rù)的(de)數據(jù)有(yǒu)效,为(wèi)0时(shí)表(biǎo)示輸入(rù)數據(jù)无效。
|
|
dout
|
輸出(chū)信(xìn)号(hào)
|
輸出(chū)數據(jù),位宽(kuān)为(wèi)8bit(1字(zì)节(jié))。
設計(jì)邏輯:在(zài)取(qǔ)數據(jù)狀态时(shí),每2个(gè)數據(jù)拼接成(chéng)1字(zì)节(jié)輸出(chū)。
|
|
dout_vld
|
輸出(chū)信(xìn)号(hào)
|
輸出(chū)數據(jù)有(yǒu)效指示信(xìn)号(hào),位宽(kuān)为(wèi)1bit。
設計(jì)邏輯:在(zài)取(qǔ)數據(jù)狀态,每取(qǔ)到(dào)1个(gè)字(zì)节(jié)數據(jù)就(jiù)輸出(chū)1个(gè)有(yǒu)效指示停車。
|
|
cnt0
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
數據(jù)个(gè)數計(jì)數器。用(yòng)于(yú)对(duì)接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)的(de)數據(jù)个(gè)數進(jìn)行計(jì)數,接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)两(liǎng)个(gè)輸入(rù)數據(jù)。該計(jì)數器的(de)計(jì)數周期(qī)为(wèi)2。
|
|
add_cnt0
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
數據(jù)个(gè)數計(jì)數器加1条(tiáo)件(jiàn)。
設計(jì)邏輯:在(zài)取(qǔ)數據(jù)狀态,輸入(rù)有(yǒu)效此(cǐ)信(xìn)号(hào)就(jiù)有(yǒu)效。
|
|
end_cnt0
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
數據(jù)个(gè)數計(jì)數器的(de)結束(shù)条(tiáo)件(jiàn)。
設計(jì)邏輯:接收(shōu)一(yī)个(gè)字(zì)节(jié)需要(yào)两(liǎng)个(gè)數據(jù),所(suǒ)以(yǐ)數到(dào)两(liǎng)个(gè)就(jiù)結束(shù)。
|
|
cnt1
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
字(zì)节(jié)數計(jì)數器。用(yòng)于(yú)对(duì)地(dì)址和(hé)數據(jù)的(de)字(zì)节(jié)數進(jìn)行計(jì)數,地(dì)址和(hé)數據(jù)各(gè)占一(yī)个(gè)字(zì)节(jié)。該計(jì)數器的(de)計(jì)數周期(qī)为(wèi)2。
|
|
add_cnt1
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
字(zì)节(jié)數計(jì)數器加1条(tiáo)件(jiàn)。
設計(jì)邏輯:每接收(shōu)完1个(gè)字(zì)节(jié),此(cǐ)計(jì)數器就(jiù)加1。
|
|
end_cnt1
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
字(zì)节(jié)計(jì)數器結束(shù)条(tiáo)件(jiàn)。
設計(jì)邏輯:地(dì)址和(hé)數據(jù)共(gòng)两(liǎng)个(gè)字(zì)节(jié),所(suǒ)以(yǐ)數到(dào)两(liǎng)个(gè)就(jiù)結束(shù)。
|
|
din_tmp
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
輸入(rù)數據(jù)din的(de)寄存器信(xìn)号(hào)。位宽(kuān)为(wèi)12位,由(yóu)高(gāo)到(dào)低,每4位組成(chéng)一(yī)組數據(jù),分(fēn)别存儲的(de)din之前(qián)三(sān)个(gè)有(yǒu)效數據(jù)。詳细(xì)請看(kàn)設計(jì)架構部(bù)分(fēn)。
|
|
din_top
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
指令头(tóu)有(yǒu)效指示信(xìn)号(hào)。
設計(jì)邏輯:當前(qián)輸入(rù)數據(jù)和(hé)之前(qián)的(de)三(sān)个(gè)數據(jù)組成(chéng)55D5时(shí),就(jiù)表(biǎo)示檢测到(dào)指令头(tóu)。
|
|
flag_add
|
中(zhōng)間(jiān)信(xìn)号(hào)
|
取(qǔ)數據(jù)狀态指示信(xìn)号(hào)。當为(wèi)1时(shí),表(biǎo)示檢测到(dào)包(bāo)文(wén)头(tóu),此(cǐ)时(shí)处于(yú)取(qǔ)數據(jù)狀态。
設計(jì)邏輯:指令头(tóu)有(yǒu)效时(shí),就(jiù)變(biàn)1;當取(qǔ)完4个(gè)數據(jù)後(hòu)就(jiù)變(biàn)0。
|
三(sān)、參考代(dài)碼
|
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
|
module opcode_dect(
clk ,
rst_n ,
din ,
din_vld ,
dout_vld ,
dout
);
//參數定(dìng)義
parameter DOUT_W = 8;
parameter DIN_W = 4;
//輸入(rù)信(xìn)号(hào)定(dìng)義
input clk ;
input rst_n ;
input[DIN_W-1:0] din ;
input din_vld ;
wire [DIN_W-1:0] din ;
wire din_vld ;
//輸出(chū)信(xìn)号(hào)定(dìng)義
output[DOUT_W-1:0] dout ;
output dout_vld;
//輸出(chū)信(xìn)号(hào)reg定(dìng)義
reg [DOUT_W-1:0] dout ;
reg dout_vld;
//中(zhōng)間(jiān)信(xìn)号(hào)定(dìng)義
reg [2-1:0] cnt0;
wire add_cnt0;
wire end_cnt0;
reg [2-1:0] cnt1;
wire add_cnt1;
wire end_cnt1;
reg [11:0] din_tmp;
wire [15:0] din_top;
reg flag_add ;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 0;
else
cnt0 <= cnt0 + 1;
end
end
assign add_cnt0 = flag_add&&din_vld;
assign end_cnt0 = add_cnt0 && cnt0== 2-1;
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 0;
else
cnt1 <= cnt1 + 1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1== 2-1;
assign din_top = {din_tmp[11:0],din}==16'h55d5;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
flag_add <= 0;
end
else if(din_vld&&flag_add==0&&din_top)begin
flag_add <= 1;
end
else if(end_cnt1)begin
flag_add <= 0;
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
din_tmp <= 0;
end
else if(din_vld&&flag_add==0)begin
din_tmp <= {din_tmp[7:0],din};
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout <= 0;
end
else if(din_vld)begin
dout <= {dout[3:0],din};
end
end
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
dout_vld <= 1'b0;
end
else if(end_cnt0)begin
dout_vld <= 1'b1;
end
else begin
dout_vld <= 1'b0;
end
end
endmodule
|