前言
最近一直在做方案,挺长时间没有专注的写过rtl,感觉手很生需要写点代码找找手感。恰好最近看到了评论(不知道是不是做推广的啊):
想了下反正周末闲着也是闲着,那刷两个题找找写rtl的手感吧。于是乎我信心满满的打开了这个题目,看了下觉得这不是手拿把掐么,结果吧:
就我也没想到这么几十行的代码我能改3次,看来我写bug的能力是一点没减。
题目
请编写一个序列检测模块,检测输入信号(a)是否满足011100序列, 要求以每六个输入为一组,不检测重复序列,例如第一位数据不符合,则不考虑后五位。一直到第七位数据即下一组信号的第一位开始检测。当信号满足该序列,给出指示信号match。当不满足时给出指示信号not_match
解题
我的思路比较简单,把输入的data按位置摆放在6bit寄存器的对应位置,从高到低就这么循环摆放,凑够6个数后用6bit寄存器的值去和对应的值比较,比上了就输出match,比不上就输出not_match。
循环转的msk信号,对应位置1表示这拍的data放置位置,为什么不使用count呢是因为相比于选择逻辑我更喜欢与或逻辑,映射的电路结构更加清晰:
reg[5:0]msk; always @(posedge clk or negedge rst_n)begin if(~rst_n)begin msk <= 6'b100000; end else if (msk == 6'b000001)begin msk <= 6'b100000; end else begin msk <= (msk>>1); end end
6bit的seq寄存器,与或逻辑产生seq的D端,seq的复位值我用的匹配序列取反值:
parameter MATCH_SEQ = 6'b011100; parameter NOT_MATCH_SEQ = ~MATCH_SEQ; reg[5:0]seq; wire[5:0]seq_d = (msk & {6{data}}) | (~msk & seq); always @(posedge clk or negedge rst_n)begin if(~rst_n)begin seq <= NOT_MATCH_SEQ; end else begin seq <= seq_d; end end
因为示意图时序里,第6个data的下一拍就要出match/not_match,所以用seq的D端来做逻辑:
wire match_d = (seq_d == MATCH_SEQ); wire not_match_d = (seq_d != MATCH_SEQ); always @(posedge clk or negedge rst_n)begin if(~rst_n)begin match <= 1'b0; not_match <= 1'b0; end else if (msk == 6'b000001)begin match <= match_d; not_match <= not_match_d; end else begin match <= 1'b0; not_match <= 1'b0; end end
结果
结果还是好的o(╥﹏╥)o