我是靠谱客的博主 可耐电话,这篇文章主要介绍verilog 任意序列检测(python自动生成模板代码+dot状态转换图)任意序列检测器,现在分享给大家,希望可以做个参考。

文章目录

  • 任意序列检测器
    • 简介
    • 用python自动生成verilog任意序列检测器代码与状态转换图
      • 自动生成的状态转换图代码
      • 自动生成的verilog代码

任意序列检测器

简介

上一节(链接见1)我们讲了如何生成一个m序列。m序列作为伪随机数发生器,自然可以设计一个与之配套的任意序列检测器。其思路为使用有限状态机,一旦序列与对应的模式序列相匹配,则状态加一,否则状态将会下降(具体如何下降此处不予赘述,详请复习《数字电路》)。当状态满了就会输出1,表示检测到对应的模式序列。

对于任意序列检测器,有着许多细节而琐碎的问题。例如如何进行状态化简(使用最少的D触发器)、竞争冒险毛刺如何规避、检测到对应的模式序列后是应当从0开始还是保留状态(两者皆可,根据不同的需求设计)等。限于时间与篇幅,此处不予赘述。本文的核心在于代码与实现


本文均以序列11001010为例


用python自动生成verilog任意序列检测器代码与状态转换图

运行如下python代码(如果想要其他序列,只需要改第二行python代码series的值即可):

复制代码
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
# 全局变量 series = "11001010" # 要生成的序列 state_jump = [[0 for i in range(2)]for i in range(len(series)+1)] # 状态转换表 # 函数功能:计算state_jump[row][col]的值并返回 # 输入参数:row 为 state_jump列表的行数 # :col 为 state_jump列表的列数 # :series 为 待判断字符数组 # 输出参数:state_jump[row][col] # 说 明:当前值int(series[0:row-1].append(str(col)), 2) # :待匹配值int(series[0:row], 2) def cal_state_jump(row, col, series): temp_now = int(series[0:row]+str(col), 2) temp_aim = int(series[0:(row+1)], 2) divisor = 2 ** row for i in range(row+1): # 0 -> (row) if (temp_now == temp_aim): # 匹配 return (row+1-i) temp_aim = temp_aim // 2 temp_now = temp_now % divisor divisor = divisor // 2 return 0 #state = ["s0"] # 状态机 # 函数功能:计算state_jump[row][col]的值并直接修改列表 #def cal_change_state(): # for i in range(len(series)): # state.append("s"+str(i+1)) # 函数功能:计算二维列表state_jump的值并直接修改列表 # 输入参数:way 为 状态机执行方式 # 说 明:way为0 代表 每次检测出后均归0 # :way为其余值 代表 每次检测出继续计数 def cal_change_state_jump(way): for i in range(len(series)+1): if i != len(series): for j in range(2): state_jump[i][j] = cal_state_jump(i,j,series) else: if way == 0: # 每次检测出后均归0 if j == int(series[0]): state_jump[i][j] = 1 else: state_jump[i][j] = 0 else: # 每次检测出继续计数 state_jump[i][j] = cal_state_jump(i,j,series+str(1-j)) # 函数功能:生成有限状态机图 def generate_FSM(): cal_change_state_jump(0) print("// generate_code_start : FSMn") print("digraph finite_state_machine {") print(" rankdir=LR;") # LR:从左到右;TB:从上到下 # print(" size="8,5"") print(" node [shape = circle];") for j in range(2): for i in range(len(series)+1): print(" s%d -> s%d [ label = "%d" ];" %(i,state_jump[i][j],j)) print("}") print("// generate_code_end : FSMn") # 函数功能:把十进制数转2进制字符串并补0 # 输入参数:num 为 待转换十进制数 # :length 为 补0后长度 # 输出参数:2进制字符串 def dec2bin(num,length): temp_str = str(length)+''b' for i in range(length+2-len(bin(num))): temp_str += '0' temp_str += bin(num)[2:] return temp_str # 函数功能:生成verilog代码 def generate_verilog(): length = len(bin(len(series)))-2 # FSM的D触发器数量 cal_change_state_jump(0) print("// generate_code_start : verilogn") print("`timescale 1ns / 1ns") print("module check(") print(" input wire clk,") print(" input wire rst_n,") print(" input wire checkQ,n") print(" output wire is_series") print(" );n") print(" reg[3:0] now_state;n") print(" parameter",end = 'r') for i in range(len(series)): print(" s%d = %s" %(i,dec2bin(i,length)) ,end=',') print(" s%d = %s;n" %(len(series),dec2bin(len(series),length))) print(" assign is_series = (now_state == s%d);n" %(len(series))) print(" always @(posedge clk or negedge rst_n) beginn") print(" if (rst_n == 0) begin // negedge rest") print(" now_state <= 0;") print(" endn") print(" else begin") print(" casex(now_state)") for i in range(len(series)): print(" s%d: begin" %(i)) print(" if(checkQ == %s) now_state <= now_state + 4'b0001;" %(series[i])) print(" else now_state <= s%d;" %(state_jump[i][1-int(series[i])])) print(" end") print(" s%d: begin" %(len(series))) print(" if(checkQ == 0) now_state <= s%d;" %(state_jump[len(series)][0])) print(" else now_state <= s%d;" %(state_jump[len(series)][1])) print(" end") print(" default: now_state <= s0;") print(" endcase") print(" endn") print(" endn") print("endmodulen") print("// generate_code_end : verilogn") # main函数 if __name__ == "__main__": generate_FSM() generate_verilog()

