用序列缓存对比法创建寄存器,随时记录当前a的值,判断是否符合问题的含义match要慢一拍。
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input a, output reg match ); reg [7:0] a_1; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin match <= 0; a_1 <= 0; end else if(a_1 == 8'b01110001) match <= 1; else match <= 0; end always@(posedge clk or negedge rst_n) begin if(!rst_n) a_1 <= 0; else a_1 <= {
a_1[6:0],a}; end endmodule
或者序列缓存对比法
`timescale 1ns/1ns module sequence_detect( input clk, input rst_n, input a, output reg match ); reg [8:0] a_1; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin a_1 <= 0; match <= 0; end else if((a_1[8:6] == 3'b011) & (a_1[2:0] == 3'b110))
match <= 1;
else
match <= 0;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
a_1 <= 0;
else
a_1 <= {
a_1[7:0],a};
end
endmodule
需要注意的就是match和not_match信号比题目要求的提前了一个周期,小离谱 状态转移图如下:
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
output reg match,
output reg not_match
);
reg [3:0] ns,cs;
parameter
start = 4'd0,
s1 = 4'd1,
s2 = 4'd2,
s3 = 4'd3,
s4 = 4'd4,
s5 = 4'd5,
s6 = 4'd6,
s11 = 4'd7,
s22 = 4'd8,
s33 = 4'd9,
s44 = 4'd10,
s55 = 4'd11,
s66 = 4'd12;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
cs <= start;
else
cs <= ns;
end
always@(*) begin
case(cs)
start : ns = data ? s11 :s1;
s1 : ns = data ? s2 : s22;
s2 : ns = data ? s3 : s33;
s3 : ns = data ? s4 : s44;
s4 : ns = data ? s55 : s5;
s5 : ns = data ? s66 : s6;
s6 : ns = data ? s11 :s1;
s11 : ns = s22;
s22 : ns = s33;
s33 : ns = s44;
s44 : ns = s55;
s55 : ns = s66;
s66 : ns = data ? s11 : s1;
default : ns = data ? s11 : s1;
endcase
end
//always@(posedge clk or negedge rst_n) begin
always@(*) begin
if(!rst_n) begin
match = 0;
not_match = 0;
end
else if(cs == s6) begin
match = 1;
not_match = 0;
end
else if(cs == s66) begin
match = 0;
not_match = 1;
end
else begin
match = 0;
not_match = 0;
end
end
endmodule
不能直接判断data_1 == 3’b0110,这样会让match的输出延迟一个周期。
`timescale 1ns/1ns
module sequence_detect(
input clk,
input rst_n,
input data,
input data_valid,
output reg match
);
reg [3:0] data_1;
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
data_1 <= 3'b0000;
else if(data_valid)
data_1 <= {
data_1[2:0],data};
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
match <= 1'b0;
else if((data_1[2:0] == 2'b011) & (data_valid) & !data)
match <= 1'b1;
else
match <= 1'b0;
end
endmodule
`timescale 1ns/1ns
module count_module(
input clk,
input rst_n,
output reg [5:0]second,
output reg [5:0]minute
);
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
minute <= 0;
else if(second == 6'd60)
minute <= minute + 1;
else
minute <= minute;
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
second <= 0;
else if(second == 6'd60)
second <= 6'd1;
else if(minute == 6'd60)
second <= 0;
else
second <=second + 1;
end
endmodule
很喜欢评论区的一句话,“我猜是个软件大佬自学1天verilog速成,写出来的答案(流汗黄豆)” number要延后一拍,可以用寄存器num强行拖一拍,没必要做,自己测试能过就好。
vl52也是延后一拍。
`timescale 1ns/1ns
module RAM_1port(
input clk,
input rst,
input enb,
input [6:0]addr,
input [3:0]w_data,
output wire [3:0]r_data
);
//*************code***********//
reg [3:0] rom_1 [127:0];
genvar i;
generate
for(i = 0;i < 128;i = i + 1) begin
always@(posedge clk or negedge rst) begin
if(!rst)
rom_1[i] <= 0;
else
rom_1[addr] = enb ? w_data : rom_1[addr];
end
end
endgenerate
assign r_data = (enb) ? 0 : rom_1[addr];
//*************code***********//
endmodule
`timescale 1ns/1ns
module ram_mod(
input clk,
input rst_n,
input write_en,
input [7:0]write_addr,
input [3:0]write_data,
input read_en,
input [7:0]read_addr,
output reg [3:0]read_data
);
reg [3:0] rom_1 [7:0];
integer i;
always@(posedge clk or negedge rst_n) begin
if(!rst_n) begin
for(i = 0;i < 8;i = i + 1) begin
rom_1[i] <= 0;
end
end
else
rom_1[write_addr] = write_en ? write_data : rom_1[write_addr];
end
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
read_data <= 0;
else
read_data <= read_en ? rom_1[read_addr] : 0;
end
endmodule