天天看點

非整數倍位寬轉換(Verilog)

RTL代碼:

module fsm(
	input clk,
	input rst_n,
	input [7:0]data_in,
	output reg [11:0]data_out
);

	reg [11:0]data_out_r1;
	reg [11:0]data_out_r2;
	reg [1:0]cnt;
	
	[email protected](posedge clk or negedge rst_n)begin
		if(!rst_n)
			cnt <= 'd0;
		else if(cnt == 'd2)
			cnt <= 'd0;
		else 
			cnt <= cnt + 1'b1;
	end
	
	[email protected](posedge clk or negedge rst_n)begin
		if(!rst_n)begin
			data_out_r1 <= 'd0;
			data_out_r2 <= 'd0;
			data_out <= 'd0;
		end
		else if(cnt == 'd0)begin
			data_out_r1 <= {4'b0,data_in};
			data_out_r2 <= data_out_r2;
			data_out <= data_out_r2;
		end
		else if(cnt == 'd1)begin
			data_out_r1 <= {data_in[3:0],data_out_r1[7:0]};
			data_out_r2 <= {8'b0,data_in[7:4]};
			data_out <= data_out;
		end
		else if(cnt == 'd2)begin
			data_out_r1 <= data_out_r1;
			data_out_r2 <= {data_in,data_out_r2[3:0]};
			data_out <= data_out_r1;
		end
	end

endmodule


           

仿真代碼:

`timescale 1ns/1ns
module fsm_tb;

	reg clk;
	reg rst_n;
	reg [7:0]data_in;
	wire [11:0]data_out;
	
	fsm fsm_inst(
		.clk			(clk		),
		.rst_n		(rst_n	),
		.data_in		(data_in	),
		.data_out	(data_out)
);
	
	initial clk = 0;
	always#10 clk = ~clk;
	
	initial begin
		rst_n = 0;
		data_in = 'h0;
		#210;
		rst_n = 1;
		
		data_in = 'h12;
		#20;
		
		data_in = 'h34;
		#20;
		
		data_in = 'h56;
		#20;
		
		data_in = 'h78;
		#20;
		
		data_in = 'h9a;
		#20;
		
		data_in = 'hbc;
		#40;
		
		$stop;
	end

endmodule

           

仿真截圖:

非整數倍位寬轉換(Verilog)

繼續閱讀