运行结果如下:
在这里插入图片描述

在这里插入图片描述

其中第一部分代表自动生成的用dot234状态转换图绘制的代码,第二部分代表自动生成的Verilog代码。
如果需要graphviz-2.38.msi文件,可以用该百度云链接下载
链接:https://pan.baidu.com/s/1ddjYwUiEqsB-T5ttlYTx6Q
提取码:0721
复制这段内容后打开百度网盘手机App,操作更方便哦)

自动生成的状态转换图代码

这部分是python自动生成的用dot234状态转换图绘制的代码:

如果需要graphviz-2.38.msi文件,可以用该百度云链接下载
链接:https://pan.baidu.com/s/1ddjYwUiEqsB-T5ttlYTx6Q
提取码:0721
复制这段内容后打开百度网盘手机App,操作更方便哦)

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
digraph finite_state_machine { rankdir=LR; node [shape = circle]; s0 -> s0 [ label = "0" ]; s1 -> s0 [ label = "0" ]; s2 -> s3 [ label = "0" ]; s3 -> s4 [ label = "0" ]; s4 -> s0 [ label = "0" ]; s5 -> s6 [ label = "0" ]; s6 -> s0 [ label = "0" ]; s7 -> s8 [ label = "0" ]; s8 -> s0 [ label = "0" ]; s0 -> s1 [ label = "1" ]; s1 -> s2 [ label = "1" ]; s2 -> s2 [ label = "1" ]; s3 -> s1 [ label = "1" ]; s4 -> s5 [ label = "1" ]; s5 -> s2 [ label = "1" ]; s6 -> s7 [ label = "1" ]; s7 -> s2 [ label = "1" ]; s8 -> s1 [ label = "1" ]; }

用Graphix(具体操作见234)画出的图像如下:
在这里插入图片描述

自动生成的verilog代码

复制代码
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
`timescale 1ns / 1ns module check( input wire clk, input wire rst_n, input wire checkQ, output wire is_series ); reg[3:0] now_state; parameter s0 = 4'b0000, s1 = 4'b0001, s2 = 4'b0010, s3 = 4'b0011, s4 = 4'b0100, s5 = 4'b0101, s6 = 4'b0110, s7 = 4'b0111, s8 = 4'b1000; assign is_series = (now_state == s8); always @(posedge clk or negedge rst_n) begin if (rst_n == 0) begin // negedge rest now_state <= 0; end else begin casex(now_state) s0: begin if(checkQ == 1) now_state <= now_state + 4'b0001; else now_state <= s0; end s1: begin if(checkQ == 1) now_state <= now_state + 4'b0001; else now_state <= s0; end s2: begin if(checkQ == 0) now_state <= now_state + 4'b0001; else now_state <= s2; end s3: begin if(checkQ == 0) now_state <= now_state + 4'b0001; else now_state <= s1; end s4: begin if(checkQ == 1) now_state <= now_state + 4'b0001; else now_state <= s0; end s5: begin if(checkQ == 0) now_state <= now_state + 4'b0001; else now_state <= s2; end s6: begin if(checkQ == 1) now_state <= now_state + 4'b0001; else now_state <= s0; end s7: begin if(checkQ == 0) now_state <= now_state + 4'b0001; else now_state <= s2; end s8: begin if(checkQ == 0) now_state <= s0; else now_state <= s1; end default: now_state <= s0; endcase end end endmodule

  1. https://editor.csdn.net/md/?articleId=109794254 ↩︎

  2. https://zhuanlan.zhihu.com/p/138847719 ↩︎ ↩︎ ↩︎

  3. https://www.cnblogs.com/shuqin/p/11897207.html ↩︎ ↩︎ ↩︎

  4. https://www.cnblogs.com/onemorepoint/p/8310996.html ↩︎ ↩︎ ↩︎

最后

以上就是可耐电话最近收集整理的关于verilog 任意序列检测(python自动生成模板代码+dot状态转换图)任意序列检测器的全部内容,更多相关verilog内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(79)

评论列表共有 0 条评论

立即
投稿
返回
顶部