/*
VME : DTB Modules Master Sim
*/
module vme_sim
(
input clk,//40mHz
input rst_n,
//--------------------------
output reg [5:0]am,
output reg as_n,
output reg ds0_n,
output reg ds1_n,
output reg lword_n,
output reg write_n,
output reg [23:1] addr,
inout [15:0] data,
//--------------------------
input dtack_n
//---------------------------
);
reg data_en;/*synthesis preserve = 1*/
reg[15:0] data_o;/*synthesis preserve = 1*/
reg [15:0] vme_data;/*synthesis preserve = 1*/
reg vme_ack;/*synthesis preserve = 1*///下降沿说明要读的数据已经完成
wire [31:0] mv_regs[3:0];/*synthesis preserve = 1*/
wire udr;/*synthesis preserve = 1*/
wire [2:0]ir;/*synthesis preserve = 1*/
//-----------------------vjtag--------------------------
m_vjtag_vme m_vjtag_vme_ins0(
.clk(clk),
.rst_n(rst_n),
.mv_regs(mv_regs),
//
.vme_data(vme_data),
.vme_ack(vme_ack),//下降沿说明要读的数据已经完成
//used for signaltap!not need to connected.
.cdr(),
.e1dr(),
.e2dr(),
.pdr(),
.sdr(),
.udr(udr),
.uir(),
.cir(),
.tck(),
.tdi(),
.ir_in(ir),
.tdo()
);
wire udr_p;
HEdgeC_PulseO #(0) HEdgeC_PulseO_Ins0(
.clk(clk),//
.rst_n(rst_n),
.IN(udr),//
.Q(udr_p),//out
.Qn()
);
reg [15:0] data_w;
reg [23:0] addr_x;
reg [1:0] wr_st;
always @ ( posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
addr_x <= 'b0;
wr_st <= 'b0;
data_w <= 'b0;
end
else if(vme_ack == 'b1)
begin
wr_st <= 'b00;
end
else if ( ir[2:0] == 3'b101)
begin
if(udr_p)
begin
data_w <= mv_regs[2][15:0];
end
end
else if ( ir[2:0] == 3'b111)
begin
if(udr_p)
begin
addr_x <= {8'ha0,mv_regs[3][15:0]};
wr_st <= mv_regs[3][31:30];
end
end
end
//-----------------------------------------
reg [7:0] wr_sm;
//
parameter rd_sm_0_idle = 8'b0000_0000,
rd_sm_1_as = 8'b0000_0001,
rd_sm_2_wre = 8'b0000_0011,
rd_sm_3_ds0 = 8'b0000_0010,
rd_sm_4_dtack = 8'b0000_0110,
rd_sm_5_ds0_ = 8'b0000_0111,
rd_sm_6_rst = 8'b0000_0101,
wr_sm_1_as = 8'b0001_0000,
wr_sm_2_wre = 8'b0011_0000,
wr_sm_3_ds0 = 8'b0010_0000,
wr_sm_4_dtack = 8'b0110_0000,
wr_sm_5_ds0_ = 8'b0111_0000,
wr_sm_6_rst = 8'b0101_0000;
//ds0 ds1 lword_n
assign data = data_en?data_o:16'hz;
always @ ( posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
vme_ack <= 'b0;
addr[23:1]<= 'd0;
//
data_en <= 'b0;
data_o <= 'hFFFF;
//
write_n <= 'b1;
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
//
as_n<= 'b1;
//
wr_sm <= 'b0;
end
else if(wr_sm == rd_sm_0_idle)
begin
vme_ack <= 'b0;
data_en <= 'b0;
write_n <= 'b1;
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
as_n <= 'b1;
wr_sm <= 'd1;
if(wr_st == 2'b01)
begin
wr_sm <= rd_sm_1_as;
end
else if(wr_st == 2'b10)
begin
wr_sm <= wr_sm_1_as;
end
else
begin
wr_sm <= rd_sm_0_idle;
end
end
else if(wr_sm == rd_sm_1_as)
begin
vme_ack <= 'b1;
addr[23:1]<=addr_x[23:1];
//
data_en <= 'b0;
write_n <= 'b1;
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
as_n <= 'b1;
wr_sm <= rd_sm_2_wre;
end
else if(wr_sm == rd_sm_2_wre)
begin
data_en <= 'b0;
write_n <= 'b1;
//
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
as_n <= 'b0;
wr_sm <= rd_sm_3_ds0;
end
else if(wr_sm == rd_sm_3_ds0)
begin
ds0_n<='b0;
ds1_n<='b0;
wr_sm <= rd_sm_4_dtack;
end
else if(wr_sm == rd_sm_4_dtack)
begin
if(dtack_n == 0)
begin
vme_data <= data;
wr_sm <= rd_sm_5_ds0_;
as_n <= 'b1;
end
else
begin
wr_sm <= rd_sm_4_dtack;
end
end
else if(wr_sm == rd_sm_5_ds0_)
begin
data_en <= 'b0;
write_n <= 'b1;
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
as_n <= 'b1;
wr_sm <= rd_sm_0_idle;
end
else if(wr_sm == wr_sm_1_as)
begin
vme_ack <= 'b1;
addr[23:1]<=addr_x[23:1];
//
data_en <= 'b0;
write_n <= 'b1;
am <=6'h39;
ds0_n<='b1;
ds1_n<='b1;
lword_n <='b1;
as_n <= 'b1;
wr_sm <= wr_sm_2_wre;
end
else if(wr_sm == wr_sm_2_wre)
begin
write_n <= 'b0;
as_n <= 'b0;
data_en <= 'b1;
data_o <= data_w;
wr_sm <= wr_sm_3_ds0;
end
else if(wr_sm == wr_sm_3_ds0)
begin
data_en <= 'b1;
write_n <= 'b0;
am <=6'h39;
ds0_n<='b0;
ds1_n<='b0;
lword_n <='b1;
as_n <= 'b0;
wr_sm <= wr_sm_4_dtack;
end
else if(wr_sm == wr_sm_4_dtack)
begin
if(dtack_n == 0)
begin
as_n <= 'b1;
wr_sm <= wr_sm_5_ds0_;
end
else
begin
wr_sm <= wr_sm_4_dtack;
end
end
else if(wr_sm == wr_sm_5_ds0_)
begin
data_en <= 'b0;
write_n <= 'b1;
ds0_n<='b1;
ds1_n<='b1;
as_n <= 'b1;
wr_sm <= rd_sm_0_idle;
end
else
begin
end
end
// always @ ( posedge clk or negedge rst_n)
// begin
// if(!rst_n)
// begin
// end
// else
// begin
// end
// end
// always @ ( posedge clk or negedge rst_n)
// begin
// if(!rst_n)
// begin
// end
// else
// begin
// end
// end
endmodule
module m_vjtag_vme (
input clk,rst_n,
output reg [31:0] mv_regs[3:0],
//
input [15:0] vme_data,
input vme_ack,//下降沿说明要读的数据已经完成
//used for signaltap!not need to connected.
output cdr, e1dr, e2dr, pdr, sdr, udr, uir, cir,tck,tdi,
output [2:0] ir_in,
output reg tdo='b0
);
//
wire vme_ack_p;
wire udr_p;
HEdgeC_PulseO #(0) HEdgeC_PulseO_MV_Ins0(
.clk(clk),//
.rst_n(rst_n),
.IN(~vme_ack),//
.Q(vme_ack_p),//out
.Qn()
);
HEdgeC_PulseO #(0) HEdgeC_PulseO_MV_Ins1(
.clk(clk),//
.rst_n(rst_n),
.IN(udr),//
.Q(udr_p),//out
.Qn()
);
reg[15:0] vme_data_buffer;
always @ ( posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
vme_data_buffer <=16'hffff;
end
else if(vme_ack_p)
begin
vme_data_buffer <= vme_data;
end
else if ( ir_in[2:0] == 3'b111)//reset
begin
if(udr_p)
begin
vme_data_buffer <=16'hffff;
end
end
else
;
end
//------------------------------------------------------vjtag part---------------------------------------------
// Signals and registers declared for VJI instance
//wire tck, tdi;/*synthesis preserve = 1*/
//reg tdo='b0;/*synthesis preserve = 1*/
//wire cdr, eldr, e2dr, pdr, sdr, udr, uir, cir;/*synthesis preserve = 1*/
//wire ir_in;/*synthesis preserve = 1*/
// Instantiation of VJI
vjtag my_vji(
.tdo (tdo),
.tck (tck),
.tdi (tdi),
.tms(),
.ir_in(ir_in),
.ir_out(),
.virtual_state_cdr (cdr),
.virtual_state_e1dr(e1dr),
.virtual_state_e2dr(e2dr),
.virtual_state_pdr (pdr),
.virtual_state_sdr (sdr),
.virtual_state_udr (udr),
.virtual_state_uir (uir),
.virtual_state_cir (cir)
);
// Deocde Logic Block
// Making some decode logic from ir_in output port of VJI
// Bypass used to maintain the scan chain continuity for
// tdi and tdo ports
reg bypass_reg='b0;
always @ (*)
bypass_reg <= tdi;
// Data Register Block
reg[31:0] m_data_t = 'd0;
//
always @ (posedge tck)
if ( sdr)
m_data_t <= {tdi, m_data_t[31:1]};
else if(cdr)
begin //read
if(ir_in[2:1] == 2'b01 )
m_data_t <= vme_data_buffer;
else
m_data_t <= mv_regs[ir_in[2:1]];//
end
else if(udr||e1dr)
begin
if(ir_in[0])//write
mv_regs[ir_in[2:1]] <= m_data_t;
end
// tdo Logic Block
always @ (*)
//if(ir_in[0])
if(sdr)
tdo <= m_data_t[0];
else
tdo <= bypass_reg;
//
endmodule
/*
FUNCTION:上升边沿检测,高/低电平有效脉冲输出模块
2019.1.11 wuhou
IN:____(0)___|----------------(1)--------------------------------|____(0)_____
{ T(delay)=N clk. }
Q:_____(0)___|------------(1)------------|____(0)____________________________________
Qn
*/
module HEdgeC_PulseO
#(parameter N=10000)//脉冲输出的clk个数,范围2^32.
(
input clk,//
input rst_n,
input IN,//
output reg Q,//out
output reg Qn
);
//
wire IN_D;
DFF DFF_inst1 (//priority: clrn > prn
.d(IN),
.clk(clk),//40MHZ,25ns
.clrn(rst_n),//同步复位
.prn(1'b1), //异步置位
.q(IN_D)
);
//
reg [31:0] PulLenCnt;
//
reg IN_R1,IN_R2;
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
IN_R1 <= 1'd0;
IN_R2 <= 1'd0;
end
else
begin
IN_R1 <= IN_D;
IN_R2 <= IN_R1;
end
end
//Q
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
Q <= 1'd0;
end
else if(IN_R1&(~IN_R2))//posedge of R singal
begin
Q <= 1'd1;
end
else if(PulLenCnt == N)
begin
Q <= 1'd0;
end
else
Q <= Q;
end
//Qn
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
Qn <= ~Q;
end
else
Qn <= ~Q;
end
//
always @(posedge clk or negedge rst_n)
begin
if(~rst_n)
begin
PulLenCnt <= 32'h00000000;
end
else if(Q == 1'b1)//posedge of R singal
begin
PulLenCnt <= PulLenCnt+ 1'b1;
end
else
PulLenCnt <= 32'h00000000;
end
//
endmodule
package require Tk
package require Ttk
# Initialize the Tk library
init_tk
# Create a top level and add a title
toplevel .top
wm title .top "VJTAG<->VME"
set w .top
#
set usb [lindex [get_hardware_names] 0]
puts $usb
set device_name [lindex [get_device_names -hardware_name $usb] 0]
puts $device_name
proc int2bits {i} {
set res ""
while {$i>0} {
set res [expr {$i%2}]$res
set i [expr {$i/2}]
}
if {$res==""} {set res 0}
return $res
}
proc hex16bits24 {value} {
set res_hex [format "0x%s" $value]
puts $res_hex
set res_d [format "%d" $res_hex]
set push_value [int2bits $res_d]
set diff [expr {24-[string length $push_value] %24}]
puts $diff
if {$diff != 24} {
set res [format "%0${diff}d${push_value}" 0]
}
puts $res
return $res
}
proc hex16bits32 {value} {
set res_hex [format "0x%s" $value]
puts $res_hex
set res_d [format "%d" $res_hex]
set push_value [int2bits $res_d]
set diff [expr {32-[string length $push_value] %32}]
puts $diff
if {$diff != 32} {
set res [format "%0${diff}d${push_value}" 0]
}
puts $res
return $res
}
proc bin32dec {value } {
puts [format "%s " $value]
set r1 [binary format B32 $value]
#puts [format "%s " $r1]
binary scan $r1 H8 r2
puts [format "%s" $r2]
set res_hex [format "0x%s" $r2]
puts $res_hex
set res_d [format "%d" $res_hex]
puts $res_d
return $res_d
}
proc bin32hex {value } {
puts [format "%s " $value]
set r1 [binary format B32 $value]
#puts [format "%s " $r1]
binary scan $r1 H8 r2
puts [format "%s" $r2]
set res_hex [format "0x%s" $r2]
return $res_hex
}
#------
#addr 注意:地址的第一位不能为0,如果为0这直接去掉否则地址不对!
proc b32_push {addr b32 } {
#
global device_name usb
#--------------------------------------------------------
open_device -device_name $device_name -hardware_name $usb
device_lock -timeout 1000
#----
device_virtual_ir_shift -instance_index 0 -ir_value $addr
-no_captured_ir_value
set result [device_virtual_dr_shift -instance_index 0 -length 32 -dr_value
$b32 ]
#-----
device_unlock
close_device
#puts "-----------"
#puts $result
return $result
}
#
proc push32 {addr value } {
#
set vt [format "%032d" $value]
puts $vt
set result [b32_push $addr $vt]
puts "push ok!"
return $result
}
#
proc vj_rd {addr } {
#
set vt2 [hex16bits24 $addr]
set vt1 [format "01000000%s" $vt2]
puts $vt1
b32_push 111 $vt1
#
set vt2 [format "%032d" 0]
puts $vt2
#注意:地址不能写010,而应该是10
set result [b32_push 10 $vt2]
puts "vj_read ok!"
#return [bin32dec $result]
return [bin32hex $result]
}
proc vj_wr {addr value } {
#
set vt1 [hex16bits32 $value]
puts $vt1
b32_push 101 $vt1
#
set vt1 [hex16bits24 $addr]
set vt2 [format "10000000%s" $vt1]
puts $vt2
set result [b32_push 111 $vt2]
#
puts "vj_wr ok!"
return $result
}
#
foreach i {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20} {
entry $w.e$i -width 32 -relief sunken -textvariable value$i
label $w.msg$i -width 32 -relief sunken -textvariable result$i
}
#
set i 0
label $w.txt$i -width 12 -text addr0x[expr $i*2]:
button $w.push$i -text push -width 10 -command {[vj_wr 0 $value0 ]}
button $w.get$i -text get -width 10 -command { set result0 [vj_rd 0] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 1
label $w.txt$i -width 12 -text addr0x[expr $i*2]:
button $w.push$i -text push -width 10 -command {[vj_wr 2 $value1 ]}
button $w.get$i -text get -width 10 -command { set result1 [vj_rd 2] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 2
label $w.txt$i -width 12 -text addr0x[expr $i*2]:
button $w.push$i -text push -width 10 -command {[vj_wr 4 $value2 ]}
button $w.get$i -text get -width 10 -command { set result2 [vj_rd 4] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 3
label $w.txt$i -width 12 -text addr0x[expr $i*2]:
button $w.push$i -text push -width 10 -command {[vj_wr 6 $value3 ]}
button $w.get$i -text get -width 10 -command { set result3 [vj_rd 6] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 4
label $w.txt$i -width 12 -text addr0x[expr $i*2]:
button $w.push$i -text push -width 10 -command {[vj_wr 8 $value4 ]}
button $w.get$i -text get -width 10 -command { set result4 [vj_rd 8] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 5
label $w.txt$i -width 12 -text addr0xa:
button $w.push$i -text push -width 10 -command {[vj_wr a $value5 ]}
button $w.get$i -text get -width 10 -command { set result5 [vj_rd a] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 6
label $w.txt$i -width 12 -text addr0xc:
button $w.push$i -text push -width 10 -command {[vj_wr c $value6 ]}
button $w.get$i -text get -width 10 -command { set result6 [vj_rd c] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 7
label $w.txt$i -width 12 -text addr0xe:
button $w.push$i -text push -width 10 -command {[vj_wr e $value7 ]}
button $w.get$i -text get -width 10 -command { set result7 [vj_rd e] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 8
label $w.txt$i -width 12 -text addr0x10:
button $w.push$i -text push -width 10 -command {[vj_wr 10 $value8 ]}
button $w.get$i -text get -width 10 -command { set result8 [vj_rd 10] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 9
label $w.txt$i -width 12 -text addr0x26:
button $w.push$i -text push -width 10 -command {[vj_wr 26 $value9 ]}
button $w.get$i -text get -width 10 -command { set result9 [vj_rd 26] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 10
label $w.txt$i -width 12 -text addr0x30:
button $w.push$i -text push -width 10 -command {[vj_wr 30 $value10 ]}
button $w.get$i -text get -width 10 -command { set result10 [vj_rd 30] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 11
label $w.txt$i -width 12 -text addr0x32:
button $w.push$i -text push -width 10 -command {[vj_wr 32 $value11 ]}
button $w.get$i -text get -width 10 -command { set result11 [vj_rd 32] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 12
label $w.txt$i -width 12 -text addr0x34:
button $w.push$i -text push -width 10 -command {[vj_wr 34 $value12 ]}
button $w.get$i -text get -width 10 -command { set result12 [vj_rd 34] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 13
label $w.txt$i -width 12 -text addr0xf0:
button $w.push$i -text push -width 10 -command {[vj_wr f0 $value13 ]}
button $w.get$i -text get -width 10 -command { set result13 [vj_rd f0] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 14
label $w.txt$i -width 12 -text addr0xf2:
button $w.push$i -text push -width 10 -command {[vj_wr f2 $value14 ]}
button $w.get$i -text get -width 10 -command { set result14 [vj_rd f2] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 15
label $w.txt$i -width 12 -text addr0xbff4:
button $w.push$i -text push -width 10 -command {[vj_wr bff4 $value15 ]}
button $w.get$i -text get -width 10 -command { set result15 [vj_rd bff4] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 16
label $w.txt$i -width 12 -text addr0xbff6:
button $w.push$i -text push -width 10 -command {[vj_wr bff6 $value16 ]}
button $w.get$i -text get -width 10 -command { set result16 [vj_rd bff6] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 17
label $w.txt$i -width 12 -text addr0xbff8:
button $w.push$i -text push -width 10 -command {[vj_wr bff8 $value17 ]}
button $w.get$i -text get -width 10 -command { set result17 [vj_rd bff8] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 18
label $w.txt$i -width 12 -text addr0xbffa:
button $w.push$i -text push -width 10 -command {[vj_wr bffa $value18 ]}
button $w.get$i -text get -width 10 -command { set result18 [vj_rd bffa] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 19
label $w.txt$i -width 12 -text addr0xbffc:
button $w.push$i -text push -width 10 -command {[vj_wr bffc $value19 ]}
button $w.get$i -text get -width 10 -command { set result19 [vj_rd bffc] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
set i 20
label $w.txt$i -width 12 -text addr0xbffe:
button $w.push$i -text push -width 10 -command {[vj_wr bffe $value20 ]}
button $w.get$i -text get -width 10 -command { set result20 [vj_rd bffe] }
bind $w <Return> {
$w.push$i flash
$w.push$i invoke
}
grid $w.txt$i $w.e$i $w.msg$i $w.push$i $w.get$i
#
tkwait window .top
cd
C:altera91quartusinquartus_stp.exe "-t" ".vjtag_vme.tcl"
pause
参考:
VME总线结构和工作原理