Verilog语法学习——LV4_移位运算与乘法

LV4_移位运算与乘法

题目来源于牛客网

[牛客网在线编程_Verilog篇_Verilog快速入门 (nowcoder.com)](https://www.nowcoder.com/exam/oj?page=1&tab=Verilog篇&topicId=301)

题目

题目描述:

已知d为一个8位数,请在每个时钟周期分别输出该数乘1/3/7/8,并输出一个信号通知此时刻输入的d有效(d给出的信号的上升沿表示写入有效)

信号示意图:

Verilog语法学习——LV4_移位运算与乘法_第1张图片

波形示意图:

Verilog语法学习——LV4_移位运算与乘法_第2张图片

输入描述:

输入信号 d, clk, rst
类型 wire
在testbench中,clk为周期5ns的时钟,rst为低电平复位

输出描述:

输出信号 input_grant out
类型 reg

状态机

在Verilog中,可以使用always语句和case语句来实现状态机。

首先,声明一个状态寄存器state_reg,用于存储当前状态的值。状态寄存器通常是一个有限状态机中的关键变量。

reg [2:0] state_reg;

always @(posedge clk) 块中,使用case语句根据当前的状态值执行相应的操作。在时钟的上升沿触发该always块。

always @(posedge clk) begin
    case (state_reg)
        // 根据当前状态执行相应操作
        // 每个状态对应一个case
        // 每个case中描述该状态下的行为
    endcase
end

在每个case中,根据当前的状态值执行相应的操作。每个case对应一个状态,并描述在该状态下的行为。

always @(posedge clk) begin
    case (state_reg)
        // 状态1
        2'd0: begin
            // 在状态1执行的操作
            // 可以包括信号的赋值、状态变迁等
        end
        
        // 状态2
        2'd1: begin
            // 在状态2执行的操作
        end
        
        // 状态3
        2'd2: begin
            // 在状态3执行的操作
        end
        
        default: begin
            // 默认情况下的操作,当状态寄存器的值不匹配任何已定义的状态时执行
        end
    endcase
end

代码

`timescale 1ns/1ns
	module multi_sel(
	input [7:0]d ,
	input clk,
	input rst,
	output reg input_grant,
	output reg [10:0]out
);
//*************code***********//
/*代码思路:使用状态机,进行逻辑跳转。可以借此题来练习状态机
1.声明状态寄存器
2.状态之间的转换
3.每个状态执行的操作
	将乘法改为移位来计算,可以节省资源*/

//声明参数,状态寄存器
	parameter	IDLE	= 3'd0;		//空状态
	parameter	M1		= 3'd1;		//M1时,输入有效(input_grant=1)
	parameter	M3		= 3'd2;
	parameter	M7		= 3'd3;
	parameter	M8		= 3'd4;
	
	reg [2:0]	current_state;
	reg [2:0]	next_state;
	reg [7:0]	d_tool;	//此变量是存储输入有效时d的值
	
//状态之间的转换
	always @(posedge clk or negedge rst) begin
		if(!rst)
			current_state <= IDLE;
		else 
			current_state <= next_state;
	end
//不同状态所要执行的操作
	always @(*) begin	//和时钟、复位无关
		case (current_state)
			IDLE : begin
				input_grant <= 0;
				out <= 0;
				next_state <= M1;
			end
			M1 : begin
				input_grant <= 1;
				out <= d_tool;
				next_state <= M3;
			end
			M3 : begin
				input_grant <= 0;
				out <= (d_tool << 2'd2) - d_tool;
				next_state <= M7;
			end
			M7 : begin
				input_grant <= 0;
				out <= (d_tool << 2'd3) - d_tool;
				next_state <= M8;
			end
			M8 : begin
				input_grant <= 0;
				out <= (d_tool << 2'd3);
				next_state <= M1;
			end
			default : begin
				input_grant <= 0;
				out <= 0;
				next_state <= IDLE;
			end	
		endcase	
	end
//输入有效数据 d_tool 和实际的输入 d 的关系
	always @(posedge clk or negedge rst) begin
		if(!rst)
			d_tool <= 0;
		else begin
			if(current_state == IDLE)
				d_tool <= d;
			else if(current_state == M8)
				d_tool <= d;
			else 
				d_tool <= d_tool;
		
		end
	end

//*************code***********//
endmodule

你可能感兴趣的:(Verilog语法学习,fpga开发)