Verilog学习-04

 考研上微电子入了材料坑,开始自学verilog

此文很多也是在其他优秀的博文中复制过来

(在此也非常感谢大家在网上分享的笔记)

仅为方便记录自己学习的笔记

习题链接:HDLBits

三,电路

3.2,时序逻辑电路

 状态机

状态机

简单说是通过不同的状态迁移来完成一些特定的顺序逻辑。

状态机分类

Moore型:状态机的输出仅和当前状态有关;

Mealy型:状态机的输出不仅和当前状态有关,还取决于当前的输入条件。

当两者实现同一种功能的时候,moore型状态机需要比mealy型状态机多定义一个状态,且输出也比mealy型延后一个时钟周期。之所以多一个状态,是因为moore型的输出只取决于当前状态,因此需要有一个中间状态来产生输出。

由于Mealy型输出直接受到输入的影响,这使得输入信号的噪声可能会出现在输出信号上。

// Moore型
assign out = state == B ;//表示,输出只和状态B有关,当状态为B的时候,不管输入是多少,都输出1。

// Mealy型
assign out = ((state == B) && (in == 1)) ; //表示输出和状态以及输入有关,当状态为B且输入等于1的时候输出1.

状态机的写法
状态机一般包括三种写法:一段式、两段式和三段式。
(1)一段式:整个状态机写到一个always块里面,在该块中既描述状态寄存器,又描述状态转移和输出;

(2)二段式:用两个always块来描述状态机,一个always块采用同步时序描述状态转移;另一个块采用组合逻辑判断状态转移条件和状态输出;

(3)三段式:使用三个always块,一个always块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always块描述状态输出(可以用组合电路输出,也可以时序电路输出)。(三段式参考同步复位)

状态机编码方式
独热码、格雷码。
独热码永远只有一位为1,缺点:用独热码后会有多余的状态;优点:可减少组合逻辑资源的消耗,比如在描述输出的时候,当采用组合逻辑进行比较的时候,可以只用其中的一位。assign state = S1[0] ;
格雷码相邻两个数只有一位不同;优点:状态少,而且可以避免毛刺出现;缺点:消耗组合逻辑资源多。assign state = S1;

注意:写case语句时,需要要加上default的情况,不然的话,会生成锁存器(跟电平有关),但在时序逻辑中,不加default生成的不是锁存器,是触发器。其中default分支可以用默认项表示,也可以用确定向来表示,以确保能最初状态。

简单状态机

异步复位

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
        case(state)// State transition logic
            A:next_state=in?A:B;
            B:next_state=in?B:A;
        endcase
    end

    always @(posedge clk, posedge areset) begin    // This is a sequential always block
        if(areset==1)// State flip-flops with asynchronous reset
            state	<=	B;
        else
            state	<=	next_state;
    end

    // Output logic
    assign	out	=	(state==B);// assign out = (state == ...);

endmodule

同步复位

