1
0
mirror of https://github.com/pConst/basic_verilog.git synced 2025-01-14 06:42:54 +08:00

Updated dynamic_delay to allow delays bit-wize, not just element-wize

This commit is contained in:
Konstantin Pavlov 2019-05-26 21:12:19 +03:00
parent 431d06145b
commit 3474f7b505
7 changed files with 329 additions and 25 deletions

75
dynamic_delay.sv Normal file → Executable file
View File

@ -4,55 +4,80 @@
//--------------------------------------------------------------------------------
// INFO --------------------------------------------------------------------------------
// Dynamic delay for arbitrary signal
// Dynamic delay for arbitrary signal.
//
// CAUTION: The module intentionally does NOT implement error handling when
// LENGTH is not a multiple of 2. Please handle "out of range"
// checks externally.
// Incoming data elements have WIDTH bits each. Module does serialization of
// input data and outputs flattened bits, based on provided selector value.
// You can perform delays bit-wize, not just element-wize.
//
// CAUTION: Be careful selecting last, most-delayed "WIDTH" number of bits.
// The module intentionally does NOT implement "out of range"
// checks. Please handle them externally.
/* --- INSTANTIATION TEMPLATE BEGIN ---
dynamic_delay #(
.LENGTH( 8 )
//.SEL_W( 3 )
) DD1 (
.LENGTH( 3 ),
.WIDTH( 4 )
) M (
.clk( clk ),
.nrst( 1'b1 ),
.nrst( nrst ),
.ena( 1'b1 ),
.in( ),
.sel( ),
.out( )
.in( in_data[3:0] ),
.sel( sel[3:0] ),
.out( out_data[3:0] )
);
--- INSTANTIATION TEMPLATE END ---*/
module dynamic_delay #( parameter
LENGTH = 8, // maximum delay chain width
SEL_W = $clog2(LENGTH) // output selector width
LENGTH = 63, // maximum delay chain length
WIDTH = 4, // data width
SEL_W = $clog2( (LENGTH+1)*WIDTH ) // output selector width
// plus one is for zero delay element
)(
input clk,
input nrst,
input ena,
input in,
input [SEL_W-1:0] sel, // output selector
output logic out
input [WIDTH-1:0] in, // input data
input [SEL_W-1:0] sel, // output selector
output logic [WIDTH-1:0] out // output data
);
logic [(LENGTH-1):0] data = 0;
logic [(LENGTH+1)-1:0][WIDTH-1:0] data = '0;
// packed vector includes extra bits
logic [(LENGTH+1)*WIDTH-1:0] pack_data;
assign pack_data[(LENGTH+1)*WIDTH-1:0] = data;
integer i;
always_ff @(posedge clk) begin
if (~nrst) begin
data[(LENGTH-1):0] <= 0;
out <= 0;
end else if (ena) begin
data[0] <= in;
for (i=1; i<LENGTH; i=i+1) begin
data[i] <= data[i-1];
if( ~nrst ) begin
// reset all data except zero element
for( i=1; i<(LENGTH+1); i=i+1 ) begin
data[i][WIDTH-1:0] <= '0;
end
out <= data[sel[SEL_W-1:0]];
end else if (ena) begin
for( i=1; i<(LENGTH+1); i=i+1 ) begin
data[i][WIDTH-1:0] <= data[i-1][WIDTH-1:0];
end
end
end
integer j;
always_comb begin
// zero element assignment
data[0][WIDTH-1:0] <= in[WIDTH-1:0];
// output selector, sel==0 gives non-delayed output
for( j=0; j<WIDTH; j=j+1 ) begin
out[j] <= pack_data[sel[SEL_W-1:0]+j];
end
end

48
dynamic_delay_tb/c_rand.v Executable file
View File

