官方论坛
官方淘宝
官方博客
微信公众号
点击联系吴工 点击联系周老师
您的当前位置:主页-old > 新闻中心 > FPGA技术教程 > 边缘检测 >

边缘检测项目:指令检测模块代码解析(附源代码)-明德扬科教(mdy-edu.com)

发布时间:2019-12-10   作者:admin 浏览量:


边缘检测项目:指令检测模块代码解析


本文为明德扬原创文章,转载请注明出处!

本模块的功能,是从一串输入的数据中,检测出指令头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。


二、信号的意义


信号

类型

意义

clk

输入信号

时钟信号。

rst_n

输入信号

复位信号,低电平有效。

din

输入信号

输入的数据,位宽为4bit

din_vld

输入信号

输入数据有效指示信号。当其为1时,表示输入的数据有效,为0时表示输入数据无效。

dout

输出信号

输出数据,位宽为8bit(1字节)。

设计逻辑:在取数据状态时,每2个数据拼接成1字节输出。

dout_vld

输出信号

输出数据有效指示信号,位宽为1bit。

设计逻辑:在取数据状态,每取到1个字节数据就输出1个有效指示停车。

cnt0

中间信号

数据个数计数器。用于对接收一个字节需要的数据个数进行计数,接收一个字节需要两个输入数据。该计数器的计数周期为2。

add_cnt0

中间信号

数据个数计数器加1条件。

设计逻辑:在取数据状态,输入有效此信号就有效。

end_cnt0

中间信号

数据个数计数器的结束条件。

设计逻辑:接收一个字节需要两个数据,所以数到两个就结束。

cnt1

中间信号

字节数计数器。用于对地址和数据的字节数进行计数,地址和数据各占一个字节。该计数器的计数周期为2。

add_cnt1

中间信号

字节数计数器加1条件。

设计逻辑:每接收完1个字节,此计数器就加1。

end_cnt1

中间信号

字节计数器结束条件。

设计逻辑:地址和数据共两个字节,所以数到两个就结束。

din_tmp

中间信号

输入数据din的寄存器信号。位宽为12位,由高到低,每4位组成一组数据,分别存储的din之前三个有效数据。详细请看设计架构部分。

din_top

中间信号

指令头有效指示信号。

设计逻辑:当前输入数据和之前的三个数据组成55D5时,就表示检测到指令头。

flag_add

中间信号

取数据状态指示信号。当为1时,表示检测到包文头,此时处于取数据状态。

设计逻辑:指令头有效时,就变1;当取完4个数据后就变0。


三、参考代码

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

);


//参数定义

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




   拓展阅读