动态延迟模块的verilog编写

在FPGA项目中遇到一个问题,大体是要实现不同数据的动态延迟,而且要实现流水作业。如下为示意图:


动态延迟模块的verilog编写_第1张图片

为此思考了方案一

动态延迟模块的verilog编写_第2张图片

--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

有了方案,开始设计每个模块的实现,这里分为三个部分设计

1 前仲裁模块

这个实现的就是每个有两路信号过来时(以flag上升沿为标志),将这个信号依次分配给delay模块,可以考虑类似于3-8编码器的设计思路

下面为block视图

动态延迟模块的verilog编写_第3张图片

d1到d8是8级缓存,实现8级流水,当有信号来时,依次分流到d1——d8,再循环。

下面为modelsim仿真图

动态延迟模块的verilog编写_第4张图片

2 delay模块

这个模块实际就是一个状态机就能解决,分为idle 和 计数延迟两个状态

block视图为

动态延迟模块的verilog编写_第5张图片


3 后仲裁模块

使用 “与” 操作将8路信号串行输出

 动态延迟模块的verilog编写_第6张图片

整体的block视图为

 动态延迟模块的verilog编写_第7张图片

给出testbanch文件

// Copyright (C) 1991-2011 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions 
// and other software and tools, and its AMPP partner logic 
// functions, and any output files from any of the foregoing 
// (including device programming or simulation files), and any 
// associated documentation or information are expressly subject 
// to the terms and conditions of the Altera Program License 
// Subscription Agreement, Altera MegaCore Function License 
// Agreement, or other applicable license agreement, including, 
// without limitation, that your use is for the sole purpose of 
// programming logic devices manufactured by Altera and sold by 
// Altera or its authorized distributors.  Please refer to the 
// applicable agreement for further details.

// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to  
// suit user's needs .Comments are provided in each section to help the user    
// fill out necessary details.                                                  
// *****************************************************************************
// Generated on "01/17/2015 20:08:08"
                                                                                
// Verilog Test Bench template for design : multi_delay
// 
// Simulation tool : ModelSim-Altera (Verilog)
// 

