Fsm1
这里需要实现一个简单的摩尔状态机,即输出只与状态有关的状态机。
我这里代码看上去比长一点,答案用的case和三目运算符,结果是一样的。
module top_module( input clk, input areset, // Asynchronous reset to state B input in, output out);// parameter A=0, B=1; reg state, next_state; always @(*) begin // This is a combinational always block if(state ==A)begin if(in==1) next_state=A; else next_state=B; end else if(state ==B)begin if(in==1) next_state=B; else next_state=A; end end always @(posedge clk, posedge areset) begin // This is a sequential always block if(areset) state <= B; else state <= next_state; end // Output logic assign out = (state == B); endmodule
Fsm1s
和上一题是一样的,只不过换成了同步复位。
// Note the Verilog-1995 module declaration syntax here: module top_module(clk, reset, in, out); input clk; input reset; // Synchronous reset to state B input in; output out;// // Fill in state name declarations reg present_state, next_state; parameter A=0, B=1; always @(posedge clk) begin if (reset) begin present_state <= B; end else begin // State flip-flops present_state <= next_state; end end always@(*) begin case (present_state) A:next_state=in?A:B; B:next_state=in?B:A; endcase end assign out = (present_state == B); endmodule
Fsm2
这里是一个JK触发器。
module top_module( input clk, input areset, // Asynchronous reset to OFF input j, input k, output out); // parameter OFF=0, ON=1; reg state, next_state; always @(*) begin case(state) OFF:next_state=j?ON:OFF; ON:next_state=k?OFF:ON; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= OFF; else state <= next_state; end // Output logic assign out = (state == ON); endmodule
Fsm2s
同样是异步改成同步就可以了。
module top_module( input clk, input reset, // Synchronous reset to OFF input j, input k, output out); // parameter OFF=0, ON=1; reg state, next_state; always @(*) begin case(state) OFF:next_state=j?ON:OFF; ON:next_state=k?OFF:ON; endcase end always @(posedge clk) begin if(reset) state <= OFF; else state <= next_state; end // Output logic assign out = (state == ON); endmodule
Fsm3comb
这道题只需要实现状态转换逻辑和输出逻辑,状态转换的时序逻辑不需要实现。
module top_module( input in, input [1:0] state, output [1:0] next_state, output out); // parameter A=0, B=1, C=2, D=3; // State transition logic: next_state = f(state, in) always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // Output logic: out = f(state) for a Moore state machine assign out=(state==D); endmodule
Fsm3onehot
这道题要求使用独热码,即只有一个1的编码。
这里提到了一个概念"derive equations by inspection",指通过某一个位就可以判断当前状态,例如可以用state[0]判断当前状态是否为A,这样可以简化状态转换逻辑。
module top_module( input in, input [3:0] state, output [3:0] next_state, output out); // parameter A=0, B=1, C=2, D=3; // State transition logic: Derive an equation for each state flip-flop. assign next_state[A] = (state[A]&~in)|(state[C]&~in); assign next_state[B] = (state[A]&in)|(state[B]&in)|(state[D]&in); assign next_state[C] = (state[B]&~in)|(state[D]&~in); assign next_state[D] = (state[C]&in); // Output logic: assign out = state[D]; endmodule
Fsm3
状态转换逻辑在前面已经实现了,这里只需要实现状态转换寄存器和输出寄存器。
module top_module( input clk, input in, input areset, output out); // reg [1:0]state,next_state; // State transition logic parameter A=0, B=1, C=2, D=3; always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // State flip-flops with asynchronous reset always@(posedge clk or posedge areset) begin if(areset) state <= A; else state <= next_state; end // Output logic assign out=(state==D); endmodule
Fsm3s
把上一题的异步复位改成同步复位。
module top_module( input clk, input in, input reset, output out); // reg [1:0]state,next_state; // State transition logic parameter A=0, B=1, C=2, D=3; always@(*) begin case(state) A:next_state=in?B:A; B:next_state=in?B:C; C:next_state=in?D:A; D:next_state=in?B:C; endcase end // State flip-flops with asynchronous reset always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end // Output logic assign out=(state==D); endmodule
Exams/ece241 2013 q4
又是一道正确率十几的题目。。
fr1、fr2、fr3结果输出可以直接根据题目给的表得出,dfr需要仔细考虑一下,题目的意思是如果之前的水位比现在的水位低,那么就打开dfr,这里的之前并不是指一个时钟的之前,所以当状态不变的时候不需要改变dfr。不过我这种写法就不是严格的摩尔状态机了,因为我在一个时序逻辑中同时使用了state和next_state做对比。
题目给的答案通过六个状态来给出输出,感觉还是有点复杂的。
module top_module ( input clk, input reset, input [3:1] s, output fr3, output fr2, output fr1, output reg dfr ); parameter A=0,B=1,C=2,D=3; reg[1:0]state,next_state; always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end always@(*) begin next_state = A; case(s) 3'b111:next_state = D; 3'b011:next_state = C; 3'b001:next_state = B; 3'b000:next_state = A; endcase end always@(posedge clk) begin if(reset) dfr <= 1; else if(next_state<state) dfr <= 1; else if(next_state>state) dfr <= 0; end assign fr3=(state==A); assign fr2=(state==A)||(state==B); assign fr1=(state==A)||(state==B)||(state==C); endmodule
Lemmings1
这道题要求用有限状态机描述游戏Lemmings中的角色,角色将在撞到障碍物时改变方向。
题目已经把状态机和代码框架都给出来了,只要补充关键部分即可。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, output walk_left, output walk_right); // parameter LEFT=0, RIGHT=1; reg state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=bump_left?RIGHT:LEFT; RIGHT:next_state=bump_right?LEFT:RIGHT; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); endmodule
Lemmings2
相比上一题多了一个FALL的状态,要求FALL之后还要恢复之前的方向,所以这里增加一个状态是不够的,至少要增加两个状态之后才能使FALL之后恢复原来的状态。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, input ground, output walk_left, output walk_right, output aaah ); parameter LEFT=0, RIGHT=1,FALL_L=2,FALL_R=3; reg [1:0]state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(bump_left?RIGHT:LEFT):FALL_L; RIGHT:next_state=ground?(bump_right?LEFT:RIGHT):FALL_R; FALL_L:next_state=ground?LEFT:FALL_L; FALL_R:next_state=ground?RIGHT:FALL_R; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); endmodule
Lemmings3
根据题目给的题目给的状态转换表,还是比较好写的。
直接在上一题代码基础上改的,越改越长。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, input ground, input dig, output walk_left, output walk_right, output aaah, output digging ); parameter LEFT=0, RIGHT=1,FALL_L=2,FALL_R=3,DIG_L=4,DIG_R=5; reg [2:0]state, next_state; always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(dig?DIG_L:(bump_left?RIGHT:LEFT)):FALL_L; RIGHT:next_state=ground?(dig?DIG_R:(bump_right?LEFT:RIGHT)):FALL_R; FALL_L:next_state=ground?LEFT:FALL_L; FALL_R:next_state=ground?RIGHT:FALL_R; DIG_L:next_state=ground?DIG_L:FALL_L; DIG_R:next_state=ground?DIG_R:FALL_R; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); assign digging = (state == DIG_L)||(state == DIG_R); endmodule
Lemmings4
当Lemmings 下落超过20个时钟周期会摔死,注意!Lemmings 不会在半空中摔死,不能以20个周期作为判别条件,而要以到ground时的时钟周期数来计算。
module top_module( input clk, input areset, // Freshly brainwashed Lemmings walk left. input bump_left, input bump_right, input ground, input dig, output walk_left, output walk_right, output aaah, output digging ); parameter LEFT=0, RIGHT=1,FALL_L=2,FALL_R=3,DIG_L=4,DIG_R=5,SPLAT=6; reg [2:0]state, next_state; reg [7:0]fall_cnt; always@(posedge clk , posedge areset) begin if(areset) fall_cnt <= 'd0; else if((state == FALL_L)||(state == FALL_R)) fall_cnt <= (fall_cnt>=20)?fall_cnt:fall_cnt+1'b1; else fall_cnt <= 'd0; end always @(*) begin // State transition logic case(state) LEFT:next_state=ground?(dig?DIG_L:(bump_left?RIGHT:LEFT)):FALL_L; RIGHT:next_state=ground?(dig?DIG_R:(bump_right?LEFT:RIGHT)):FALL_R; FALL_L:next_state=ground?((fall_cnt==20)?SPLAT:LEFT):FALL_L; FALL_R:next_state=ground?((fall_cnt==20)?SPLAT:RIGHT):FALL_R; DIG_L:next_state=ground?DIG_L:FALL_L; DIG_R:next_state=ground?DIG_R:FALL_R; SPLAT:next_state=SPLAT; default:next_state='dx; endcase end always @(posedge clk, posedge areset) begin // State flip-flops with asynchronous reset if(areset) state <= LEFT; else state <= next_state; end // Output logic assign walk_left = (state == LEFT); assign walk_right = (state == RIGHT); assign aaah = (state == FALL_L)||(state == FALL_R); assign digging = (state == DIG_L)||(state == DIG_R); endmodule
一次过,完美。今天就做到这里了,这一节题目有点多,有些题还有些复杂,估计还要再写两天了。
Fsm onehot
看着简单,但得找对思路,一开始我用的always@(*)并且标注出了S9~S0,但是由于该测试还会输入非独热码,会导致输出也并非全是独热码,所以要按照出题者的意图,直接将每一位作为一个状态直接进行判断。
module top_module( input in, input [9:0] state, output [9:0] next_state, output out1, output out2); assign next_state[0]=~in&&(state[4:0]||state[9:7]); assign next_state[1]=in&&(state[0]||state[9:8]); assign next_state[2]=in&&state[1]; assign next_state[3]=in&&state[2]; assign next_state[4]=in&&state[3]; assign next_state[5]=in&&state[4]; assign next_state[6]=in&&state[5]; assign next_state[7]=in&&state[7:6]; assign next_state[8]=~in&&state[5]; assign next_state[9]=~in&&state[6]; assign out1=state[8]|state[9]; assign out2=state[7]|state[9]; endmodule
Fsm ps2
ps/2是早期鼠标和键盘的接口,现在已经基本被USB取代。
这道题只需要通过in[3]来判断数据传输什么时候结束即可。
module top_module( input clk, input [7:0] in, input reset, // Synchronous reset output done); // parameter BYTE1=0,BYTE2=1,BYTE3=2,DONE=3; reg[1:0]state,next_state; // State transition logic (combinational) always@(*) begin case(state) BYTE1:next_state=in[3]?BYTE2:BYTE1; BYTE2:next_state=BYTE3; BYTE3:next_state=DONE; DONE:next_state=in[3]?BYTE2:BYTE1; endcase end // State flip-flops (sequential) always@(posedge clk) begin if(reset) state <= BYTE1; else state <= next_state; end // Output logic assign done=(state==DONE); endmodule
Fsm ps2data
在上一题的基础上增加一个存储数据的功能.
注意,由于这里状态DONE的时候下一个状态直接就是BYTE2了,所以在DONE的时候就可以存储BYTE1了。
module top_module( input clk, input [7:0] in, input reset, // Synchronous reset output reg[23:0] out_bytes, output done); // // FSM from fsm_ps2 parameter BYTE1=0,BYTE2=1,BYTE3=2,DONE=3; reg[1:0]state,next_state; // State transition logic (combinational) always@(*) begin case(state) BYTE1:next_state=in[3]?BYTE2:BYTE1; BYTE2:next_state=BYTE3; BYTE3:next_state=DONE; DONE:next_state=in[3]?BYTE2:BYTE1; endcase end // State flip-flops (sequential) always@(posedge clk) begin if(reset) state <= BYTE1; else state <= next_state; end // Output logic assign done=(state==DONE); // New: Datapath to store incoming bytes. always@(posedge clk) begin if(reset) out_bytes <= 'd0; else begin case(state) BYTE1:out_bytes[23:16] <= in; BYTE2:out_bytes[15:8] <= in; BYTE3:out_bytes[7:0] <= in; DONE:out_bytes[23:16] <= in; endcase end end endmodule
Fsm serial
又是一道正确率很低的题目。
一开始写的count==8,一直出错,要注意count=0也有一个周期的长度。
module top_module( input clk, input in, input reset, // Synchronous reset output done ); parameter IDLE=0,START=1,DATA=2,STOP=3; reg[1:0]state,next_state; reg[3:0]count; always@(posedge clk) begin if(reset) state <= IDLE; else state <= next_state; end always@(posedge clk) begin if(reset) count <= 'd0; else if(state == DATA) count <= (count>7)?count:count+1'b1; else count <= 'd0; end always@(*) begin case(state) IDLE:next_state=in?IDLE:START; START:next_state=DATA; DATA:begin if(count==7&&in) next_state=STOP; else if(count>7&&in) next_state=IDLE; else next_state=DATA; end STOP:next_state=in?IDLE:START; endcase end assign done=(state==STOP); endmodule
Fsm serialdata
使用state计数的话整体的数据采集会落后一个周期,所以这题的计数使用next_state来进行判断,所以上一题的7要改成8。
原理参考三段式状态机使用case(next_state)用作输出,否则使用case(state)输出会落后两个周期。
module top_module( input clk, input in, input reset, // Synchronous reset output reg[7:0] out_byte, output done ); // // Use FSM from Fsm_serial parameter IDLE=0,START=1,DATA=2,STOP=3; reg[1:0]state,next_state; reg[3:0]count; always@(posedge clk) begin if(reset) state <= IDLE; else state <= next_state; end always@(posedge clk) begin if(reset) count <= 'd0; else if(next_state == DATA)begin out_byte <= {in,out_byte[7:1]}; count <= (count>8)?count:count+1'b1; end else count <= 'd0; end always@(*) begin case(state) IDLE:next_state=in?IDLE:START; START:next_state=DATA; DATA:begin if(count==8&&in) next_state=STOP; else if(count>8&&in) next_state=IDLE; else next_state=DATA; end STOP:next_state=in?IDLE:START; endcase end assign done=(state==STOP); // New: Datapath to latch input bits. endmodule
Fsm serialdp
在上一题的基础上实现一个奇校验:通过加入一个冗余位,使得9位数据中的1的个数始终为奇数。
题目给了一个T触发器,即输入为1时,输出翻转的触发器,T触发一般使用一个JK触发器构成。
debug不能看全部信号的波形也太折磨了,最好还是用vivado仿真调一下。
在经过六次失败之后,终于成功了,错误的原因是T触发器的in信号经过了选通,导致可能少计了一个周期,其实reset位置合适,in可以直接连接到T触发器上。
module top_module( input clk, input in, input reset, // Synchronous reset output [7:0] out_byte, output done ); // // Use FSM from Fsm_serial parameter IDLE=0,START=1,DATA=2,STOP=3; reg[1:0]state,next_state; reg[3:0]count; wire odd; reg[8:0]data; wire parity_reset; always@(posedge clk) begin if(reset) state <= IDLE; else state <= next_state; end always@(posedge clk) begin if(reset) count <= 'd0; else if(next_state == DATA)begin data <= {in,data[8:1]}; count <= (count>9)?count:count+1'b1; end else if(next_state == START) count <= 'd0; end always@(*) begin case(state) IDLE:next_state=in?IDLE:START; START:next_state=DATA; DATA:begin if(count==9&&in&&odd) next_state=STOP; else if(count>=9&&in) next_state=IDLE; else next_state=DATA; end STOP:next_state=in?IDLE:START; endcase end assign done=(state==STOP); // New: Datapath to latch input bits. // New: Add parity checking. parity u0(clk,parity_reset,in,odd); assign out_byte=data[7:0]; assign parity_reset = reset||next_state ==IDLE||next_state == START; endmodule
Fsm hdlc
序列检测器,这里有三个序列需要检测
- 0111110: Signal a bit needs to be discarded (disc).
- 01111110: Flag the beginning/end of a frame (flag).
- 01111111...: Error (7 or more 1s) (err).
根据题目意思可以构建一个Moore状态机,结果发现和前面Fsm onehot中的状态机是一样的,这不是巧了吗。前面用的是独热码并且已经写出了状态转移方程,这里直接用就好了。
module top_module( input clk, input reset, // Synchronous reset input in, output disc, output flag, output err); reg[9:0]state; wire[9:0]next_state; parameter NONE=10'd0000_0000_01; parameter ONE=10'd0000_0000_10; parameter TWO=10'd0000_0001_00; parameter THREE=10'd0000_0010_00; parameter FOUR=10'd0000_0100_00; parameter FIVE=10'd0000_1000_00; parameter SIX=10'd0001_0000_00; parameter ERROR=10'd0010_0000_00; parameter DISCARD=10'd0100_0000_00; parameter FLAG=10'd1000_0000_00; always@(posedge clk) begin if(reset) state <= NONE; else state <= next_state; end assign next_state[0]=~in&&(state[4:0]||state[9:7]); assign next_state[1]=in&&(state[0]||state[9:8]); assign next_state[2]=in&&state[1]; assign next_state[3]=in&&state[2]; assign next_state[4]=in&&state[3]; assign next_state[5]=in&&state[4]; assign next_state[6]=in&&state[5]; assign next_state[7]=in&&state[7:6]; assign next_state[8]=~in&&state[5]; assign next_state[9]=~in&&state[6]; assign err=state[7]; assign disc=state[8]; assign flag=state[9]; endmodule
有状态转换逻辑就是好写。
Exams/ece241 2013 q8
使用Mealy状态机,也就是输出和状态和输入都有关,这里使用Moore状态机会多一个状态.,而题目要求使用三个状态,所以最好使用Mealy状态机。
module top_module ( input clk, input aresetn, // Asynchronous active-low reset input x, output z ); reg[1:0]state,next_state; parameter S0=0,S1=1,S2=2; always@(posedge clk or negedge aresetn) begin if(~aresetn) state <= S0; else state <= next_state; end always@(*) begin case(state) S0:next_state=x?S1:S0; S1:next_state=x?S1:S2; S2:next_state=x?S1:S0; default:next_state=S0; endcase end assign z=(state==S2)&&x; endmodule
这里使用的是两段式,输出直接使用组合逻辑。我一开始写的三段式,输出用的时序逻辑,输入会同时改变次态和输出,所以电路综合出来显示一直是0,晕。
下面是代码,用来当反面教材。
module top_module ( input clk, input aresetn, // Asynchronous active-low reset input x, output reg z ); reg[1:0]state,next_state; parameter S0=0,S1=1,S2=2; always@(posedge clk or negedge aresetn) begin if(~aresetn) state <= S0; else state <= next_state; end always@(*) begin case(state) S0:next_state=x?S1:S0; S1:next_state=x?S1:S2; S2:next_state=x?S1:S0; default:next_state=S0; endcase end always@(posedge clk or negedge aresetn) begin if(~aresetn) z <= 1'b0; else begin case(next_state) S0:z <= 1'b0; S1:z <= 1'b0; S2:z <= x; default:z <= 1'b0; endcase end end endmodule
Exams/ece241 2014 q5a
这道题一开始没看懂啥意思,看了一下Rong晔大佬的视频才懂。
大概意思就是遇到第一个1时开始进行取反运算,由于1000的补码仍然是1000,所以第一个1保持不变,后面出现的高位全部取反。
注意这里只需要对输入进行补码运算,不需要也没有办法判断输入的数到底是正数还是负数(一开始就是没想清楚这一点),所以无脑对输入进行计算就可以了。
这里用S1代表需要输出1,S2代表需要输出0。
module top_module ( input clk, input areset, input x, output z ); reg [1:0] state,next_state; parameter S0=0,S1=1,S2=2; always@(posedge clk or posedge areset) begin if(areset) state <= S0; else state <= next_state; end always@(*) begin case(state) S0:next_state=x?S1:S0; S1:next_state=x?S2:S1; S2:next_state=x?S2:S1; endcase end assign z=(state == S1); endmodule
Exams/ece241 2014 q5b
和上一题是一样的,注意Moore状态机比Mealy状态机多一个状态,并且Mealy状态机直接使用组合逻辑输出会相比Moore状态机提前一个周期。
module top_module ( input clk, input areset, input x, output z ); reg [1:0]state,next_state; parameter S0=2'b01,S1=2'b10; always@(posedge clk or posedge areset) begin if(areset) state <= S0; else state <= next_state; end always@(*) begin case(state) S0:next_state=x?S1:S0; S1:next_state=S1; default:next_state=S0; endcase end assign z=(state[0]&&x)||(state[1]&&~x); endmodule
Exams/2014 q3fsm
这道题正确率只有13%
主要困难的地方在于计数每三个周期里w有多少个1,由于这里计数是连续的,所以w的计数不能简单的清零,在第一个周期时便可以开始判断w的值,并决定初始化为0还是1。
module top_module ( input clk, input reset, // Synchronous reset input s, input w, output z ); parameter A=0,B=1; reg state,next_state; reg [1:0]w_count,count; always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end always@(*) begin case(state) A:next_state=s?B:A; B:next_state=B; endcase end always@(posedge clk) begin if(reset) count <= 'd0; else begin if((state==B)&&count <2) begin count <= count + 1'b1; end else begin count <= 'd0; end end end always@(posedge clk) begin if(reset) w_count <= 'd0; else if(state ==B) begin if(count ==0) begin if(w) w_count <= 'd1; else w_count <= 'd0; end else if(w) w_count <= w_count +1'b1; end end assign z=(count == 'd0)&&(w_count ==2); endmodule
Exams/2014 q3bfsm
终于来了一道简单题。
module top_module ( input clk, input reset, // Synchronous reset input x, output z ); parameter S0=3'b000; parameter S1=3'b001; parameter S2=3'b010; parameter S3=3'b011; parameter S4=3'b100; reg[2:0]state,next_state; always@(posedge clk) begin if(reset) state <= S0; else state <= next_state; end always@(*) begin case(state) S0:next_state=x?S1:S0; S1:next_state=x?S4:S1; S2:next_state=x?S1:S2; S3:next_state=x?S2:S1; S4:next_state=x?S4:S3; default:next_state=S0; endcase end assign z=(state==S3)||(state==S4); endmodule
Exams/2014 q3c
这道题给的clk没啥用。
module top_module ( input clk, input [2:0] y, input x, output Y0, output z ); parameter S0=3'b000; parameter S1=3'b001; parameter S2=3'b010; parameter S3=3'b011; parameter S4=3'b100; reg[2:0]next_state; always@(*) begin case(y) S0:next_state=x?S1:S0; S1:next_state=x?S4:S1; S2:next_state=x?S1:S2; S3:next_state=x?S2:S1; S4:next_state=x?S4:S3; default:next_state=S0; endcase end assign z=(y==S3)||(y==S4); assign Y0=next_state[0]; endmodule
Exams/m2014 q6b
这题只要求把Y2逻辑写出来,Y2只在两种情况为1,即状态C和状态D,把所有会跳转到这两种状态的情况列举出来即可。
module top_module ( input [3:1] y, input w, output Y2); parameter A=3'b000; parameter B=3'b001; parameter C=3'b010; parameter D=3'b011; parameter E=3'b100; parameter F=3'b101; assign Y2=(y==B&&~w)||(y==F&&~w)|| (y==B&&w)||(y==C&&w)||(y==E&&w)||(y==F&&w); endmodule
Exams/m2014 q6c
做过的题型,要求使用独热码编码。
module top_module ( input [6:1] y, input w, output Y2, output Y4); parameter A=6'b000_001; parameter B=6'b000_010; parameter C=6'b000_100; parameter D=6'b001_000; parameter E=6'b010_000; parameter F=6'b100_000; assign Y2=y[1]&&~w; assign Y4=(y[2]&&w)||(y[3]&&w)||(y[5]&&w)||(y[6]&&w); endmodule
Exams/m2014 q6
直接接着上一题写。
module top_module ( input clk, input reset, // synchronous reset input w, output z); parameter A=6'b000_001; parameter B=6'b000_010; parameter C=6'b000_100; parameter D=6'b001_000; parameter E=6'b010_000; parameter F=6'b100_000; reg [6:1]state,next_state; always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end assign next_state[1]=(state[1]&&w)||(state[4]&&w); assign next_state[2]=state[1]&&~w; assign next_state[3]=(state[2]&&~w)||(state[6]&&~w); assign next_state[4]=(state[2]&&w)||(state[3]&&w)||(state[5]&&w)||(state[6]&&w); assign next_state[5]=(state[3]&&~w)||(state[5]&&~w); assign next_state[6]=state[4]&&~w; assign z=state[5]||state[6]; endmodule
Exams/2012 q2fsm
和上一题是一样的,只不过按题目要求用了两个always。
module top_module ( input clk, input reset, // Synchronous active-high reset input w, output z ); parameter A=3'b000; parameter B=3'b001; parameter C=3'b010; parameter D=3'b011; parameter E=3'b100; parameter F=3'b101; reg [6:1]state,next_state; always@(posedge clk) begin if(reset) state <= A; else state <= next_state; end always@(*) begin case(state) A:next_state=w?B:A; B:next_state=w?C:D; C:next_state=w?E:D; D:next_state=w?F:A; E:next_state=w?E:D; F:next_state=w?C:D; default:next_state=A; endcase end assign z=(state==E)||(state==F); endmodule
Exams/2012 q2b
为啥还是这道题,稍微变了一点逻辑。
module top_module ( input [5:0] y, input w, output Y1, output Y3 ); assign Y1=y[0]&&w; assign Y3=(y[1]&&~w)||(y[2]&&~w)||(y[4]&&~w)||(y[5]&&~w); endmodule
Exams/2013 q2afsm
这个状态机是一个仲裁器,不难看出,三个设备具有不同的优先级,B>C>D,根据状态转移图不难得出方程。
一开始写错了,因为r1、r2、r3顺序搞错了,晕。
module top_module ( input clk, input resetn, // active-low synchronous reset input [3:1] r, // request output [3:1] g // grant ); parameter A=0,B=1,C=2,D=3; reg [1:0]state,next_state; always@(posedge clk) begin if(~resetn) state <= A; else state <= next_state; end always@(*) begin case(state) A:begin casex(r) 3'b000:next_state=A; 3'bxx1:next_state=B; 3'bx10:next_state=C; 3'b100:next_state=D; endcase end B:next_state=r[1]?B:A; C:next_state=r[2]?C:A; D:next_state=r[3]?D:A; endcase end assign g[1]=state==B; assign g[2]=state==C; assign g[3]=state==D; endmodule
Exams/2013 q2bfsm
疯狂加状态就完事了,主要是要理解题目意思,一步一步写就行了。
module top_module ( input clk, input resetn, // active-low synchronous reset input x, input y, output f, output g ); parameter A=0,B=1,C=2,D=3,E=4,F=5,G=6,H=7,I=8; reg [3:0]state,next_state; always@(posedge clk) begin if(~resetn) state <= A; else state <= next_state; end always@(*) begin case(state) A:next_state=B; B:next_state=C; C:next_state=x?D:C; D:next_state=x?D:E; E:next_state=x?F:C; F:next_state=y?H:G; G:next_state=y?H:I; H:next_state=H;//g=1 I:next_state=I;//g=0; endcase end assign f=(state==B); assign g=(state==F)||(state==G)||(state==H); endmodule
写了一个星期终于写完这一节了,泪目。