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:
parent
431d06145b
commit
3474f7b505
75
dynamic_delay.sv
Normal file → Executable file
75
dynamic_delay.sv
Normal file → Executable 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
48
dynamic_delay_tb/c_rand.v
Executable 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
1
dynamic_delay_tb/compile.bat
Executable file
@ -0,0 +1 @@
|
||||
modelsim.exe -do compile.tcl
|
9
dynamic_delay_tb/compile.sh
Executable file
9
dynamic_delay_tb/compile.sh
Executable 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
96
dynamic_delay_tb/compile.tcl
Executable 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"
|
||||
}
|
||||
|
95
dynamic_delay_tb/dynamic_delay_tb.sv
Executable file
95
dynamic_delay_tb/dynamic_delay_tb.sv
Executable 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
30
dynamic_delay_tb/wave.do
Executable 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}
|
Loading…
x
Reference in New Issue
Block a user