计组P1总结

本文最后更新于 2024年10月16日 凌晨

往年題

允许括号的表达式状态机

P1_L7_允许括号的表达式状态机 - 系统能力课程实验平台 (buaa.edu.cn)

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
module string2(
input clk,
input clr,
input [7:0] in,
output out
);
parameter START = 3'B000,
DIGIT = 3'B001,
CAL = 3'B010,
LEFT_BRACKET = 3'B011,
LEFT_DIGIT = 3'B100,
LEFT_CAL = 3'B101,
ILLEGAL = 3'B110;
parameter zero = 48,
nine = 57,
left = 40,
right = 41,
mult_ = 42,
plus_ = 43;
reg [2:0] state;
reg num;
reg mark;
reg left_bracket;
reg right_bracket;
initial begin
state = START;
num = 1'b0;
mark = 1'b0;
left_bracket = 1'b0;
right_bracket = 1'b0;
end
always @(posedge clk or posedge clr) begin
if (clr)begin
state = START;
num = 1'b0;
mark = 1'b0;
left_bracket = 1'b0;
right_bracket = 1'b0;
end
else begin
num = (in >= zero && in <= nine) ? 1 : 0;
mark = (in == mult_ || in == plus_) ? 1 : 0;
left_bracket = (in == left) ? 1 : 0;
right_bracket = (in == right) ? 1 : 0;

case (state)
START:begin
state = num ? DIGIT:
left_bracket ? LEFT_BRACKET:
ILLEGAL;
end
DIGIT:begin
state = mark ? CAL: ILLEGAL;
end
CAL:begin
state = left_bracket ? LEFT_BRACKET :
num ? DIGIT:
ILLEGAL;
end
LEFT_BRACKET:begin
state = num ? LEFT_DIGIT: ILLEGAL;
end
LEFT_DIGIT:begin
state = mark ? LEFT_CAL :
right_bracket ? DIGIT:
ILLEGAL;
end
LEFT_CAL:begin
state = num ? LEFT_DIGIT : ILLEGAL;
end
ILLEGAL:begin
state = ILLEGAL;
end
endcase
end
end

assign out = (state == DIGIT) ? 1 : 0;

endmodule

投票表決器

P1_L1_vote_plus - 系统能力课程实验平台 (buaa.edu.cn)

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
module VoterPlus(
input clk,
input reset,
input [31:0] np,
input [7:0] vip,
input vvip,
output reg[7:0] result
);

reg[31:0] last_np;
reg[7:0] last_vip;
reg last_vvip;
integer temp;
integer i;
always @(posedge clk or posedge reset) begin
if (reset)begin
last_np = 32'b0;
last_vip = 8'b0;
last_vvip = 1'b0;
result = 8'b0;
end
else begin
temp = 0;
for (i = 0; i < 32; i=i+1)begin:c
temp = temp + ((last_np[i] ^ np[i]) & np[i]);
end
result = result + temp;

temp = 0;
for (i = 0; i < 8; i=i+1) begin:cycle
temp = temp + ((last_vip[i] ^ vip[i]) & vip[i]);
end
result = result + 4 * temp;

result = result + 16 * ((last_vvip ^ vvip) & vvip);
last_np = last_np | np;
last_vip = last_vip | vip;
last_vvip = last_vvip | vvip;
end
end

endmodule

上机

题目大意

三道题,前一道是考察for循环的基本语法,后两道考察状态机

  • 题目1:输入两个32位数,将其中一个数的二进制位逆序排列,比较两个数同一二进制位上出现不同位的次数
  • 题目2:判断一串由0,1组成的字符串是否符合如下要求:
    • 将相邻的相同数字合成一组,相邻组的长度奇偶性一定不同
  • 题目3:输入格式为{xxxx:xxxx,xxxx:xxxx,}的字符串,记录当前的键值对数目和自上次复位以来的单个集合中最大键值对数目

思路

1

使用组合逻辑,在always @(*)块中写一个for循环

1
2
3
4
5
always @(*)begin
for (i = 0; i < 32; i = i + 1) begin
cnt = (a[i] ^ b[i] == 1) ? cnt + 1 : cnt;
end
end

2

设置状态:

xx_xx中,下划符前的表示上一个集合的奇偶性(或者NULL表示暂无上一个集合,下划符后的表示当前集合的集合的奇偶性

状态转换图如下:

状态转换图

3

考场没有写出来,错在了对于异常输入的处理办法.该题已经指明了{xxxx:xxx,xxxx:xxxx}的结构是固定的,测试数据不会出现{,},:,,这四个字符的丢失,所以当存在键值对不满足条件后,应当等待下一个,的输入

例如在{a:,b:12,}中,a:明显不是一个符合要求的键值对(缺乏value),但这时我们必须保证后面的键值对能计入,需要等待,输入后进入新一轮输入键值对中.


计组P1总结
https://meteor041.git.io/2024/10/09/计组P1总结/
作者
meteor041
发布于
2024年10月9日
许可协议