@ -0,0 +1,48 @@
// Copyright 2007 Altera Corporation. All rights reserved.
// Altera products are protected under numerous U.S. and foreign patents,
// maskwork rights, copyrights and other intellectual property laws.
//
// This reference design file, and your use thereof, is subject to and governed
// by the terms and conditions of the applicable Altera Reference Design
// License Agreement (either as signed by you or found at www.altera.com). By
// using this reference design file, you indicate your acceptance of such terms
// and conditions between you and Altera Corporation. In the event that you do
// not agree with such terms and conditions, you may not use the reference
// design file and please promptly destroy any copies you have made.
//
// This reference design file is being provided on an "as-is" basis and as an
// accommodation and therefore all warranties, representations or guarantees of
// any kind (whether express, implied or statutory) including, without
// limitation, warranties of merchantability, non-infringement, or fitness for
// a particular purpose, are specifically disclaimed. By making this reference
// design file available, Altera expressly does not recommend, suggest or
// require that this reference design file be used in combination with any
// other product not provided by Altera.
/////////////////////////////////////////////////////////////////////////////
// C runtime library random number generator
//
// uses 32 logic cells for DFF/ADD and 8 DSP blocks for the
// 32x18=>32 multiply
module c_rand (clk,rst,reseed,seed_val,out);
input clk,rst,reseed;
input [31:0] seed_val;
output [15:0] out;
wire [15:0] out;
reg [31:0] state;
always @(posedge clk or posedge rst) begin
if (rst) state <= 0;
else begin
if (reseed) state <= seed_val;
else begin
state <= state * 32'h343fd + 32'h269EC3;
end
end
end
assign out = (state >> 16) & 16'h7fff;
endmodule

1
dynamic_delay_tb/compile.bat Executable file
View File

@ -0,0 +1 @@
modelsim.exe -do compile.tcl

9
dynamic_delay_tb/compile.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
# compile.sh
# Konstantin Pavlov, pavlovconst@gmail.com
#
# This is a support script for launching "Modelsim compile script" on Linux
vsim -do compile.tcl

96
dynamic_delay_tb/compile.tcl Executable file
View File

