[經驗] 邊緣檢測項目:指令檢測模塊代碼解析

邊緣檢測項目:指令檢測模塊代碼解析

本文爲明德揚原創文章,禁止轉載

本模塊的功能,是從一串輸入的數據中,檢測出指令頭55D5,檢測出包文頭後,獲取到緊接着的4個數據(2字節),並按字節爲單位送給下游模塊。指令頭和無效數據則丟棄。

輸入的包文指令格式:

在這裏插入圖片描述
輸入的數據din爲4比特,假設其依次輸入:

5、5、d、5、0、2、9、9、1、5、5、d、5、0、1、0、3

其中前兩個字節55d5就表示指令頭,後一個字節02表示地址,再一個字節99表示數據。緊跟着後面的1爲無效數據,往後又檢測到55d5,則01爲地址,03爲數據。把指令頭、無效的數據過濾掉(即dout_vld爲0),最終輸出以字節爲單位的02、99、01、03。

一、設計架構

檢測出指令頭的方法如下:在這裏插入圖片描述
檢測出包文頭後,需要對後面的4個數據進行計數。每2個數據組成1個字節,一共有2個字節。所以指令檢測模塊採用兩個計數器的結構,這兩個計數器分別對應接收一個字節需要的數據個數和接收字節數,其結構圖如下所示:
在這裏插入圖片描述
計數器cnt0:數據個數計數器。對接收一個字節需要的數據進行計數,接收一個字節需要2個數據。該計數器的計數週期爲2。

計數器cnt1:字節數計數器。對接收的字節數進行計數,地址加上數據共兩個字節。該計數器的計數週期爲2。

二、信號的意義
在這裏插入圖片描述
在這裏插入圖片描述
三、參考代碼

module opcode_dect(

clk ,

rst_n ,

din ,

din_vld ,

dout_vld ,

dout

);

//參數定義

parameter DOUT_W = 8;

parameter DIN_W = 4;

//輸入信號定義

input clk ;

input rst_n ;

input[DIN_W-1:0] din ;

input din_vld ;

wire [DIN_W-1:0] din ;

wire din_vld ;

//輸出信號定義

output[DOUT_W-1:0] dout ;

output dout_vld;

//輸出信號reg定義

reg [DOUT_W-1:0] dout ;

reg dout_vld;

//中間信號定義

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章