// 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;//  
    reg out;

	parameter A = 1'b0,
    		  B = 1'b1;    
    reg c_state;
    reg n_state;
    
    //第一段 描述状态的转移 同步时序逻辑
    always @(posedge clk) begin
        if (reset == 1'b1)
            c_state <= B;
        else
            c_state <= n_state;
    end            
    //第二段 描述状态转移的条件 组合逻辑
    always @(*) begin
        case(c_state)
            A : begin
                if (in == 1'b1)
                    n_state = A;
                else
                    n_state = B;
            end
            B : begin
                if (in == 1'b1)
                    n_state = B;
                else
                    n_state = A;
            end
            default: n_state = B;
        endcase
    end
    //第三段 描述状态的输出
    always @(posedge clk) begin
        if (reset == 1'b1)
            out <= 1'b1;
        else begin
            case (n_state)
                A : out <= 1'b0;
                B : out <= 1'b1;
            endcase
        end
    end

endmodule
三状态转换

The following is the state transition table for a Moore state machine with one input, one output, and four states. Use the following state encoding:

A=2'b00, B=2'b01, C=2'b10, D=2'b11.

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;

    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
        if(state==D)
            out	=	1;
        else
            out	=	0;
    end

endmodule

 parameter定义常量,可以定义在模块内部或外部;常用于定义位宽或时间延迟(易变),此处以加一个常数的电路进行示例,如下:定义方式为: parameter 标识符 = (位宽)常数;// 位宽默认为32位,如果指定位宽则以指定值为准

The following is the state transition table for a Moore state machine with one input, one output, and four states. Use the following one-hot state encoding:

A=4'b0001, B=4'b0010, C=4'b0100, D=4'b1000.

图同上

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

The following is the state transition table for a Moore state machine with one input, one output, and four states. Implement this state machine. Include an asynchronous reset that resets the FSM to state A.

module top_module(
    input clk,
    input in,
    input areset,
    output out); //

    parameter	a=2'b00,b=2'b01,c=2'b10,d=2'b11;
    reg	[1:0]state,next;
  	// State transition logic
    always@(posedge	clk,posedge	areset)begin//异步复位用areset,同步复位时删去,下同
        if(areset==1)                       //当为同步复位时改为reset,下同
            state	<=	a;
        else
            state	<=	next;
    end
    // State flip-flops with asynchronous reset
    always@(*)begin
        case(state)
            a:next=in?b:a;
            b:next=in?b:c;
            c:next=in?d:a;
            d:next=in?b:c;
        endcase
    end
    // Output logic
    always@(posedge	clk,posedge	areset)begin
        if(areset==1)
            out	<=	0;
        else
            out	<=	(next==d);//当下个状态是d时,下一个状态的输出变为1
    end

endmodule
设计moore状态机

Also include an active-high synchronous reset that resets the state machine to a state equivalent to if the water level had been low for a long time (no sensors asserted, and all four outputs asserted).

module top_module (
    input clk,
    input reset,
    input [3:1] s,
    output fr3,
    output fr2,
    output fr1,
    output dfr
); 
    
    parameter	a=2'b00,b=2'b01,c=2'b10,d=2'b11;
    //对应四种状态,分别为above S3,between S3 and S2,between S2 and S1,below S1
    reg	[1:0]state,next;//现态,次态
    
    always@(posedge	clk)begin
        if(reset==1)
            state	<=	d;
        else
            state	<=	next;
    end
    always@(*)begin
        case(s)
            3'b111:next=a;
            3'b011:next=b;
            3'b001:next=c;
            3'b000:next=d;
        endcase
    end
    always@(posedge	clk)begin
        if(reset==1)
            dfr	<=	1'b1;//{fr3,fr2,fr1}<=3'b111;不可以写在这,当reset==1时,fr[3;1]=111,但是可能会被上一个always中状态转换成其他状态
        else	begin
            if(state>next)
            	dfr	<=	1'b0;
        	else	if(state<next)
            	dfr	<=	1'b1;
       	 	else
            	dfr	<=	dfr;
        end
        if(reset==1)
            {fr3,fr2,fr1}	<=	3'b111;
        else	begin
        	case({next})
            	3'b00:{fr3,fr2,fr1}	<=	3'b000;
            	3'b01:{fr3,fr2,fr1}	<=	3'b001;
            	3'b10:{fr3,fr2,fr1}	<=	3'b011;
            	3'b11:{fr3,fr2,fr1}	<=	3'b111;
            	default:{fr3,fr2,fr1}	<={fr3,fr2,fr1};
       	 	endcase
        end
    end

endmodule
旅鼠游戏

《旅鼠》这款游戏涉及大脑相当简单的动物,简单到我们要用有限状态机来建模。

1、在《旅鼠》的2D世界中,旅鼠可以有两种状态:向左走或向右走。如果碰到障碍物,它会改变方向。特别是,如果旅鼠在左边被撞了,它会向右走。如果它在右边被撞了一下,它就会向左走。如果两边同时碰撞,它仍然会改变方向。

2、除了左右行走之外,如果地面消失在它们脚下,旅鼠还会摔倒(大概会发出“啊!”的声音)。除了左右行走和颠簸时改变方向外,当地面=0时,旅鼠会摔倒并发出“啊!”当地面重新出现时(地面=1),旅鼠将继续沿着坠落前的方向行走。在下落过程中被撞不影响行走方向,在地面消失(但尚未下落)的同一周期内被撞,或者地面在下落过程中再次出现,也不影响行走方向。

3、除了走路和摔倒,旅鼠有时可以被告知做一些有用的事情,比如挖掘(当挖掘=1时它开始挖掘)。如果旅鼠目前在地面上行走(地面=1且不下落),它就可以挖掘,并将继续挖掘,直到到达另一边(地面=0)。在这一点上,因为没有地面,它会下降(啊!),然后继续朝原来的方向行走,一旦它再次落地。就像摔倒一样,在挖掘的时候被撞到是没有效果的,而在摔倒或者没有地面的时候被告知去挖掘也会被忽略。(换句话说,一个行走的旅鼠可以摔倒,挖洞,或者改变方向。如果满足这些条件中的一个以上,则fall的优先级高于dig,而dig的优先级高于切换方向。)

4、虽然旅鼠会走、会摔、会挖,但它们并非刀枪不入。如果旅鼠摔倒的时间太长,然后撞到地上,它就会溅到地上。特别是,如果一个旅鼠摔倒超过20个时钟周期,然后撞到地面,它将飞溅并停止行走,坠落或挖掘(所有4个输出都变为0),永远(或直到FSM被重置)。旅鼠在落地前的下落高度没有上限。旅鼠只会在撞到地面时溅起水花;它们不会在半空中飞溅。

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	l=0,r=1,fl=2,fr=3,dl=4,dr=5,fd=6;//左走,右走,左走掉下,右走掉下,左走下挖,右走下挖,摔死
    reg [3:0]state, next;//现态,次态
    reg	[7:0]cnt_clk;//时钟计数
    always @(posedge clk, posedge areset) begin//第一段 描述状态的转移 同步时序逻辑
        if(areset==1)// State flip-flops with asynchronous reset
            state	<=	l;
        else
            state	<=	next;
    end
	always @(*) begin//第二段 描述状态转移的条件 组合逻辑
        case(state)// State transition logic
            0:next=ground?dig?dl:bump_left?r:l:fl;
            1:next=ground?dig?dr:bump_right?l:r:fr;
            2:next=ground?{cnt_clk>8'd20}?fd:l:fl;
            3:next=ground?{cnt_clk>8'd20}?fd:r:fr;
            4:next=ground?dl:fl;
            5:next=ground?dr:fr;
            6:next=fd;
            default:next=l;
        endcase
    end
    always @(posedge clk, posedge areset) begin//第三段 描述状态的输出
        if(areset==1)begin
          	{walk_left,walk_right,aaah,digging}	<=	4'b1000;
            cnt_clk		<=	0;
        end   
        else	begin
             case(next)
             	0:begin
                	{walk_left,walk_right,aaah,digging}	<=	4'b1000;
                    cnt_clk		<=	0;
            	end
    			1:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0100;
                    cnt_clk		<=	0;
     			end
     			2:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0010;
                    cnt_clk		<=	cnt_clk	+1;
            	end
           		3:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0010;
                    cnt_clk		<=	cnt_clk	+1;
                end
                 4:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0001;
                    cnt_clk		<=	0;
            	end
        		5:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0001;
                    cnt_clk		<=	0;
             	end
                6:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b0000;
                end
                default:begin
                    {walk_left,walk_right,aaah,digging}	<=	4'b1000;
                    cnt_clk		<=	0;
            	end
           endcase
        end
    end

endmodule
 状态机热靴码

 这一题没整明白,次态一直在显示输出错误,这是自己写的:

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    
    parameter	s0=10'b0000000001,s1=10'b0000000010,s2=10'b0000000100,s3=10'b0000001000,s4=10'b0000010000,
    s5=10'b0000100000,s6=10'b0001000000,s7=10'b0010000000,s8=10'b0100000000,s9=10'b1000000000,s10=10'b0000000000;
    always@(*)begin
        casez(state)
            10'bzz_zzzz_zzz1:next_state = in? s1:s0;
            10'bzz_zzzz_zz10:next_state = in? s2:s0;
            10'bzz_zzzz_z100:next_state = in? s3:s0;
            10'bzz_zzzz_1000:next_state = in? s4:s0;
            10'bzz_zzz1_0000:next_state = in? s5:s0;
            10'bzz_zz10_0000:next_state = in? s6:s8;
            10'bzz_z100_0000:next_state = in? s7:s9;
            10'bzz_1000_0000:next_state = in? s7:s0;
            10'bz1_0000_0000:next_state = in? s1:s0;
            10'b10_0000_0000:next_state = in? s1:s0;
            s10:next_state	=	s10;
            default:next_state = s0;
        endcase
    end
    assign out1 = state[8] | state[9];
    assign out2 = state[7] | state[9];

endmodule

 当输入状态是像60(00 0110 0000)以及后面的12,22等有多个1的时候,输出就会报错,因为代码在检测state时,不能同时检测两个1,一直无法解决这个问题

 

在网上看了一些答案,很多都会在次态也是在显示输出错误,最后在网上找到一个答案

module top_module(
    input in,
    input [9:0] state,
    output [9:0] next_state,
    output out1,
    output out2);
    
    assign next_state[0] = ~in & (state[0] | state[1] | state[2] | state[3] | state[4] | state[7] | state[8] | state[9]);
    assign next_state[1] = in & (state[0] | state[8] | state[9]);
    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[6] | state[7]);
    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
PS/2鼠标协议

PS/2鼠标协议发送的消息长度为3字节。但是,在连续字节流中,消息的开始和结束位置并不明显。唯一的指示是,每个三字节消息的第一个字节总是具有in[3]=1(但其他两个字节的位[3]可能是1或0,这取决于数据)。

我们需要一个有限状态机,当给定输入字节流时,它将搜索消息边界。我们将使用的算法是丢弃字节,直到我们看到位[3]=1的字节。然后我们假设这是消息的第一个字节,一旦所有3个字节都被接收(done),就发出消息接收的信号。

在成功接收到每条消息的第三个字节后,FSM应该立即发出完成的信号。

请添加一条数据路径,以便在接收到数据包时也输出24位(3字节)消息(out_bytes[23:16]是第一个字节,out_bytes[15:8]是第二个字节,等等)。Out_bytes需要在断言done信号时有效。

您可以在其他时间输出任何内容(即,不关心)。

module top_module(
    input clk,
    input [7:0] in,
    input reset,    // Synchronous reset
    output [23:0] out_bytes,
    output done); //

	parameter	s0=0,s1=1,s2=2;
    reg	[1:0]state,next;
    always@(posedge	clk)begin
        if(reset==1)
            state	<=	s0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=in[3]?s1:s0;
            s1:next=s2;
            s2:next=s0;
            default:next=s0;
        endcase
    end
    always@(posedge	clk)begin
        if(reset==1)begin
            done	<=	0;
            out_bytes<=	0;
        end
        else	begin
            case(state)
                s0:out_bytes[23:16]	<=	in;
                s1:out_bytes[15:8]	<=	in;
                s2:out_bytes[7:0]	<=	in;
            endcase
            if(state==s2)
                done	<=	1;
            else
                done	<=	0;
        end
    end
    
endmodule
奇偶串行接收器

一,In many (older) serial communications protocols, each data byte is sent along with a start bit and a stop bit, to help the receiver delimit bytes from the stream of bits. One common scheme is to use one start bit (0), 8 data bits, and 1 stop bit (1). The line is also at logic 1 when nothing is being transmitted (idle).

Design a finite state machine that will identify when bytes have been correctly received when given a stream of bits. It needs to identify the start bit, wait for all 8 data bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte.

二,Now that you have a finite state machine that can identify when bytes are correctly received in a serial bitstream, add a datapath that will output the correctly-received data byte. out_byte needs to be valid when done is 1, and is don't-care otherwise.

Note that the serial protocol sends the least significant bit first.

三,We want to add parity checking to the serial receiver. Parity checking adds one extra bit after each data byte. We will use odd parity, where the number of 1s in the 9 bits received must be odd. For example, 101001011 satisfies odd parity (there are 5 1s), but 001001011 does not.

Change your FSM and datapath to perform odd parity checking. Assert the done signal only if a byte is correctly received and its parity check passes. Like the serial receiver FSM, this FSM needs to identify the start bit, wait for all 9 (data and parity) bits, then verify that the stop bit was correct. If the stop bit does not appear when expected, the FSM must wait until it finds a stop bit before attempting to receive the next byte.

You are provided with the following module that can be used to calculate the parity of the input stream (It's a TFF with reset). The intended use is that it should be given the input bit stream, and reset at appropriate times so it counts the number of 1 bits in each byte.

题目

这一题前两个问题都完成了,但是第三个奇偶校验这一题一直看的不是很明白,开始写的就是自己想的流程,但是仿真一直不对,后面发现定义的输出数据是8位后,有点懵,搞不明白为什么题目例子有9位数据,自己之前写的时候一直是以为是9位输出,S1状态也是停9个clk,现在彻底懵了。现在错误的地方应该是无法正确奇偶校验,导致无法进入S2状态。

以后在研究一下,最近各种事情,这题一直搞步明白搞的有点烦。

module top_module(
    input clk,
    input in,
    input reset,    // Synchronous reset
    output [7:0] out_byte,
    output done
); //
    parameter	s0=0,s1=1,s2=2,s3=3,so=4;//初始状态,计数状态,停止接收,等待状态,奇偶校验
    reg	odd;
    reg	[2:0]state,next;
    reg	[4:0]cnt;
    reg	[7:0]bytes;
    always@(posedge	clk)begin
        if(reset==1)
            state	<=	s0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=in?s0:s1;
            s1:begin
                next=(cnt==7)?odd?s2:s3:s1;
                bytes[cnt]=in;
            end
            s2:next=in?s0:s3;
            s3:next=in?s0:s3;
            default:next=s0;
        endcase
    end
    always@(posedge	clk)begin
        if(reset==1)begin
            done	<=	0;
            cnt		<=	0;
            odd		<=	0;
        end
        else	begin
            if(state==s1)begin
                cnt		<=	cnt+1;
                if(in==1)
                    odd	<=	~odd;
                else
                    odd	<=	odd;
            end
            else	begin
                cnt		<=	0;
                odd		<=	0;
            end
           if(state==s2	&&	in==1)begin
				done	<=	1;
                out_byte	<=	bytes;
            end
            else
                done	<=	0;
        end
    end
                
endmodule
 序列识别

Synchronous HDLC framing involves decoding a continuous bit stream of data to look for bit patterns that indicate the beginning and end of frames (packets). Seeing exactly 6 consecutive 1s (i.e., 01111110) is a "flag" that indicate frame boundaries. To avoid the data stream from accidentally containing "flags", the sender inserts a zero after every 5 consecutive 1s which the receiver must detect and discard. We also need to signal an error if there are 7 or more consecutive 1s.

Create a finite state machine to recognize these three sequences:

  • 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).

When the FSM is reset, it should be in a state that behaves as though the previous input were 0.

Here are some example sequences that illustrate the desired operation.

module top_module(
    input clk,
    input reset,    // Synchronous reset
    input in,
    output disc,
    output flag,
    output err);
    
    parameter	s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6;
    //初始状态,接收状态1,检测零状态,接收状态2,disc状态,flag状态,err状态
    reg	[3:0]state,next;
    reg	[3:0]cnt;
    always@(posedge	clk)begin
        if(reset==1)
            state	<=	s0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=in?s1:s0;
            s1:next=in?(cnt==4)?s2:s1:s0;
            s2:next=in?s3:s4;
            s3:next=in?s6:s5;
            s4:next=in?s1:s0;
            s5:next=in?s1:s0;
            s6:next=in?s6:s0;
            default:next=s0;
        endcase
    end
    always@(posedge	clk)begin
        if(reset==1)begin
            cnt	<=	0;
            disc<=	0;
            flag<=	0;
            err	<=	0;
        end
        else	begin
            case(next)//case(next)不可以用state,不然输出会迟一个状态
                s1:begin
                    cnt	<=	cnt+1;
                    {disc,flag,err}	<=	{3'b000};
                end
                s4:{cnt,disc,flag,err}	<=	{4'b0000,3'b100};
                s5:{cnt,disc,flag,err}	<=	{4'b0000,3'b010};
                s6:{cnt,disc,flag,err}	<=	{4'b0000,3'b001};
                default:{cnt,disc,flag,err}	<=	{4'b0000,3'b000};
           	endcase
        end
    end
                
endmodule
Mealy状态机设计

Implement a Mealy-type finite state machine that recognizes the sequence "101" on an input signal named x. Your FSM should have an output signal, z, that is asserted to logic-1 when the "101" sequence is detected. Your FSM should also have an active-low asynchronous reset. You may only have 3 states in your state machine. Your FSM should recognize overlapping sequences.

module top_module (
    input clk,
    input aresetn,    // Asynchronous active-low reset
    input x,
    output z ); 
    
    parameter	s0=0,s1=1,s2=2,s3=3;
    reg	[1:0]state,next;
    always@(posedge	clk	or	negedge	aresetn)begin
    //当时posedge A的时候,后面必须是if(A==1),当是negedge A的时候,后面必须是if(A==0)
        if(aresetn==0)
            state	<=	0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=x?s1:s0;
            s1:next=x?s1:s2;
            s2:next=x?s3:s0;
            s3:next=x?s1:s2;
            default:next=s0;
        endcase
    end
    assign	z	=	state==s2	&&	x==1;
    //开始一直打算输出用时序逻辑写,在always函数里面用case(next),后面发现无论自己怎么样写,都会导致输出状态迟一个时钟信号,现在暂时不知道用时序逻辑该怎么写

endmodule
字符串2的补码(Moore型)

You are to design a one-input one-output serial 2's complementer Moore state machine. The input (x) is a series of bits (one per clock cycle) beginning with the least-significant bit of the number, and the output (Z) is the 2's complement of the input. The machine will accept input numbers of arbitrary length. The circuit requires an asynchronous reset. The conversion begins when Reset is released and stops when Reset is asserted.

分析

1,对一个二进制数取补码有两种方法,一种是取反加1,另一种是将从LSB开始的第一个1之后的位全部取反。
2,分为三种状态,s0:全为0,没有1,则补码为本身;s1:最高位为1,其他为0,即仅接收到第一个1,补码为本身;s2:接收到第一个1之后的状态,补码为第一个1之后的位取反。
3,根据2中分析,对于下一状态为s0和s1的,在上升沿取输入值为输出值,即本身;对于下一状态为s2的,上升沿取输入值的反为输出。
 

module top_module (
    input clk,
    input areset,
    input x,
    output z
); 
    parameter	s0=0,s1=1,s2=2;
    reg	[1:0]state,next;
   	always@(posedge clk	or	posedge	areset)begin
        if(areset==1)
            state	<=	s0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=x?s1:s0;
            s1:next=s2;
            s2:next=s2;
            default:next=s0;
      	endcase
    end
    always@(posedge	clk or	posedge	areset)begin
        if(areset==1)
            z	<=	0;
        else	begin
            case(next)
                s0:z	<=	x;
                s1:z	<=	x;
                s2:z	<=	~x;
         	endcase
 		end
    end
endmodule
字符串2的补码(Mealy型)

module top_module (
    input clk,
    input areset,
    input x,
    output z
);
    parameter	s0=0,s1=1;
    reg	state,next;
    always@(posedge	clk	or	posedge	areset)begin
        if(areset==1)
           state	<=	s0;
        else
           state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=x?s1:s0;
            s1:next=s1;
            default:next=s0;
        endcase
    end
    assign	z	=	(state==s1	&&	x==0)	||	(state==s0	&&	x==1);
endmodule

 (2023.12.26)

独热码编码状态机

For this part, assume that a one-hot code is used with the state assignment 'y[6:1] = 000001, 000010, 000100, 001000, 010000, 100000 for states A, B,..., F, respectively.

Write a logic expression for the next-state signals Y2 and Y4. (Derive the logic equations by inspection assuming a one-hot encoding. The testbench will test with non-one hot inputs to make sure you're not trying to do something more complicated).

本以为很简单和之前的题目一样就是简单的状态变换,就快速的写下这样的代码:

module top_module (
    input [6:1] y,
    input w,
    output Y2,
    output Y4);
    parameter	a=6'b000001,b=6'b000010,c=6'b000100,d=6'b001000,e=6'b010000,f=6'b100000;
    reg	[6:1]next;
    always@(*)begin
        case(y)
            a:next=w?a:b;
            b:next=w?d:c;
            c:next=w?d:e;
            d:next=w?a:f;
            e:next=w?d:e;
            f:next=w?d:c;
            default:next=a;
        endcase
    end
   	assign	Y2	=	next[2];
    assign	Y4	=	next[4];

endmodule

但是仿真后报错了

因为仿真时候,输入不仅是0000001,000010等这样之前设定好的数值,也有像36,12,9等原本没有的数值。感觉不能简单的根据状态转换来写,应该根据每一位每个位输出1时的式子来判断输出Y2和Y4

module top_module (
    input [6:1] y,
    input w,
    output Y2,
    output Y4);
    
    reg	[6:1]next;
    assign next[1] = (y[1]|y[4])&w;
    assign next[2] = (y[1]&~w);
    assign next[3] = (y[2]|y[6])&~w;
    assign next[4] = (y[2]|y[3]|y[5]|y[6])&w;
    assign next[5] = (y[3]|y[5])&~w;
    assign next[6] = (y[4]&~w);
    
   	assign	Y2	=	next[2];
    assign	Y4	=	next[4];

endmodule

 说实话,感觉其实也没啥意思这一题

最后一题

Consider a finite state machine that is used to control some type of motor. The FSM has inputs x and y, which come from the motor, and produces outputs f and g, which control the motor. There is also a clock input called clk and a reset input called resetn.

The FSM has to work as follows. As long as the reset input is asserted, the FSM stays in a beginning state, called state A. When the reset signal is de-asserted, then after the next clock edge the FSM has to set the output f to 1 for one clock cycle. Then, the FSM has to monitor the x input. When x has produced the values 1, 0, 1 in three successive clock cycles, then g should be set to 1 on the following clock cycle. While maintaining g = 1 the FSM has to monitor the y input. If y has the value 1 within at most two clock cycles, then the FSM should maintain g = 1 permanently (that is, until reset). But if y does not become 1 within two clock cycles, then the FSM should set g = 0 permanently (until reset).

(The original exam question asked for a state diagram only. But here, implement the FSM.)

module top_module (
    input clk,
    input resetn,    // active-low synchronous reset
    input x,
    input y,
    output f,
    output g
); 
    parameter	s0=0,s1=1,s2=2,s3=3,s4=4,s5=5,s6=6,s7=7,s8=8;
    reg	[3:0]state,next;
    always@(posedge	clk)begin
        if(resetn==0)
            state	<=	s0;
        else
            state	<=	next;
    end
    always@(*)begin
        case(state)
            s0:next=s1;
            s1:next=x?s3:s2;
            s2:next=x?s3:s2;
            s3:next=x?s3:s4;
            s4:next=x?s5:s2;
            s5:next=y?s8:s6;
            s6:next=y?s8:s7;
            s7:next=s7;
            s8:next=s8;
            default:next=s8;
        endcase
    end
    always@(posedge	clk)begin
        if(resetn==0)
        	{f,g}	<=	2'b00;
        else	begin
            case(next)
                s1:{f,g}	<=	2'b10;
                s5:{f,g}	<=	2'b01;
                s6:{f,g}	<=	2'b01;
                s8:{f,g}	<=	2'b01;
                default:{f,g}	<=	2'b00;
            endcase
        end
    end
    
endmodule

输出一直有点问题,但是检查好一会,没检查出来到底哪有问题,最近搞论文的事情弄得很烦,不想搞了,有时间再来看看吧。

(2024.01.04)

  • 24
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值