`timescale 1 ns/ 1 ps
module multi_delay_vlg_tst();
// constants                                           
// general purpose registers
reg [3:0] lval_cnt;
// test vector input registers
reg clk;
reg [23:0] data_in;
reg flag;
reg lval;
// wires                                               
wire [23:0]  d;
wire [23:0]  data_out1;
wire [23:0]  data_out2;
wire [23:0]  data_out3;
wire [23:0]  data_out4;
wire [23:0]  data_out5;
wire [23:0]  data_out6;
wire [23:0]  data_out7;
wire [23:0]  data_out8;
wire f;
wire flag_out1;
wire flag_out2;
wire flag_out3;
wire flag_out4;
wire flag_out5;
wire flag_out6;
wire flag_out7;
wire flag_out8;

// assign statements (if any)                          
multi_delay i1 (
// port map - connection between master ports and signals/registers   
	.clk(clk),
	.d(d),
	.data_in(data_in),
	.data_out1(data_out1),
	.data_out2(data_out2),
	.data_out3(data_out3),
	.data_out4(data_out4),
	.data_out5(data_out5),
	.data_out6(data_out6),
	.data_out7(data_out7),
	.data_out8(data_out8),
	.f(f),
	.flag(flag),
	.flag_out1(flag_out1),
	.flag_out2(flag_out2),
	.flag_out3(flag_out3),
	.flag_out4(flag_out4),
	.flag_out5(flag_out5),
	.flag_out6(flag_out6),
	.flag_out7(flag_out7),
	.flag_out8(flag_out8),
	.lval(lval)
);
initial                                                
begin                                                  
clk=0;
lval_cnt=0;
lval=0;
data_in=0;
flag=0;
#10000 $stop;                                            
                       
end                                                    
always                                                               
begin                                                                                                      
#1 clk=~clk;                                           
end  

always@(posedge clk)
	begin
		lval_cnt <= lval_cnt + 1'b1;
		if(lval_cnt == 4'b1111)
			lval <= ~lval;
		else
			lval <= lval;
	end

wire lval_pos;
wire lval_neg;
reg [1:0] lval_reg;
always@(posedge clk)
	begin
		lval_reg[0] <= lval;
		lval_reg[1] <= lval_reg[0];
	end
assign lval_pos = lval_reg[0] &(~lval_reg[1]);
assign lval_neg = (~lval_reg[0]) &(lval_reg[1]);
	
always@(posedge clk)
	begin
		if(lval_pos == 1'b1)
			begin
				flag<= ~flag;
				data_in<=data_in+ 'h0100;
			end
		else
			begin
				flag<= flag;
				data_in<=data_in;
			end	
	end                                                   
endmodule
modelsim 仿真图




信号f就是串行输出的信号流

----------------------------------------------------------------------------verilog 源码-------------------------------------------------------------------------------------------

module decode_to_delay(
input clk,
input flag,
input [23:0] data_in,

output reg d1,
output reg d2,
output reg d3,
output reg d4,
output reg d5,
output reg d6,
output reg d7,
output reg d8,


output [23:0] data_out	

);

initial {d8,d7,d6,d5,d4,d3,d2,d1} = 8'b0000_0000;

wire flag_pos;
reg [1:0] flag_reg;
always@(posedge clk)
	begin
		flag_reg[0] <= flag;
		flag_reg[1] <= flag_reg[0];
	end
assign flag_pos = flag_reg[0] & (~flag_reg[1]);

reg [3:0] decode_to_delay;
initial decode_to_delay = 4'd0;
always@(posedge clk)
	begin
		if(flag_pos == 1'b1)
			begin
				if(decode_to_delay == 4'd8)
					decode_to_delay <= 4'd0;
				else
					decode_to_delay <= decode_to_delay + 1'b1;
			end
		else
			decode_to_delay <= decode_to_delay;
	end
	
always@(decode_to_delay)
	begin
		case(decode_to_delay)
			'd0:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0000_0001;
			'd1:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0000_0010;
			'd2:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0000_0100;
			'd3:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0000_1000;
			'd4:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0001_0000;
			'd5:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0010_0000;
			'd6:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0100_0000;
			'd7:{d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b1000_0000;
			default: {d8,d7,d6,d5,d4,d3,d2,d1} <= 8'b0000_0000;
		endcase
		
	end

assign data_out = data_in;



endmodule

module delay_pid(
input clk,
input lval,
input [23:0] data_in,
input enable,

output reg flag_out,
output reg [23:0] data_out
);


	
parameter idle = 2'b01;
parameter do_delay = 2'b10;
			 
reg [1:0] state;
reg [1:0] next_state;


wire enable_pos;
reg [1:0] enable_reg;
always@(posedge clk)
	begin
		enable_reg[0] <= enable;
		enable_reg[1] <= enable_reg[0];
	end
assign enable_pos = enable_reg[0] & (~enable_reg[1]);

wire lval_pos;
reg [1:0] lval_reg;
always@(posedge clk)
	begin
		lval_reg[0] <= lval;
		lval_reg[1] <= lval_reg[0];
	end
assign lval_pos = lval_reg[0] & (~lval_reg[1]);



reg [23:0] data_in_save;

always@(posedge clk )
	begin
		if((enable_pos == 1'b1) && (state == idle))
			data_in_save <= data_in;
		else
			data_in_save <= data_in_save;
	end

reg do_delay_falg;
reg delay_over;
reg [7:0] cnt_reg;

always@(posedge clk)
	begin
		if(do_delay_falg == 1'b1)
			begin
				if(lval_pos == 1'b1)
					begin
						cnt_reg <= cnt_reg + 1'b1;
						if(cnt_reg == (data_in_save[15:8]-1'b1))
							delay_over <= 1'b1;
						else
							delay_over <= 1'b0;
					end
				else
					begin
						cnt_reg <= cnt_reg;
					end
			end
		else
			begin
				delay_over <= 1'b0;
				cnt_reg    <= 'd0;
			end
	end
	

/*
 delay_over output
*/
always@(posedge clk)
	begin
		if(delay_over == 1'b1)
			begin
				flag_out <= 1'b1;
				data_out <= data_in_save;
			end
		else
			begin
				flag_out <= 1'b0;
				data_out <= 'd0;
			end
	end
	


always@(posedge clk)
	begin
		state <= next_state;
	end
	
always@(state,enable_pos,delay_over)
	begin
		case(state)
			idle:
				begin
					if(enable_pos == 1'b1)
						begin
							next_state <= do_delay;
							do_delay_falg <= 1'b1;
						end
					else
						begin
							do_delay_falg <= 1'b0;
							next_state <= idle;
						end
				end
			do_delay:
				begin
					if(delay_over == 1'b1)
						begin
							next_state <= idle;
							do_delay_falg <= 1'b0;
						end
					else
						begin
							do_delay_falg <= 1'b1;
							next_state <= do_delay;
						end
				end
			default: next_state <= idle;
		endcase
	end

	


endmodule

module flag_or(
input d1,
input d2,
input d3,
input d4,
input d5,
input d6,
input d7,
input d8,
input [23:0] data1,
input [23:0] data2,
input [23:0] data3,
input [23:0] data4,
input [23:0] data5,
input [23:0] data6,
input [23:0] data7,
input [23:0] data8,

output [23:0] data_out,
output flag_out_final

);


assign flag_out_final = d1 | d2 | d3 | d4 | d5 | d6 | d7 | d8;
assign data_out = data1 | data2 | data3 | data4 | data5 | data6 | data7 | data8;


endmodule

							

你可能感兴趣的:(FPGA,verilog,HDL)