@ -0,0 +1,96 @@
#------------------------------------------------------------------------------
# compile.tcl
# Konstantin Pavlov, pavlovconst@gmail.com
#------------------------------------------------------------------------------
# INFO ------------------------------------------------------------------------
# Modelsim compile script
# based on "ModelSimSE general compile script version 1.1" by Doulos
# launch the script by "vsim -do compile.tcl" command on linux
# or by "modelsim.exe -do compile.tcl" on windows
# Simply change the project settings in this section
# for each new project. There should be no need to
# modify the rest of the script.
set library_file_list {
work {dynamic_delay_tb.sv
../dynamic_delay.sv
c_rand.v
../edge_detect.sv
../delay.sv
../clk_divider.sv}
}
set vsim_params "-L altera_mf_ver -L altera_mf -L lpm_ver -L lpm"
set top_level work.dynamic_delay_tb
# Console commands:
# r = Recompile changed and dependent files
# rr = Recompile everything
# q = Quit without confirmation
# After sourcing the script from ModelSim for the
# first time use these commands to recompile.
proc r {} {uplevel #0 source compile.tcl}
proc rr {} {global last_compile_time
set last_compile_time 0
r }
proc q {} {quit -force }
#Does this installation support Tk?
set tk_ok 1
if [catch {package require Tk}] {set tk_ok 0}
# Prefer a fixed point font for the transcript
set PrefMain(font) {Courier 10 roman normal}
# Compile out of date files
set time_now [clock seconds]
if [catch {set last_compile_time}] {
set last_compile_time 0
}
foreach {library file_list} $library_file_list {
vlib $library
vmap work $library
foreach file $file_list {
if { $last_compile_time < [file mtime $file] } {
if [regexp {.vhdl?$} $file] {
vcom -93 $file
} else {
vlog $file
}
set last_compile_time 0
}
}
}
set last_compile_time $time_now
# Load the simulation
eval vsim $top_level $vsim_params
# Load saved wave patterns
do wave.do
# Run the simulation
run 100us
wave zoom range 0 100us
# How long since project began?
if {[file isfile start_time.txt] == 0} {
set f [open start_time.txt w]
puts $f "Start time was [clock seconds]"
close $f
} else {
set f [open start_time.txt r]
set line [gets $f]
close $f
regexp {\d+} $line start_time
set total_time [expr ([clock seconds]-$start_time)/60]
puts "Project time is $total_time minutes"
}

View File

@ -0,0 +1,95 @@
// testbench for dynamic_delay_tb.sv module
`timescale 1ns / 1ps
module dynamic_delay_tb();
logic clk200;
initial begin
#0 clk200 = 1'b0;
forever
#2.5 clk200 = ~clk200;
end
logic rst;
initial begin
#0 rst = 1'b0;
#10.2 rst = 1'b1;
#5 rst = 1'b0;
end
logic nrst;
assign nrst = ~rst;
logic rst_once;
initial begin
#0 rst_once = 1'b0;
#10.2 rst_once = 1'b1;
#5 rst_once = 1'b0;
end
logic nrst_once;
assign nrst_once = ~rst_once;
logic [31:0] DerivedClocks;
clk_divider #(
.WIDTH( 32 )
) cd1 (
.clk( clk200 ),
.nrst( nrst_once ),
.ena( 1'b1 ),
.out( DerivedClocks[31:0] )
);
logic [31:0] E_DerivedClocks;
edge_detect ed1[31:0] (
.clk( {32{clk200}} ),
.nrst( {32{nrst_once}} ),
.in( DerivedClocks[31:0] ),
.rising( E_DerivedClocks[31:0] ),
.falling( ),
.both( )
);
logic [15:0] RandomNumber1;
c_rand rng1 (
.clk( clk200 ),
.rst( rst_once ),
.reseed( 1'b0 ),
.seed_val( DerivedClocks[31:0] ),
.out( RandomNumber1[15:0] )
);
// Module under test ==========================================================
logic [5:0] test_data = '0;
logic [3:0] sel = '0;
always_ff @(posedge clk200) begin
if( ~nrst_once ) begin
test_data[5:0] <= '0;
sel[3:0] <= '0;
end else begin
test_data[5:0] <= test_data[5:0] + 1'b1;
if( test_data[5:0]=='1 ) begin
sel[3:0] <= sel[3:0] + 1'b1;
end
end
end
dynamic_delay #(
.LENGTH( 3 ),
.WIDTH( 4 )
) M (
.clk( clk200 ),
.nrst( nrst_once ),
.ena( 1'b1 ),
.in( test_data[3:0] ),
.sel( sel[3:0] ),
.out( )
);
endmodule

30
dynamic_delay_tb/wave.do Executable file
View File

@ -0,0 +1,30 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -noupdate /dynamic_delay_tb/M/LENGTH
add wave -noupdate /dynamic_delay_tb/M/WIDTH
add wave -noupdate /dynamic_delay_tb/M/SEL_W
add wave -noupdate /dynamic_delay_tb/M/clk
add wave -noupdate /dynamic_delay_tb/M/nrst
add wave -noupdate /dynamic_delay_tb/M/ena
add wave -noupdate -radix hexadecimal -childformat {{{/dynamic_delay_tb/M/in[3]} -radix hexadecimal} {{/dynamic_delay_tb/M/in[2]} -radix hexadecimal} {{/dynamic_delay_tb/M/in[1]} -radix hexadecimal} {{/dynamic_delay_tb/M/in[0]} -radix hexadecimal}} -expand -subitemconfig {{/dynamic_delay_tb/M/in[3]} {-radix hexadecimal} {/dynamic_delay_tb/M/in[2]} {-radix hexadecimal} {/dynamic_delay_tb/M/in[1]} {-radix hexadecimal} {/dynamic_delay_tb/M/in[0]} {-radix hexadecimal}} /dynamic_delay_tb/M/in
add wave -noupdate -radix hexadecimal /dynamic_delay_tb/M/sel
add wave -noupdate -radix hexadecimal -childformat {{{/dynamic_delay_tb/M/out[3]} -radix hexadecimal} {{/dynamic_delay_tb/M/out[2]} -radix hexadecimal} {{/dynamic_delay_tb/M/out[1]} -radix hexadecimal} {{/dynamic_delay_tb/M/out[0]} -radix hexadecimal}} -subitemconfig {{/dynamic_delay_tb/M/out[3]} {-radix hexadecimal} {/dynamic_delay_tb/M/out[2]} {-radix hexadecimal} {/dynamic_delay_tb/M/out[1]} {-radix hexadecimal} {/dynamic_delay_tb/M/out[0]} {-radix hexadecimal}} /dynamic_delay_tb/M/out
add wave -noupdate -radix hexadecimal /dynamic_delay_tb/M/data
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {1330926 ps} 0}
quietly wave cursor active 1
configure wave -namecolwidth 209
configure wave -valuecolwidth 100
configure wave -justifyvalue right
configure wave -signalnamewidth 0
configure wave -snapdistance 10
configure wave -datasetprefix 0
configure wave -rowmargin 4
configure wave -childrowmargin 2
configure wave -gridoffset 0
configure wave -gridperiod 1
configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {3620021 ps} {5306117 ps}