接下来的练习记录
150 Exams/review2015 count1k
module top_module (
input clk,
input reset,
output [9:0] q);
parameter count = 999;
always@(posedge clk) begin
if(reset) begin
q <= 10'b0;
end
else if(q == count)
q <= 10'b0;
else
q <= q + 1;
end
endmodule
151 Exams/review2015 shiftcount
module top_module (
input clk,
input shift_ena,
input count_ena,
input data,
output [3:0] q);
always@(posedge clk)begin
if(shift_ena)begin
q <= {q[2:0],data};
end
else if(count_ena)begin
q <= q -1;
end
end
endmodule
152 exams/review2015_fsmseq
序列检测自动机
module top_module (
input clk,
input reset, // Synchronous reset
input data,
output start_shifting);
parameter RESET = 0,A =1,B =2,C=3,D=4;
reg [4:0] state,next_state;
always@(posedge clk) begin
if(reset)
state <= RESET;
else
state <= next_state;
end
always@(*) begin
if(reset)
next_state <= RESET;
else begin
case(state)
RESET:next_state <= (data)?A:RESET;
A:next_state <=(data)?B:RESET;
B:next_state <=(data)?B:C;
C:next_state <= (data)?D:RESET;
D:next_state <= D;
endcase
end
end
assign start_shifting = (state == D);
endmodule
153 Exams/review2015 fsmshift
这道题我使用两个标志位加计数器的方式完成,但第二种思路我觉得很好。可以借鉴一下。
module top_module (
input clk,
input reset, // Synchronous reset
output shift_ena);
reg [2:0] count;
reg count_flag;
reg reset_flag;
always@(*) begin
if(reset)
count_flag <= 1'b0;
else if(count == 3'b100)
count_flag <= 1'b0;
else if(count >= 0 && count < 3'b100)
count_flag <= 1'b1;
else
count_flag <= 1'b0;
end
always@(posedge clk) begin
if(reset)
count <= 3'b00;
else if(count == 3'b100)
count <= 3'b111;
else if(count_flag == 1'b1)
count <= count + 1'b1;
end
always@(posedge clk) begin
if(reset)
reset_flag <= 1'b1;
else
reset_flag <= 1'b0;
end
assign shift_ena = count_flag | reset_flag ;
endmodule
另外一种思路
module top_module (
input clk,
input reset, // Synchronous reset
output shift_ena);
//记录时钟周期
reg [2:0]cnt ;
always @(posedge clk)
begin
if(reset)
cnt <= 0;
else if(cnt >= 4)
cnt <= 4;
else
cnt = cnt + 1;
end
assign shift_ena = (cnt == 0 | cnt == 1 | cnt == 2 | cnt == 3);
endmodule
154 Exams/review2015 fsmshift
本题的题意主体要完成的是序列监测,以及根据后面的信号输入进行后续的状态转移,我这里犯了一个错误就是S2在接收到1时的错误,看来做序列监测的时候还是不能大意,导致我仿真看了一下波形图,找到问题,下面依次是状态转移图,解答,仿真图,testbench。
module top_module (
input clk,
input reset, // Synchronous reset
input data,
input ack,
input done_counting,
output shift_ena,
output counting,
output done
);
parameter RESET = 8'b11111111 ,S1 = 8'b00000001 ,S2 = 8'b00000010,S3 = 8'b00000100,S4 = 8'b00001000,
S5 = 8'b00010000 ,S6 = 8'b00100000,S7 = 8'b01000000,S8 = 8'b10000000;
reg [7:0] state , next_state;
reg [1:0] count;
always@(posedge clk) begin
if(reset)
state <= RESET;
else
state <= next_state;
end
always@(posedge clk)begin
if(reset)
count <= 2'b00;
else if(state == S4 && count != 2'b11)
count <= count + 1'b1;
else
count <= 2'b00;
end
always@(*) begin
if(reset)
next_state <= RESET;
else begin
case(state)
RESET:next_state <= (!reset & data == 1'b1)?S1:RESET;
S1: next_state <= (data)?S2:RESET;
S2: next_state <= (data)?S2:S3;
S3: next_state <= (data)?S4:RESET;
S4: next_state <= (count == 2'b11)?S5:S4;
S5: next_state <= (done_counting)?S6:S5;
S6: next_state <= (ack)?RESET:S6;
default:next_state <= RESET;
endcase
end
end
assign shift_ena = (state== S4);
assign counting = (state == S5);
assign done = (state == S6);
endmodule
仿真时序图
//testbench
module tb_top_module_154();
reg clk;
reg reset; // Synchronous reset
reg data;
reg ack;
reg done_counting;
wire shift_ena;
wire counting;
wire done;
initial begin
clk <= 1;
reset <= 1'b0;
end
always begin
#2 clk = ~clk;
end
initial begin
#4
data <= 1'b1;
#2
data <= 1'b0;
#6
data <= 1'b1;
#2
data <= 1'b0;
#8
data <= 1'b1;
#4
data <= 1'b0;
#2
data <= 1'b1;
#4
data <= 1'b0;
#2
data <= 1'b1;
#8
data <= 1'b0;
#2
data <= 1'b1;
#14
data <= 1'b0;
#2
data <= 1'b1;
#4;
end
initial begin
done_counting <= 1'b0;
#48
done_counting <= 1'b1;
#2
done_counting <= 1'b0;
#14;
end
initial begin
ack <= 1'b0;
#6;
ack <= 1'b1;
#2
ack <= 1'b0;
#14
ack <= 1'b1;
#2
ack <= 1'b0;
#22
ack <= 1'b1;
#2
ack <= 1'b0;
#16;
end
top_module_154 tb_top_module_inst(
.clk(clk),
.reset(reset),
.data(data),
.ack(ack),
.done_counting(done_counting),
.shift_ena(shift_ena),
.counting(counting),
.done(done)
);
endmodule
155 Exams/review2015 fsm
155的状态转移图大体没有变动,需要改变的就是S5到S6的转变,然后其中在S4时要记录移位得到的数据count,然后我用round信号记录需要计数几轮,assign round <= count + 1’b1,这样更加好判断。
还需要注意的点是,在计数时,我刚开始想通过for循环来完成计数,但是我之前看过在verilog中要避免写for循环,所有通过 判断语句来写循环。
module top_module_155 (
input clk,
input reset, // Synchronous reset
input data,
input ack,
output [3:0] count,
output counting,
output done
);
parameter thousand = 1000;
parameter RESET = 8'b11111111 ,S1 = 8'b00000001 ,S2 = 8'b00000010,S3 = 8'b00000100,S4 = 8'b00001000,
S5 = 8'b00010000 ,S6 = 8'b00100000,S7 = 8'b01000000,S8 = 8'b10000000;
reg [7:0] state , next_state;
reg [1:0] num;
reg [9:0] i;
wire [3:0] round;
assign round = count + 1'b1;
always@(posedge clk) begin
if(reset)
state <= RESET;
else
state <= next_state;
end
always@(posedge clk)begin
if(reset)
count <= 4'b0;
else if(state == S4)
count <= {count[2:0],data};
else if(state == S5 && i == thousand -1'b1 && count != 0 )
count <= count - 1'b1;
else if(next_state == S6)
count <= 4'b0;
else
count <= count;
end
always@(posedge clk)begin
if(reset)
num <= 2'b00;
else if(state == S4 && num != 2'b11)
num <= num + 1'b1;
else
num <= 2'b00;
end
always@(posedge clk)begin
if(reset) begin
i <= 10'b0;
end
else if(state == S5) begin
if(i == thousand -1'b1) begin
i <= 10'b0;
end
else begin
i <= i +1'b1;
end
end
end
always@(*) begin
if(reset)
next_state <= RESET;
else begin
case(state)
RESET:next_state <= (!reset & data == 1'b1)?S1:RESET;
S1: next_state <= (data)?S2:RESET;
S2: next_state <= (data)?S2:S3;
S3: next_state <= (data)?S4:RESET;
S4: next_state <= (num == 2'b11)?S5:S4;
S5: next_state <= (i == thousand -1'b1 && round == 1'b1)?S6:S5;
S6: next_state <= (ack)?RESET:S6;
default:next_state <= RESET;
endcase
end
end
assign counting = (state == S5);
assign done = (state == S6);
endmodule
前几个状态的仿真图
155的testbench
module tb_top_module_155();
reg clk;
reg reset; // Synchronous reset
reg data;
reg ack;
wire [3:0] count;
wire counting;
wire done;
initial begin
clk <= 1;
reset <= 1'b1;
#4;
reset <= 1'b0;
end
always begin
#2 clk = ~clk;
end
initial begin
data <= 1'b0;
#4
data <= 1'b1;
#4
data <= 1'b0;
#8
data <= 1'b1;
#8
data <= 1'b0;
#4
data <= 1'b1;
#4
data <= 1'b0;
#12
data <= 1'b1;
#4
data <= 1'b0;
end
initial begin
ack <= 1'b0;
#6;
ack <= 1'b1;
#2
ack <= 1'b0;
#14
ack <= 1'b1;
#2
ack <= 1'b0;
#22
ack <= 1'b1;
#2
ack <= 1'b0;
#16;
end
top_module_155 tb_top_module_inst(
.clk(clk),
.reset(reset),
.data(data),
.ack(ack),
.count(count),
.counting(counting),
.done(done)
);
endmodule
156 Exams/review2015 fsmonehot
module top_module(
input d,
input done_counting,
input ack,
input [9:0] state, // 10-bit one-hot current state
output B3_next,
output S_next,
output S1_next,
output Count_next,
output Wait_next,
output done,
output counting,
output shift_ena
);
//
// You may use these parameters to access state bits using e.g., state[B2] instead of state[6].
parameter S=0, S1=1, S11=2, S110=3, B0=4, B1=5, B2=6, B3=7, Count=8, Wait=9;
assign B3_next = state[B2];
assign S_next = (((state[S] || state[S1] ||state[S110]) && d == 1'b0 )|| state[Wait] && ack == 1'b1);
assign S1_next = (state[S] && d == 1'b1);
assign Count_next = state[B3] || (state[Count] && done_counting == 1'b0);
assign Wait_next = (state[Wait] && ack == 1'b0) || (state[Count]&& done_counting == 1'b1);
assign done = state[Wait];
assign counting = state[Count];
assign shift_ena = state[B0] ||state[B1] ||state[B2] ||state[B3];
endmodule
157-161 Finding bugs in code
//157
module top_module (
input sel,
input [7:0] a,
input [7:0] b,
output [7:0] out ); //修改这里
assign out = sel?a:b ; //使用这个逻辑更加好理解
endmodule
//158
module top_module (input a, input b, input c, output out);//
reg outq;
assign out = ~outq;
andgate inst1 (
.a(a),
.b(b),
.c(c),
.d(1'b1),
.e(1'b1),
.out(outq)
);
endmodule
//159
module top_module (
input [1:0] sel,
input [7:0] a,
input [7:0] b,
input [7:0] c,
input [7:0] d,
output [7:0] out ); //
wire [7:0] mux0,mux1;
mux2 mux0_inst ( sel[0], a, b, mux0 );
mux2 mux1_inst ( sel[0], c, d, mux1 );
mux2 mux2_inst ( sel[1], mux0, mux1, out );
endmodule
/160
// synthesis verilog_input_version verilog_2001
module top_module (
input do_sub,
input [7:0] a,
input [7:0] b,
output reg [7:0] out,
output result_is_zero
);
always @(*) begin
case (do_sub)
0: out = a+b;
1: out = a-b;
endcase
end
assign result_is_zero = (out == 8'b0)?1:0;
endmodule
//161
module top_module (
input [7:0] code,
output reg [3:0] out,
output reg valid=1 );//
always @(*) begin
case (code)
8'h45: begin
out = 0;
valid <= 1'b1;
end
8'h16: begin
out = 1;
valid <= 1'b1;
end
8'h1e: begin
out = 2;
valid <= 1'b1;
end
8'h26: begin
out = 3; //修改
valid <= 1'b1;
end
8'h25: begin
out = 4;
valid <= 1'b1;
end
8'h2e: begin
out = 5;
valid <= 1'b1;
end
8'h36: begin
out = 6;
valid <= 1'b1;
end
8'h3d: begin
out = 7;
valid <= 1'b1;
end
8'h3e: begin
out = 8;
valid <= 1'b1;
end
8'h46: begin
out = 9; //修改
valid <= 1'b1;
end
default: begin
out <= 0;
valid <= 0;
end
endcase
end
endmodule
162- 171 Sim/circuit1
//162
module top_module (
input a,
input b,
output q );//
assign q = a&b; // Fix me
endmodule
//163
//同或 也就是 异或非
assign q = !(a^b^c^d); // Fix me
//164
//卡诺图如下图所示:
assign q = (a|b)&(c|d); // Fix me
//165
assign q = b|c; // Fix me
//166
module top_module (
input [3:0] a,
input [3:0] b,
input [3:0] c,
input [3:0] d,
input [3:0] e,
output [3:0] q );
always@(*) begin
if(c >= 4'b0 && c <= 4'b0011) begin
case(c)
4'b0000: q <= b;
4'b0001: q <= e;
4'b0010: q <= a;
4'b0011: q <= d;
default: q <= 4'b1111;
endcase
end
else
q <= 4'b1111;
end
endmodule
//167
module top_module (
input [2:0] a,
output [15:0] q );
always@(*)begin
case(a)
3'b000:q <= 16'h1232;
3'b001:q <= 16'haee0;
3'b010:q <= 16'h27d4;
3'b011:q <= 16'h5a0e;
3'b100:q <= 16'h2066;
3'b101:q <= 16'h64ce;
4'b110:q <= 16'hc526;
4'b111:q <= 16'h2f19;
default:q <= 16'h0000;
endcase
end
endmodule
//168
module top_module (
input clk,
input a,
output q );
always@(posedge clk) begin
q <= !a;
end
endmodule
//169
module top_module (
input clock,
input a,
output p,
output q );
always@(*)begin
if(clock)
p <= a;
else
p <= p;
end
always@(negedge clock)begin
q <= a;
end
endmodule
//170
//a是复位信号
module top_module (
input clk,
input a,
output [3:0] q);
always@(posedge clk)begin
if(a)
q <= 4'b0100;
else begin
if(q == 4'b0110)
q <= 4'b0;
else
q <= q + 1'b1;
end
end
endmodule
//171
module top_module (
input clk,
input a,
input b,
output q,
output state );
reg next_state;
parameter A=1'b0,B=1'b1;
always @(*)begin
case(state)
A:next_state = a&b?B:A;
B:next_state = ((a|b)==1'b0)?A:B;
endcase
end
always @ (posedge clk) begin
state <= next_state;
end
assign q = ((state == A)&(a^b))|((state == B)& (~(a^b)));
endmodule
Testbench
172-176
//172
`timescale 1ps / 1ps
module top_module ( );
reg clk;
dut inst_dut(
.clk (clk)
);
initial begin
clk = 1'b0;
end
always begin
#5
clk = ~clk;
end
endmodule
//173
module top_module ( output reg A, output reg B );//
initial begin
A <= 1'b0;
#10
A <=1'b1;
#10
A <= 1'b0;
end
initial begin
B <= 1'b0;
#15
B <=1'b1;
#25
B <= 1'b0;
end
endmodule
//174
`timescale 1ps / 1ps
module top_module();
reg [1:0] in;
wire out;
andgate inst_andgate(
.in(in),
.out(out)
);
initial begin
in = 2'b00;
#10;
in = 2'b01;
#10;
in = 2'b10;
#10;
in = 2'b11;
end
endmodule
//175
//testbench我喜欢分信号写
module top_module();
reg clk;
reg in;
reg [2:0] s;
wire out;
q7 inst_q7(
.clk(clk),
.in(in),
.s(s),
.out(out)
);
initial begin
clk = 1'b0;
end
always begin
#5
clk = ~clk;
end
initial begin
in <= 1'b0;
#20;
in <= 1'b1;
#10;
in <= 1'b0;
#10
in <= 1'b1;
#30;
in <= 1'b0;
end
initial begin
s <= 3'b010;
#10;
s <= 3'b110;
#10
s <= 3'b010;
#10
s <= 3'b111;
#10
s <= 3'b000;
end
endmodule
//176
module top_module ();
reg clk;
reg reset;
reg t;
wire q;
tff tff_inst(
.clk(clk),
.reset(reset),
.t(t),
.q(q)
);
initial begin
clk = 1'b0;
end
always begin
#5
clk = ~clk;
end
initial begin
reset <= 1'b0;
t <= 1'b0;
#10;
reset <= 1'b1;
#10;
reset <= 1'b0;
#10
t <= 1'b1;
end
endmodule