VL75. 求最小公倍数
描述
设计一个时序电路,输入2个无符号数,位宽可以通过参数DATA_W确定,输出这两个数的最小公倍数和最大公约数。
要求使用Verilog HDL语言实现,并编写testbench验证模块的功能。
输入描述
clk::时钟信号
rst_n:复位信号,低电平有效
A:输入信号,位宽可以通过DATA_W指定
B:输入信号,位宽可以通过DATA_W指定
vld_in:输入数据有效的指示信号
输出描述
lcm_out:输出最小公倍数
mcd_out:输出最大公约数
vld_out:输出数据有效的指示信号
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05
`timescale 1ns/1ns module lcm#( parameter DATA_W = 8) ( input [DATA_W-1:0] A, input [DATA_W-1:0] B, input vld_in, input rst_n, input clk, output wire [DATA_W*2-1:0] lcm_out, output wire [DATA_W-1:0] mcd_out, output reg vld_out ); reg [DATA_W*2-1:0] mcd,a_buf,b_buf; reg [DATA_W*2-1:0] mul_buf; reg mcd_vld; reg [1:0] cur_st,nxt_st; parameter IDLE= 2'b00,S0 = 2'b01, S1 = 2'b10, S2 = 2'b11; //两段式状态机 always @(posedge clk or negedge rst_n) if (!rst_n) cur_st <= IDLE; else cur_st <= nxt_st; always @(posedge clk or negedge rst_n) if (!rst_n) begin nxt_st <= IDLE; mcd <= 0; mcd_vld <= 0; a_buf <= 0; b_buf <= 0; mul_buf <= 0; vld_out <= 1'b0; end else begin case (cur_st) IDLE:if(vld_in) begin a_buf <= A; b_buf <= B; nxt_st <= S0; mul_buf <= A*B; mcd_vld <= 0; vld_out <= 1'b0; end else begin nxt_st <= IDLE; mcd_vld <= 0; vld_out <= 1'b0; end S0:if(a_buf!=b_buf)begin if(a_buf>b_buf)begin a_buf<=a_buf-b_buf; b_buf<=b_buf; end else begin b_buf <= b_buf - a_buf; a_buf <= a_buf; vld_out <= 1'b0; end nxt_st <= S0; end else begin nxt_st <=S1; vld_out <= 1'b0; end S1:begin mcd <= b_buf; mcd_vld <= 1'b1; nxt_st <= IDLE; vld_out <= 1'b1; end default:begin nxt_st<=IDLE; vld_out <= 1'b0; end endcase end assign mcd_out = mcd; assign lcm_out = mul_buf/mcd; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-05
`timescale 1ns/1ns module lcm#( parameter DATA_W = 8) ( input [DATA_W-1:0] A, input [DATA_W-1:0] B, input vld_in, input rst_n, input clk, output wire [DATA_W*2-1:0] lcm_out, output wire [DATA_W-1:0] mcd_out, output reg vld_out ); reg [DATA_W*2-1:0] mcd,a_buf,b_buf; reg [DATA_W*2-1:0] mul_buf; reg mcd_vld; reg [1:0] cur_st,nxt_st; parameter IDLE= 2'b00,S0 = 2'b01, S1 = 2'b10, S2 = 2'b11; //两段式状态机 always @(posedge clk or negedge rst_n) if (!rst_n) cur_st <= IDLE; else cur_st <= nxt_st; always @(posedge clk or negedge rst_n) if (!rst_n) begin nxt_st <= IDLE; mcd <= 0; mcd_vld <= 0; a_buf <= 0; b_buf <= 0; mul_buf <= 0; vld_out <= 1'b0; end else begin case (cur_st) IDLE:if(vld_in) begin a_buf <= A; b_buf <= B; nxt_st <= S0; mul_buf <= A*B; mcd_vld <= 0; vld_out <= 1'b0; end else begin nxt_st <= IDLE; mcd_vld <= 0; vld_out <= 1'b0; end S0:if(a_buf!=b_buf)begin if(a_buf>b_buf)begin a_buf<=a_buf-b_buf; b_buf<=b_buf; end else begin b_buf <= b_buf - a_buf; a_buf <= a_buf; vld_out <= 1'b0; end nxt_st <= S0; end else begin nxt_st <=S1; vld_out <= 1'b0; end S1:begin mcd <= b_buf; mcd_vld <= 1'b1; nxt_st <= IDLE; vld_out <= 1'b1; end default:begin nxt_st<=IDLE; vld_out <= 1'b0; end endcase end assign mcd_out = mcd; assign lcm_out = mul_buf/mcd; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-04
`timescale 1ns/1ns module lcm#( parameter DATA_W = 8) ( input [DATA_W-1:0] A, input [DATA_W-1:0] B, input vld_in, input rst_n, input clk, output wire [DATA_W*2-1:0] lcm_out, output wire [DATA_W-1:0] mcd_out, output reg vld_out ); reg [DATA_W-1:0] atemp,btemp; reg [DATA_W*2-1:0] mcd,lcm_buf; reg [1:0] state, nexts; parameter IDLE = 2'b00, BUSY = 2'b01, VALID = 2'b10; always@(posedge clk or negedge rst_n) begin if(!rst_n) state <= IDLE; else state <= nexts; end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin atemp <= 0; btemp <= 0; mcd <= 0; lcm_buf <= 0; vld_out <= 0; nexts <= IDLE; end else case(state) IDLE: if(vld_in) begin //注意这里不能把mcd的寄存器清零,不然assign的除法会报错。 atemp <= A; btemp <= B; vld_out <= 0; lcm_buf <= A*B; nexts <= BUSY; end else begin nexts <= IDLE; vld_out <= 0; end BUSY: begin if(atemp!=btemp) begin nexts <= BUSY; if(atemp>btemp) begin atemp <= atemp-btemp; btemp <= btemp; end else begin btemp <= btemp-atemp; atemp <= atemp; end end else begin vld_out <= 0; nexts <= VALID; end end VALID: begin mcd <= btemp; vld_out <= 1; nexts <= IDLE; end default: begin vld_out <= 0; nexts <= IDLE; end endcase end assign mcd_out = mcd; assign lcm_out = lcm_buf/mcd; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-04
`timescale 1ns/1ns module lcm#( parameter DATA_W = 8) ( input [DATA_W-1:0] A, input [DATA_W-1:0] B, input vld_in, input rst_n, input clk, output wire [DATA_W*2-1:0] lcm_out, output wire [DATA_W-1:0] mcd_out, output reg vld_out ); reg [DATA_W*2-1:0] mcd,a_buf,b_buf; reg [DATA_W*2-1:0] mul_buf; reg mcd_vld; reg [1:0] cur_st,nxt_st; parameter IDLE= 2'b00,S0 = 2'b01, S1 = 2'b10, S2 = 2'b11; //两段式状态机 always @(posedge clk or negedge rst_n) if (!rst_n) cur_st <= IDLE; else cur_st <= nxt_st; always @(posedge clk or negedge rst_n) if (!rst_n) begin nxt_st <= IDLE; mcd <= 0; mcd_vld <= 0; a_buf <= 0; b_buf <= 0; mul_buf <= 0; vld_out <= 1'b0; end else begin case (cur_st) IDLE:if(vld_in) begin a_buf <= A; b_buf <= B; nxt_st <= S0; mul_buf <= A*B; mcd_vld <= 0; vld_out <= 1'b0; end else begin nxt_st <= IDLE; mcd_vld <= 0; vld_out <= 1'b0; end S0:if(a_buf!=b_buf)begin if(a_buf>b_buf)begin a_buf<=a_buf-b_buf; b_buf<=b_buf; end else begin b_buf <= b_buf - a_buf; a_buf <= a_buf; vld_out <= 1'b0; end nxt_st <= S0; end else begin nxt_st <=S1; vld_out <= 1'b0; end S1:begin mcd <= b_buf; mcd_vld <= 1'b1; nxt_st <= IDLE; vld_out <= 1'b1; end default:begin nxt_st<=IDLE; vld_out <= 1'b0; end endcase end assign mcd_out = mcd; assign lcm_out = mul_buf/mcd; endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-04
`timescale 1ns/1ns module lcm#(parameter DATA_W = 8)( input [DATA_W-1:0] A, input [DATA_W-1:0] B, input vld_in, input rst_n, input clk, output wire [DATA_W*2-1:0] lcm_out, output wire [DATA_W-1:0] mcd_out, output reg vld_out ); reg [DATA_W*2-1:0] mcd,a,b; reg [DATA_W*2-1:0] mul_buf; //reg mcd_vld; reg [1:0] cur_st,nxt_st; parameter IDLE= 2'b00,S0 = 2'b01, S1 = 2'b10, S2 = 2'b11; //两段式状态机 always @(posedge clk or negedge rst_n) if (!rst_n) cur_st <= IDLE; else cur_st <= nxt_st; always @(posedge clk or negedge rst_n) if (!rst_n) begin nxt_st <= IDLE; mcd <= 0; a <= 0; b <= 0; mul_buf <= 0; vld_out <= 1'b0; end else begin case (cur_st) IDLE:if(vld_in) begin a <= A; b <= B; nxt_st <= S0; mul_buf <= A*B; vld_out <= 1'b0; end else begin nxt_st <= IDLE; vld_out <= 1'b0; end S0:if(a!=b)begin if(a>b) a<=a-b; else b <= b-a; nxt_st <= S0; end else nxt_st <=S1; S1:begin mcd <= b; nxt_st <= IDLE; vld_out <= 1'b1; end default:begin nxt_st<=IDLE; vld_out <= 1'b0; end endcase end assign mcd_out = mcd; assign lcm_out = mul_buf/mcd; endmodule