Commit 393b47b8 authored by Andrea Boccardi's avatar Andrea Boccardi

Updated the simulation and added some Verilog models

parent e10d9b2b
Change the custom interface of the VMEInterface for a wishbone one
Si57x:
model
interface
AD9516 (PLL):
model
AD5666 (DAC):
model
AD9910 (DDS):
model
interface
AD7888 (ADC):
model
MT41J128M16 (DDR):
model
interface <= Xilinx with wishbone by Mathieu
CY7C1470 (SRAM):
model <= from Cypress but probably with excessive reolution (10ps)
interface
M25P128 (E2PROM):
model <= from numonix, but to be reworked
interface <= SPI one is enough?
DS18B20U+ (Temp + UniqueID):
model
Interface <= 1-wire from KK?
Xilinx-MGT
Xilinx-IOSerializer
module AddressDecoderWBApp(
input [20:0] Adr_ib21,
input Stb_i,
output reg [31:0] Dat_ob32,
output Ack_o,
input [31:0] DatDebugRegs_ib32,
input AckDebugRegs_i,
output reg StbDebugRegs_o);
assign Ack_o = AckDebugRegs_i;
always @* begin
StbDebugRegs_o = 1'b0;
Dat_ob32 = 32'h0;
if (Adr_ib21[20:2]=='h0) begin // FROM 0_0000 TO 0_0003 (WB) == FROM 80_0000 TO 80_000C (VME) <- 4 regs (16B)
StbDebugRegs_o = Stb_i;
Dat_ob32 =DatDebugRegs_ib32;
end
end
endmodule
module AddressDecoderWBSys(
input [21:0] Adr_ib22,
input Stb_i,
output reg [31:0] Dat_ob32,
output Ack_o,
input [31:0] DatIntManager_ib32,
input AckIntMAnager_i,
output reg StbIntManager_o,
input [31:0] DatDebugRegs_ib32,
input AckDebugRegs_i,
output reg StbDebugRegs_o,
input [31:0] DatSlv2SerWB_ib32,
input AckSlv2SerWB_i,
output reg StbSlv2SerWB_o,
input [31:0] DatSpiMaster_ib32,
input AckSpiMaster_i,
output reg StbSpiMaster_o
);
assign Ack_o = AckIntMAnager_i || AckDebugRegs_i || AckSlv2SerWB_i || AckSpiMaster_i;
always @* begin
Dat_ob32 = 32'h0;
StbIntManager_o = 1'b0;
StbDebugRegs_o = 1'b0;
StbSlv2SerWB_o = 1'b0;
StbSpiMaster_o = 1'b0;
if (Adr_ib22[21:2]==20'h0) begin // FROM 00_0000 TO 00_0003 (WB) == FROM 00_0000 TO 00_000C (VME) <- 4 regs (16B)
StbIntManager_o = Stb_i;
Dat_ob32 = DatIntManager_ib32;
end else if (Adr_ib22[21:2]==20'h1) begin // FROM 00_0004 TO 00_0007 (WB) == FROM 00_0010 TO 00_001C (VME) <- 4 regs (16B)
StbDebugRegs_o = Stb_i;
Dat_ob32 = DatDebugRegs_ib32;
end else if (Adr_ib22[21:3]==19'h1) begin // FROM 00_0008 TO 00_000F (WB) == FROM 00_0020 TO 00_003C (VME) <- 8 regs (32B)
StbSpiMaster_o = Stb_i;
Dat_ob32 = DatSpiMaster_ib32;
end else if (Adr_ib22[21]==1'b1) begin // FROM 20_0000 TO 3F_FFFF (WB) == FROM 80_0000 TO FF_FFFC (VME) <- 2M regs (8MB)
StbSlv2SerWB_o = Stb_i;
Dat_ob32 = DatSlv2SerWB_ib32;
end
end
endmodule
`timescale 1ns/1ns
module ApplicationFpga(
input SysAppClk_i,
inout [2:1] SysAppSlow_iob2,
inout [7:0] AFpgaProgD_iob8,
inout AFpgaProgClk_io,
inout [1:0] AFpgaProgM_iob2,
inout AFpgaProgCsi_io,
inout AFpgaProgRdWr_io,
inout AFpgaProgInit_io,
inout [4:1] FpGpIo_iob4,
input PushButton_ion);
`define dly #1
//#####################################
// Clock
//#####################################
wire Clk_k = SysAppClk_i;
//#####################################
// Reset Signal Generation
//#####################################
wire DeboucedPushButton_q;
Debouncer #(.g_CounterWidth(16), .g_SynchDepth(3)) i_Debouncer (
.Clk_ik(Clk_k),
.BouncingSignal_ia(PushButton_ion),
.DebouncedSignal_oq(DeboucedPushButton_q));
reg Rst_rq;
always @(posedge Clk_k) Rst_rq <= `dly ~DeboucedPushButton_q || RstWB;
//#####################################
// Front Panel Signals
//#####################################
assign FpGpIo_iob4[4] = Clk_k;
assign FpGpIo_iob4[3] = FpGpIo_iob4[1];
assign FpGpIo_iob4[2] = Clk_k;
//#####################################
// WishBone Serial Interface
//#####################################
wire [20:0] Adr_b21;
wire Cyc, We, StbMaster, AckMaster;
wire [31:0] DatMasterO_b32, DatMasterI_b32;
Ser2MstWB i_Ser2MstWB(
.Rst_orq(RstWB),
.Clk_ik(Clk_k),
.Cyc_o(Cyc),
.We_o(We),
.Adr_ob21(Adr_b21),
.Dat_ob32(DatMasterO_b32),
.Stb_o(StbMaster),
.Dat_ib32(DatMasterI_b32),
.Ack_i(AckMaster),
.SerClk_ik(SysAppClk_i),
.SerDat_i(SysAppSlow_iob2[1]),
.SerCntrl_i(SysAppSlow_iob2[2]),
.Stb_i(AFpgaProgD_iob8[7]),
.SerClk_ok(AFpgaProgD_iob8[6]),
.SerDat_o(AFpgaProgD_iob8[5]),
.Ack_o(AFpgaProgD_iob8[4]));
AddressDecoderWBApp i_AddressDecoderWB(
.Adr_ib21(Adr_b21),
.Stb_i(StbMaster),
.Dat_ob32(DatMasterI_b32),
.Ack_o(AckMaster),
.DatDebugRegs_ib32(DatDebugRegsrO_b32),
.AckDebugRegs_i(AckDebugRegs),
.StbDebugRegs_o(StbDebugRegs));
//#####################################
// Debug Registers
//#####################################
wire [31:0] DebugReg0, DebugReg1, DebugReg2, DebugReg3;
wire [31:0] DatDebugRegsrO_b32;
wire StbDebugRegs, AckDebugRegs;
Generic4RegsWB i_DebugRegs(
.Rst_irq(Rst_rq),
.Clk_ik(Clk_k),
.Cyc_i(Cyc),
.Stb_i(StbDebugRegs),
.We_i(We),
.Adr_ib2(Adr_b21[1:0]),
.Dat_ib32(DatMasterO_b32),
.Dat_oab32(DatDebugRegsrO_b32),
.Ack_oa(AckDebugRegs),
.Reg0Value_ob32(DebugReg0),
.Reg1Value_ob32(DebugReg1),
.Reg2Value_ob32(DebugReg2),
.Reg3Value_ob32(DebugReg3));
endmodule
module Generic4RegsWB (
input Rst_irq,
input Clk_ik,
input Cyc_i,
input Stb_i,
input We_i,
input [1:0] Adr_ib2,
input [31:0] Dat_ib32,
output reg [31:0] Dat_oab32,
output Ack_oa,
output reg [31:0] Reg0Value_ob32,
output reg [31:0] Reg1Value_ob32,
output reg [31:0] Reg2Value_ob32,
output reg [31:0] Reg3Value_ob32);
always @(posedge Clk_ik)
if (Rst_irq) Reg0Value_ob32 <= #1 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==2'b00) Reg0Value_ob32 <= #1 Dat_ib32;
always @(posedge Clk_ik)
if (Rst_irq) Reg1Value_ob32 <= #1 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==2'b01) Reg1Value_ob32 <= #1 Dat_ib32;
always @(posedge Clk_ik)
if (Rst_irq) Reg2Value_ob32 <= #1 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==2'b10) Reg2Value_ob32 <= #1 Dat_ib32;
always @(posedge Clk_ik)
if (Rst_irq) Reg3Value_ob32 <= #1 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==(2'b11)) Reg3Value_ob32 <= #1 Dat_ib32;
assign Ack_oa = Stb_i&&Cyc_i;
always @* case (Adr_ib2)
2'b00: Dat_oab32 = Reg0Value_ob32;
2'b01: Dat_oab32 = Reg1Value_ob32;
2'b10: Dat_oab32 = Reg2Value_ob32;
2'b11: Dat_oab32 = Reg3Value_ob32;
default: Dat_oab32 = Reg0Value_ob32;
endcase
endmodule
`timescale 1 ns/ 1 ns
module InterruptManagerWB (
input int_enable,
input Rst_irq,
input Clk_ik,
input Cyc_i,
input Stb_i,
input We_i,
input [1:0] Adr_ib2,
input [31:0] Dat_ib32,
output reg [31:0] Dat_oab32,
output Ack_oa,
input [7:0] interrupt_in,
output reg osc_clk,
input int_acknowledged,
input clear_all,
output assert_interrupt);
parameter dly = 1;
parameter int_reg_addr = 2'b00;
parameter mask_reg_addr = 2'b01;
parameter fpga_status_reg_addr = 2'b10;
parameter new_int_mode_addr = 2'b11;
reg [7:0] mask_reg, int_masked_old; //if a 1 is in position i than the i_th interrupt is masked
wire [7:0] int_masked, interrupt;
reg [2:0] int_pointer_r, int_pointer_w;
wire clear_int;
reg [7:0] int_fifo [7:0];
reg fifo_full, fifo_empty;
wire asynch_clk_change;
reg hs_int_mode;
wire int_in_fifo;
reg rora_roak;
reg ready4int;
reg [3:0] int_counter;
reg Stb_d;
always @(posedge Clk_ik)
if (Rst_irq) Stb_d <= # dly 1'b0;
else Stb_d <= # dly Stb_i;
wire NewStb_a = Stb_i && ~Stb_d;
assign clear_int = Cyc_i && ~We_i && NewStb_a && Adr_ib2==int_reg_addr;
always @(posedge Clk_ik) begin
if (Rst_irq) begin
{hs_int_mode, ready4int, rora_roak, mask_reg} <= # dly 11'h2ff;
end else if (Cyc_i && We_i && Stb_i && Adr_ib2==mask_reg_addr) begin
{hs_int_mode, ready4int, rora_roak, mask_reg} <= # dly Dat_ib32[10:0];
end else if (hs_int_mode && ((rora_roak && Cyc_i && ~We_i && Stb_i && Adr_ib2==int_reg_addr) || (~rora_roak && int_acknowledged))) begin
ready4int <= # dly 1'b0;
end
end
assign asynch_clk_change = clrn && ~interrupt_in[6];
initial osc_clk = 1;
always @(posedge Clk_ik or negedge asynch_clk_change) begin
if (~asynch_clk_change) begin
osc_clk <= # dly 1'b1;
end else if (Cyc_i && We_i && Stb_i && Adr_ib2==mask_reg_addr) begin
osc_clk <= # dly Dat_ib32[31];
end
end
assign int_masked = interrupt_in & ~mask_reg;
always @(posedge Clk_ik) begin
if (Rst_irq) begin
int_masked_old <= # dly 8'hff;
end else if (~int_enable) begin
int_masked_old <= # dly 8'hff;
end else begin
int_masked_old <= # dly int_masked;
end
end
assign interrupt = int_masked & ~int_masked_old;
assign new_interrupt = |interrupt;
always @(posedge Clk_ik) begin
if (Rst_irq) begin
int_counter <= # dly 4'h0;
end else if (~int_enable || clear_all) begin
int_counter <= # dly 4'h0;
end else begin
if (new_interrupt && ~fifo_full && ~int_acknowledged && ~&int_counter) begin
int_counter <= # dly int_counter + 1'b1;
end else if (int_acknowledged && ~(new_interrupt && ~fifo_full) && |int_counter) begin
int_counter <= # dly int_counter - 1'b1;
end
end
end
always @(posedge Clk_ik) begin
if (Rst_irq) begin
int_pointer_r <= # dly 3'h0;
int_pointer_w <= # dly 3'h0;
end else if (~int_enable || clear_all) begin
int_pointer_r <= # dly 3'h0;
int_pointer_w <= # dly 3'h0;
end else begin
if (new_interrupt && ~fifo_full) begin
int_pointer_w <= # dly int_pointer_w + 1'b1;
end
if (clear_int && ~fifo_empty) begin
int_pointer_r <= # dly int_pointer_r + 1'b1;
end
end
end
always @(posedge Clk_ik) begin
if (Rst_irq) begin
fifo_full <= # dly 1'b0;
fifo_empty <= # dly 1'b1;
end else if (~int_enable || clear_all) begin
fifo_full <= # dly 1'b0;
fifo_empty <= # dly 1'b1;
end else begin
if ((int_pointer_w+1'b1)==int_pointer_r && new_interrupt && ~clear_int) begin
fifo_full <= # dly 1'b1;
end else if (int_pointer_w!=int_pointer_r) begin
fifo_full <= # dly 1'b0;
end
if ((int_pointer_r+1'b1)==int_pointer_w && clear_int && ~new_interrupt) begin
fifo_empty <= # dly 1'b1;
end else if (int_pointer_w!=int_pointer_r) begin
fifo_empty <= # dly 1'b0;
end
end
end
assign int_in_fifo = ~fifo_empty;
always @(posedge Clk_ik) begin
if (new_interrupt && ~fifo_full) begin
int_fifo[int_pointer_w] <= # dly interrupt;
end
end
assign assert_interrupt = int_enable && ready4int && ((|int_counter && ~rora_roak) || (int_in_fifo && rora_roak));
wire [7:0] fpga_version;
wire [7:0] fpga_revision;
wire [15:0] date;
assign fpga_version = 8'h00;
assign fpga_revision = 8'h01;
assign date = {8'd6, 4'd10,4'd10};
assign Ack_oa = Stb_i&&Cyc_i;
always @* case(Adr_ib2)
int_reg_addr : Dat_oab32 <= # dly fifo_empty ? 32'h0000_0000 : {24'h0, int_fifo[int_pointer_r]};
mask_reg_addr : Dat_oab32 <= # dly {osc_clk, int_enable, 2'h0, 1'b0, int_pointer_r, 1'b0, int_pointer_w, int_counter, 5'h0, hs_int_mode, ready4int, rora_roak, mask_reg};
fpga_status_reg_addr: Dat_oab32 <= # dly {date, fpga_version, fpga_revision};
default: Dat_oab32 <= # dly 32'hdead_beef;
endcase
endmodule
`timescale 1ns/1ns
module MAX5483Manager (
input Rst_irq,
input Clk_ik,
input Cyc_i,
input Stb_i,
input We_i,
input [1:0] Adr_ib2,
input [31:0] Dat_ib32,
output reg [31:0] Dat_oab32,
output Ack_oa,
output reg SPIUD_o,
output CS_oqn,
output reg SclkInc_oqk,
output reg Din_oq);
reg [31:0] MAX5483Reg_qb32;
reg [31:0] ClockDivider;
reg [31:0] SetBusyTime; //1200000 steps @ 100MHz = 12ms as requested in datasheet
reg FlagMAX5483SPI_q; //1 clok flag for SPI cycle
reg FlagMAX5483UD_q; //1 clock flag for UD cycle
reg [31:0] CounterClockStep_q; //Counter used for Clk divider setting -> gets out SlowClck_e
reg [31:0] Counter24Clock; //For SPI full cycle
reg [31:0] CounterXClock; //For UD -> x number of step defined by MAX5483Reg[17:8]
reg SlowClk_e; //is out of clock divider setting
reg CSspi_oqn, CSud_oqn; //CS for SPI and UD cycle
reg CSudD0_oqn, CSudD1_oqn, CSudD2_oqn; //CS with delays
reg DinSPI_oq, DinUD_oq; //Data when SPI and UD mode
reg [9:0] CounterUDStepClock; //will keep CSud down for x steps
reg MAX5483Busy_s;
reg [23:0] CounterBusy_q;
parameter dly = 1;
//#############################################
//Register ClockDivider == clock divider
//#############################################
always @(posedge Clk_ik or posedge Rst_irq)
if (Rst_irq) ClockDivider <= #dly 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==2'b01) ClockDivider <= #dly Dat_ib32;
//#############################################
//Register SetBusyTime == 12ms fonction of the clk
//#############################################
always @(posedge Clk_ik or posedge Rst_irq)
if (Rst_irq) SetBusyTime <= #dly 32'h0;
else if (Cyc_i && We_i && Stb_i && Adr_ib2==2'b10) SetBusyTime <= #dly Dat_ib32;
//############################################
//Reg MAX5483
//############################################
always @(posedge Clk_ik or posedge Rst_irq) begin
if (Rst_irq) MAX5483Reg_qb32 <= #dly 32'h0;
else if (Cyc_i && We_i && Stb_i && (Adr_ib2==2'b00) && Dat_ib32[24]) begin
MAX5483Reg_qb32 <= #dly Dat_ib32;
FlagMAX5483SPI_q <= #dly 1'b1;
end
else if (Cyc_i && We_i && Stb_i && (Adr_ib2==2'b00) && (Dat_ib32[24]==1'b0)) begin
MAX5483Reg_qb32 <= #dly Dat_ib32;
FlagMAX5483UD_q <= #dly 1'b1;
end
else begin
FlagMAX5483SPI_q <= #dly 1'b0;
FlagMAX5483UD_q <= #dly 1'b0;
end
end
//#############################################
//MAX5483 control pins settings SPI
//#############################################
always @(posedge Clk_ik) begin
if (MAX5483Reg_qb32[24]) SPIUD_o <= #dly 1'b1;
else SPIUD_o <= #dly 1'b0;
end
//always @(posedge Clk_ik) SclkInc_oqk <= #dly SlowClk_e;
//#############################################
//Assign Acknowledge
//#############################################
assign Ack_oa = Stb_i && Cyc_i;
//#############################################
//Read registers
//#############################################
always @* case (Adr_ib2)
2'b00: Dat_oab32 = MAX5483Reg_qb32;
2'b01: Dat_oab32 = ClockDivider;
2'b10: Dat_oab32 = SetBusyTime;
2'b11: begin Dat_oab32[0] = MAX5483Busy_s;
Dat_oab32[31:1] = 31'b0;
end
default: Dat_oab32 = 32'hDEADBEEF;
endcase
//#############################################
//Enable 'Slow' Clock generated from ClockDivider number
//#############################################
always @(posedge Clk_ik or posedge Rst_irq) begin
if ((CounterClockStep_q == ClockDivider - 1'b1) || Rst_irq) begin
SlowClk_e <= #dly 1'b1;
CounterClockStep_q <= #dly 1'b0;
end
else if (~CSspi_oqn || ~CSudD0_oqn) begin
CounterClockStep_q <= #dly CounterClockStep_q + 1'b1;
SlowClk_e <= #dly 1'b0;
end
end
//#############################################
//24 clocks cycle manager for SPI mode
//#############################################
always @(posedge Clk_ik or posedge Rst_irq) begin
if (Counter24Clock == 5'd25*ClockDivider || Rst_irq) Counter24Clock <= #dly 32'b0;
else if (|Counter24Clock || FlagMAX5483SPI_q) Counter24Clock <= #dly Counter24Clock + 1'b1;
end
always @(posedge Clk_ik or posedge Rst_irq)
if (Rst_irq) CSspi_oqn <= #dly 1'b1;
else if (MAX5483Reg_qb32[24]) CSspi_oqn <= #dly ~|Counter24Clock;
//#############################################
//X clocks cycle manager for UD mode
//#############################################
always @(posedge Clk_ik or posedge Rst_irq) begin
if (CounterXClock == (CounterUDStepClock)*ClockDivider || Rst_irq) CounterXClock <= #dly 32'b0;
else if (|CounterXClock || FlagMAX5483UD_q) CounterXClock <= #dly CounterXClock + 1'b1;
end
always @(posedge Clk_ik or posedge Rst_irq)
if (Rst_irq) CSudD0_oqn <= #dly 1'b1;
else if (MAX5483Reg_qb32[24] == 1'b0) CSudD0_oqn <= #dly ~|CounterXClock;
//#############################################
//Parallel to serial
//#############################################
reg [23:0] ParallelData;
always @(posedge Clk_ik or posedge Rst_irq) begin
if (Rst_irq) begin
ParallelData <= #dly 24'b0;
DinSPI_oq <= #dly 1'b0;
end
else if (FlagMAX5483SPI_q) ParallelData <= #dly MAX5483Reg_qb32[23:0];
else if (SlowClk_e && ~CSspi_oqn)begin
ParallelData <= #dly {ParallelData[22:0], 1'b0};
DinSPI_oq <= #dly ParallelData[23];
end
end
//#############################################
//Register MAX5483Busy_s == flag saying in use = wiper store cycle time (12ms)
//#############################################
always @(posedge Clk_ik or posedge Rst_irq)
if (CounterBusy_q == SetBusyTime || Rst_irq) CounterBusy_q <= #dly 24'b0;
else if ((MAX5483Reg_qb32[2] == 1'b1 && MAX5483Reg_qb32[3] == 1'b0) && FlagMAX5483SPI_q || |CounterBusy_q) CounterBusy_q <= #dly CounterBusy_q + 1'b1;
always @(posedge Clk_ik) MAX5483Busy_s <= #dly |CounterBusy_q;
//#############################################
//MAX5483 control pins settings
//#############################################
always @(posedge Clk_ik) begin
CounterUDStepClock <= #dly MAX5483Reg_qb32[17:8];
if (MAX5483Reg_qb32[25] == 1'b1) DinUD_oq <= #dly 1'b1; //Count up in UD mode
else if (MAX5483Reg_qb32[25] == 1'b0) DinUD_oq <= #dly 1'b0; //Count down in UD mode
end
always @(posedge Clk_ik) SclkInc_oqk <= #dly SlowClk_e;
always @(posedge Clk_ik) CSudD1_oqn <= #dly CSudD0_oqn;
always @(posedge Clk_ik) CSudD2_oqn <= #dly CSudD1_oqn;
always @* if (MAX5483Reg_qb32[26]) CSud_oqn <= ~(~CSudD0_oqn || ~CSudD2_oqn); //Store in NV in UD mode
else if (~MAX5483Reg_qb32[26]) CSud_oqn <= #dly CSudD0_oqn; //Don't store in NV in UD mode
always @(posedge Clk_ik)
if (~CSspi_oqn) Din_oq <= #dly DinSPI_oq;
else if (~CSud_oqn) Din_oq <= #dly DinUD_oq;
assign CS_oqn = ~(~CSspi_oqn || ~CSud_oqn);
endmodule
\ No newline at end of file
module Ser2MstWB (
output Rst_orq,
output Clk_ik,
output reg Cyc_o,
output reg We_o,
output reg [20:0] Adr_ob21,
output reg [31:0] Dat_ob32,
output Stb_o,
input [31:0] Dat_ib32,
input Ack_i,
input SerClk_ik,
input SerDat_i,
input SerCntrl_i, //We, Cyc and Adr Rst are serialized on this line
input Stb_i,
output SerClk_ok,
output SerDat_o,
output reg Ack_o);
`define dly #1
reg [31:0] SerDatIShReg_b32,
SerCntrlIShReg_b32;
reg [2:0] StbI_d3;
always @(posedge SerClk_ik) StbI_d3 <= `dly {StbI_d3[1:0], Stb_i};
wire NewStbI_a = StbI_d3[2:1]==2'b01;
always @(posedge SerClk_ik) SerDatIShReg_b32 <= `dly {SerDat_i, SerDatIShReg_b32[31:1]};
always @(posedge SerClk_ik) if (NewStbI_a) Dat_ob32 <= `dly SerDatIShReg_b32;
always @(posedge SerClk_ik) SerCntrlIShReg_b32 <= `dly {SerCntrl_i, SerCntrlIShReg_b32[31:1]};
always @(posedge SerClk_ik) if (NewStbI_a) Cyc_o <= `dly SerCntrlIShReg_b32[30];
always @(posedge SerClk_ik) if (NewStbI_a) We_o <= `dly SerCntrlIShReg_b32[29];
always @(posedge SerClk_ik) if (NewStbI_a) Adr_ob21 <= `dly SerCntrlIShReg_b32[20:0];
reg [2:0] Rst_xb3;
always @(posedge SerClk_ik or posedge Rst_orq)
if (Rst_orq) Rst_xb3[0] <= `dly 1'b0;
else if (NewStbI_a) Rst_xb3[0] <= `dly SerCntrlIShReg_b32[31];
always @(posedge Clk_ik) Rst_xb3[2:1] <= `dly Rst_xb3[1:0];
assign Rst_orq = Rst_xb3[2];
reg [1:0] StbI_xb2;
always @(posedge Clk_ik) begin
if (Rst_orq) StbI_xb2 <= `dly 2'b0;
else StbI_xb2 <= `dly {StbI_xb2[0], StbI_d3[1]};
end
assign Stb_o = StbI_xb2[1];
reg [30:0] AckI_d31;
always @(posedge Clk_ik)
if (Rst_orq) AckI_d31 <= `dly 'b0;
else AckI_d31 <= `dly {AckI_d31[29:0], Ack_i};
always @(posedge Clk_ik)
if (Rst_orq) Ack_o <= `dly 1'b0;
else Ack_o <= `dly AckI_d31[30] && Ack_i;
wire NewAckI_a = ~AckI_d31[1] && Ack_i;
reg [31:0] DatInShReg_b32;
always @(posedge Clk_ik)
if (NewAckI_a) DatInShReg_b32 <= `dly Dat_ib32;
else DatInShReg_b32 <= `dly {1'b0, DatInShReg_b32[31:1]};
assign SerDat_o = DatInShReg_b32[0];
assign SerClk_ok = ~Clk_ik;
endmodule
module Slv2SerWB (
input Rst_irq,
input Clk_ik,
input Cyc_i,
input We_i,
input [20:0] Adr_ib21,
input [31:0] Dat_ib32,
input Stb_i,
output reg [31:0] Dat_ob32,
output reg Ack_o,
output SerClk_ok,
output SerDat_o,
output SerCntrl_o, //We, Cyc and Adr Rst are serialized on this line
output Stb_o,
input SerClk_ik,
input SerDat_i,
input Ack_i);
`define dly #1
reg [31:0] DatOutShReg_b32 = 32'h0,
DatInShReg_b32 = 32'h0,
CntrlShReg_b32 = 32'h2;
reg [31:0] StbShReg_b32 = 32'h2;
reg StbI_d, AckI_d;
always @(posedge Clk_ik)
if (Rst_irq) begin
AckI_d <= `dly 1'b0;
StbI_d <= `dly 1'b0;
end else begin
AckI_d <= `dly Ack_i;
StbI_d <= `dly Stb_i;
end
wire NewStbI_a = Stb_i && ~StbI_d;
always @(posedge Clk_ik) begin
DatOutShReg_b32 <= `dly {1'b0, DatOutShReg_b32[31:1]};
CntrlShReg_b32 <= `dly {1'b0, CntrlShReg_b32[31:1]};
StbShReg_b32 <= `dly {1'b0, Stb_i, StbShReg_b32[30:1]};
if (Rst_irq) begin
DatOutShReg_b32 <= `dly 32'h0;
CntrlShReg_b32 <= `dly 32'h4;
StbShReg_b32 <= `dly 'h2;
end else if (NewStbI_a) begin
DatOutShReg_b32 <= `dly Dat_ib32;
CntrlShReg_b32 <= `dly {Rst_irq, Cyc_i, We_i, 8'b0, Adr_ib21}; //Rst is useless here, but is just for documentation that i keep it
end
end
assign SerDat_o = DatOutShReg_b32[0];
assign SerCntrl_o = CntrlShReg_b32[0];
assign Stb_o = StbShReg_b32[0];
assign SerClk_ok = ~Clk_ik;
reg [2:0] AckI_d3;
always @(posedge SerClk_ik)
if (Rst_irq) begin
AckI_d3 <= `dly 'b0;
end else begin
AckI_d3 <= `dly {AckI_d3[1:0], Ack_i};
end
wire NewAckI_a = AckI_d3[2:1]==2'b01;
reg [31:0] Dat_xb32;
always @(posedge SerClk_ik) DatInShReg_b32 <= `dly {SerDat_i, DatInShReg_b32[31:1]};
always @(posedge SerClk_ik) if (NewAckI_a) Dat_xb32 <= `dly DatInShReg_b32;
reg [2:0] AckI_xb3;
always @(posedge SerClk_ik) AckI_xb3[2] <= `dly Ack_i;
always @(posedge Clk_ik) AckI_xb3[1:0]<= `dly AckI_xb3[2:1];
always @(posedge Clk_ik) if (AckI_xb3[0]) Dat_ob32 <= `dly Dat_xb32;
always @(posedge Clk_ik) Ack_o <= `dly AckI_xb3[0];
endmodule
/*
* This is a SPI master for up to 32 independent slaves
* The module support the following configurations:
* - Any CPol CPha combination
* - The lenght of the reg is programmable up to 256 allowing
* the concatenation of several slaves, if the access is longer
* than 32 bits between 2 registers the communication is paused
* - MSB or LSB first
* - The speed of the clock is settable
* - It is possible to put a wait state between the falling edge
* of SS (Slave Select) and the 1st edge of SClk as requested from some
* ADC
*/
module SpiMasterWB (
input Rst_irq,
input Clk_ik,
input Cyc_i,
input Stb_i,
input We_i,
input [2:0] Adr_ib3,
input [31:0] Dat_ib32,
output reg [31:0] Dat_oab32,
output reg Ack_oa,
output reg SClk_o,
output MoSi_o,
input [31:0] MiSo_ib32,
output reg [31:0] SS_onb32);
`define c_AddrStatus 3'd0
`define c_AddrConfig1 3'd1
`define c_AddrConfig2 3'd2
`define c_AddrShiftOut 3'd3
`define c_AddrShiftIn 3'd4
reg [31:0] Config2_qb32,
ShiftOut_qb32,
ShiftIn_qb32,
a_Status_b32,
Config1_qb32;
wire a_CPol = Config1_qb32[31];
wire a_CPha = Config1_qb32[30];
wire a_Lsb1St = Config1_qb32[29];
wire [4:0] a_SpiChannel_b5 = Config1_qb32[20:16];
wire [11:0] a_RegisterLenght_b12 = Config1_qb32[11:0];
wire [15:0] a_ClkSemiPeriod_b16 = Config2_qb32[31:16];
wire [15:0] a_WaitTime_b16 = Config2_qb32[15:0];
reg [2:0] State_a,
State_q;
`define s_Idle 3'd0
`define s_WaitBefore1StEdge 3'd1
`define s_EdgeTypeOne 3'd2
`define s_EdgeTypeTwo 3'd3
`define s_TxPause 3'd4
`define s_EndOfTx 3'd5
reg [15:0] TimeCounter_cb16;
reg [11:0] TxCounter_cb12;
always @(posedge Clk_ik)
if (Rst_irq) State_q <= `s_Idle;
else State_q <= State_a;
always @* begin
State_a = State_q;
case (State_q)
`s_Idle: if (StartTx_q) State_a = `s_WaitBefore1StEdge;
`s_WaitBefore1StEdge: if (TimeCounter_cb16==a_WaitTime_b16) State_a = `s_EdgeTypeOne;
`s_EdgeTypeOne: if (TimeCounter_cb16==a_ClkSemiPeriod_b16) State_a = `s_EdgeTypeTwo;
`s_EdgeTypeTwo: if (TimeCounter_cb16==a_ClkSemiPeriod_b16)
if (TxCounter_cb12==a_RegisterLenght_b12) State_a = `s_EndOfTx;
else if (|TxCounter_cb12[4:0]) State_a = `s_EdgeTypeOne;
else State_a = `s_TxPause;
`s_TxPause: if (StartTx_q) State_a = `s_EdgeTypeOne;
`s_EndOfTx: if (TimeCounter_cb16==a_ClkSemiPeriod_b16) State_a = `s_Idle;
default: State_a = `s_Idle;
endcase
end
reg WriteAck_q, StartTx_q;
assign MoSi_o = a_Lsb1St ? ShiftOut_qb32[0] : ShiftOut_qb32[31];
always @(posedge Clk_ik) begin
WriteAck_q <= WriteAck_q && Stb_i; // Default clear condition valid for all the states
if (Rst_irq) begin
StartTx_q <= 'b0;
WriteAck_q <= 'b0;
SClk_o <= 'b0;
SS_onb32 <= 32'hFFFF_FFFF;
TimeCounter_cb16 <= 'h0;
TxCounter_cb12 <= 'h0;
Config1_qb32 <= 'h0;
Config2_qb32 <= 'h0;
ShiftOut_qb32 <= 'h0;
ShiftIn_qb32 <= 'h0;
end else case (State_q)
`s_Idle: begin
SClk_o <= a_CPol;
SS_onb32 <= 32'h_FFFF_FFFF;
TimeCounter_cb16 <= 'h0;
TxCounter_cb12 <= 'h0;
if (Cyc_i && We_i && Stb_i && Adr_ib3==`c_AddrShiftOut) begin
ShiftOut_qb32 <= Dat_ib32;
ShiftIn_qb32 <= 'h0;
WriteAck_q <= 1'b1;
StartTx_q <= 1'b1;
end else if (Cyc_i && We_i && Stb_i && Adr_ib3==`c_AddrConfig1) begin
Config1_qb32 <= Dat_ib32;
WriteAck_q <= 1'b1;
end else if (Cyc_i && We_i && Stb_i && Adr_ib3==`c_AddrConfig2) begin
Config2_qb32 <= Dat_ib32;
WriteAck_q <= 1'b1;
end
end
`s_WaitBefore1StEdge: begin
TimeCounter_cb16 <= TimeCounter_cb16 + 1'b1;
SS_onb32[a_SpiChannel_b5] <= 1'b0;
if (State_a==`s_EdgeTypeOne) TimeCounter_cb16 <= 'h0;
end
`s_EdgeTypeOne: begin
TimeCounter_cb16 <= TimeCounter_cb16 + 1'b1;
if (State_a==`s_EdgeTypeTwo) begin
TimeCounter_cb16 <= 'h0;
SClk_o <= ~SClk_o;
TxCounter_cb12 <= TxCounter_cb12 + 1'b1;
StartTx_q <= 'h0;
if (a_CPha && ~StartTx_q) ShiftOut_qb32 <= a_Lsb1St ? {ShiftOut_qb32[0], ShiftOut_qb32[31:1]} : {ShiftOut_qb32[30:0], ShiftOut_qb32[31]};
else if (~a_CPha) ShiftIn_qb32 <= a_Lsb1St ? {MiSo_ib32[a_SpiChannel_b5], ShiftIn_qb32[31:1]} : {ShiftIn_qb32[30:0], MiSo_ib32[a_SpiChannel_b5]};
end
end
`s_EdgeTypeTwo: begin
TimeCounter_cb16 <= TimeCounter_cb16 + 1'b1;
if (State_a!=`s_EdgeTypeTwo) begin
SClk_o <= ~SClk_o;
TimeCounter_cb16 <= 'h0;
if (~a_CPha)ShiftOut_qb32 <= a_Lsb1St ? {ShiftOut_qb32[0], ShiftOut_qb32[31:1]} : {ShiftOut_qb32[30:0], ShiftOut_qb32[31]};
else ShiftIn_qb32 <= a_Lsb1St ? {MiSo_ib32[a_SpiChannel_b5], ShiftIn_qb32[31:1]} : {ShiftIn_qb32[30:0], MiSo_ib32[a_SpiChannel_b5]};
end
end
`s_TxPause: begin
if (Cyc_i && We_i && Stb_i && Adr_ib3==`c_AddrShiftOut) begin
ShiftOut_qb32 <= Dat_ib32;
ShiftIn_qb32 <= 'h0;
WriteAck_q <= 1'b1;
StartTx_q <= 1'b1;
end
end
`s_EndOfTx: begin
TimeCounter_cb16 <= TimeCounter_cb16 + 1'b1;
if (State_a==`s_Idle) SS_onb32 <= 32'hFFFF_FFFF;
end
default: begin
StartTx_q <= 'b0;
WriteAck_q <= 'b0;
SClk_o <= 'b0;
SS_onb32 <= 32'hFFFF_FFFF;
TimeCounter_cb16 <= 'h0;
TxCounter_cb12 <= 'h0;
Config1_qb32 <= 'h0;
Config2_qb32 <= 'h0;
ShiftOut_qb32 <= 'h0;
ShiftIn_qb32 <= 'h0;
end
endcase
end
always @* begin
Ack_oa <= (Stb_i&&Cyc_i&&~We_i) || WriteAck_q;
case (Adr_ib3)
`c_AddrStatus: Dat_oab32 <= {12'h0, 1'b0, State_q, 4'b0, TxCounter_cb12};
`c_AddrConfig1: Dat_oab32 <= Config1_qb32;
`c_AddrConfig2: Dat_oab32 <= Config2_qb32;
`c_AddrShiftOut: Dat_oab32 <= ShiftOut_qb32;
`c_AddrShiftIn: Dat_oab32 <= ShiftIn_qb32;
default: Dat_oab32 <= 32'hDEAD_BEEF;
endcase
end
endmodule
......@@ -47,7 +47,20 @@ module SystemFpga (
output FpGpIo1OutputMode_o,
output FpGpIo2OutputMode_o,
output FpGpIo34OutputMode_o,
inout [4:1] FpGpIo_iob4
// Application FPGA Programming Pins
inout [7:0] AFpgaProgD_iob8,
inout AFpgaProgClk_io,
inout [1:0] AFpgaProgM_iob2,
inout AFpgaProgCsi_io,
inout AFpgaProgRdWr_io,
inout AFpgaProgInit_io,
// Application FPGA Clk
output SysAppClk_o,
// Application FPGA Slow Communication
inout [2:1] SysAppSlow_iob2
);
......@@ -58,25 +71,23 @@ module SystemFpga (
// FP Leds
//####################################
wire VmeAccess = RdReg || WrReg;
wire VmeAccessForLed;
wire ClearForLed;
wire ClrInverted = ~Clr_rqn;
wire RstForLed;
Monostable i_VmeAccessMonostable(
.AsynchIn_ia(VmeAccess),
.AsynchIn_ia(StbMaster),
.Clk_ik(Clk_k),
.SynchOutput_oq(VmeAccessForLed));
Monostable i_ClearMonostable(
.AsynchIn_ia(ClrInverted),
.AsynchIn_ia(Rst_rq),
.Clk_ik(Clk_k),
.SynchOutput_oq(ClearForLed));
.SynchOutput_oq(RstForLed));
assign FpLed_onb8[0] = VmeAccessForLed ? 1'b0 : 1'bz;
assign FpLed_onb8[1] = (~&VmeIrq_ob7) ? 1'b0 : 1'bz;
assign FpLed_onb8[2] = (^{VmeGa_ib5n, ~VmeGaP_in} | ~UseGa_i) ? 1'b0 : 1'bz;
assign FpLed_onb8[3] = ClearForLed ? 1'b0 : 1'bz;
assign FpLed_onb8[3] = RstForLed ? 1'b0 : 1'bz;
wire Si57xDivided = Si57xDivider_c[21];
reg [21:0] Si57xDivider_c = 'd0;
......@@ -112,11 +123,6 @@ assign FpGpIo1OutputMode_o = 1'b0;
assign FpGpIo2OutputMode_o = 1'b1;
assign FpGpIo34OutputMode_o = 1'b1;
assign FpGpIo_iob4[2] = FpGpIo_iob4[1];
assign FpGpIo_iob4[3] = Clk_k;
assign FpGpIo_iob4[4] = FpGpIo_iob4[1];
//####################################
// Clock
//####################################
......@@ -133,7 +139,7 @@ endcase
// Reset Signal Generation
//#####################################
reg Clrn_nq;
reg Rst_rq;
reg [1:0] VmeSysReset_dx;
always @(posedge Clk_k) VmeSysReset_dx <= #`dly {VmeSysReset_dx[0], VmeSysReset_in};
......@@ -145,22 +151,17 @@ Debouncer #(.g_CounterWidth(16), .g_SynchDepth(3)) i_Debouncer (
.BouncingSignal_ia(PushButton_ion),
.DebouncedSignal_oq(DeboucedPushButton_q));
wire Clr_rqn = DeboucedPushButton_q && a_VmeSysReset_nq;
always @(posedge Clk_k) Rst_rq <= #`dly ~DeboucedPushButton_q || ~a_VmeSysReset_nq;
//#####################################
// VME Interface
//#####################################
wire [31:2] InternalBusAddress_b30;
wire [31:0] InternalBusWrData_b32, InternalBusRdData_b32;
wire InternalRdBusDav;
wire IntAcknowledged;
wire AssertInterrupt;
wire VmeDtAck_n, VmeDOe;
wire [7:0] IntVector_b8;
wire RdReg, WrReg;
wire [7:1] VmeIrq_b7n;
wire [2:0] InterrupLevel = 3'd3;
assign VmeDtAck_on = 1'b0;
assign VmeDtAckOe_oe = ~VmeDtAck_n;
......@@ -173,12 +174,24 @@ assign VmeBerr_o = 1'b0;
assign VmeIrq_ob7 = ~VmeIrq_b7n;
assign VmeTdoOe_oe = 1'b0;
assign IntVector_b8[7:5] = 'b0;
assign IntVector_b8[4:0] = (^{VmeGa_ib5n, ~VmeGaP_in} | ~UseGa_i) ? ManualAddress_ib5 : ~VmeGa_ib5n;
VmeInterface i_VmeInterface(
.clk(Clk_k),
.clrn(Clr_rqn),
wire [2:0] InterrupLevel = DebugReg0[30:28];
wire [7:0] IntVector_b8 = DebugReg0[7:0];
wire [7:0] IntSource_b8 = DebugReg1[7:0];
wire StbMaster, AckMaster, Cyc, We;
wire [21:0] Adr_b22;
wire [31:0] DatMasterI_b32, DatMasterO_b32;
VmeInterfaceWB i_VmeInterface(
.rst_i(Rst_rq),
.clk_i(Clk_k),
.adr_o(Adr_b22),
.dat_o(DatMasterO_b32),
.dat_i(DatMasterI_b32),
.we_o(We),
.stb_o(StbMaster),
.ack_i(AckMaster),
.cyc_o(Cyc),
.UseGa_i(UseGa_i),
.ManualAddress_i(ManualAddress_ib5),
.vme_ga(VmeGa_ib5n),
......@@ -200,80 +213,127 @@ VmeInterface i_VmeInterface(
.vme_irqn(VmeIrq_b7n),
.intlev_reg(InterrupLevel),
.IrqVector_i(IntVector_b8),
.wr_reg(WrReg),
.rd_reg(RdReg),
.vme_addr_out(InternalBusAddress_b30),
.vme_data_out(InternalBusWrData_b32),
.dav(InternalRdBusDav),
.data_in(InternalBusRdData_b32),
.assert_interrupt(AssertInterrupt),
.clear_int(IntAcknowledged));
wire IntManagerDav;
wire [31:0] IntManagerDataOut_b32;
wire [7:0] IntSource_b8;
wire [31:0] DatIntManagerO_b32;
wire StbIntManager, AckIntMAnager;
InterruptManager i_InterruptManager(
.clk(Clk_k),
.clrn(Clr_rqn),
.int_enable({1'b1}),
.vme_cs(CsIntManager_a),
.vme_wr(WrReg),
.vme_rd(RdReg),
.vme_addr(InternalBusAddress_b30[3:2]),
.vme_data(InternalBusWrData_b32),
.vme_dout_dav(IntManagerDav),
.vme_dout(IntManagerDataOut_b32),
InterruptManagerWB i_InterruptManager(
.Clk_ik(Clk_k),
.Rst_irq(Rst_rq),
.int_enable({1'b1}),
.interrupt_in(IntSource_b8),
.int_acknowledged(IntAcknowledged),
.clear_all({1'b0}),
.assert_interrupt(AssertInterrupt));
wire CsIntManager_a;
wire CsDebugRegs_a;
CsGenerator i_CsGenerator(
.VmeAddr_ib22(InternalBusAddress_b30[23:2]),
.CsIntManager_oa(CsIntManager_a),
.CsDebugRegs_oa(CsDebugRegs_a));
VmeDoutArbiter i_VmeDoutArbiter (
.CsIntManager_i(CsIntManager_a),
.IntManagerDav_i(IntManagerDav),
.IntManagerData_ib32(IntManagerDataOut_b32),
.CsDebugRegs_i(CsDebugRegs_a),
.DebugRegsDav_i(DebugRegsDav),
.DebugRegsData_ib32(DebugRegsDataOut_b32),
.VmeDav_o(InternalRdBusDav),
.VmeData_ob32(InternalBusRdData_b32));
.Cyc_i(Cyc),
.Stb_i(StbIntManager),
.We_i(We),
.Adr_ib2(Adr_b22[1:0]),
.Dat_ib32(DatMasterO_b32),
.Dat_oab32(DatIntManagerO_b32),
.Ack_oa(AckIntMAnager),
.interrupt_in(IntSource_b8),
.int_acknowledged(IntAcknowledged),
.clear_all({1'b0}),
.assert_interrupt(AssertInterrupt));
AddressDecoderWBSys i_AddressDecoderWB(
.Adr_ib22(Adr_b22),
.Stb_i(StbMaster),
.Dat_ob32(DatMasterI_b32),
.Ack_o(AckMaster),
.DatIntManager_ib32(DatIntManagerO_b32),
.AckIntMAnager_i(AckIntMAnager),
.StbIntManager_o(StbIntManager),
.DatDebugRegs_ib32(DatDebugRegsrO_b32),
.AckDebugRegs_i(AckDebugRegs),
.StbDebugRegs_o(StbDebugRegs),
.DatSlv2SerWB_ib32(DatSlv2SerWBO_b32),
.AckSlv2SerWB_i(AckSlv2SerWB),
.StbSlv2SerWB_o(StbSlv2SerWB),
.DatSpiMaster_ib32(DatSpiMaster_b32),
.AckSpiMaster_i(AckSpiMaster),
.StbSpiMaster_o(StbSpiMaster));
//#####################################
// Debug Registers
//#####################################
wire DebugRegsDav;
wire [31:0] DebugRegsDataOut_b32;
wire [31:0] DebugReg0, DebugReg1, DebugReg2, DebugReg3;
assign IntSource_b8 = DebugReg0[7:0];
wire [31:0] DatDebugRegsrO_b32;
wire StbDebugRegs, AckDebugRegs;
Generic4Regs i_DebugRegs(
Generic4RegsWB i_DebugRegs(
.Rst_irq(Rst_rq),
.Clk_ik(Clk_k),
.Clrn_inra(Clr_rqn),
.Cs_i(CsDebugRegs_a),
.WrReg_i(WrReg),
.Address_ib2(InternalBusAddress_b30[3:2]),
.DataIn_ib32(InternalBusWrData_b32),
.RdReg_i(RdReg),
.DataOutDav_o(DebugRegsDav),
.DataOut_ob32(DebugRegsDataOut_b32),
.Cyc_i(Cyc),
.Stb_i(StbDebugRegs),
.We_i(We),
.Adr_ib2(Adr_b22[1:0]),
.Dat_ib32(DatMasterO_b32),
.Dat_oab32(DatDebugRegsrO_b32),
.Ack_oa(AckDebugRegs),
.Reg0Value_ob32(DebugReg0),
.Reg1Value_ob32(DebugReg1),
.Reg2Value_ob32(DebugReg2),
.Reg3Value_ob32(DebugReg3));
//#####################################
// WB Serial Interface To The A-FPGA
//#####################################
wire [31:0] DatSlv2SerWBO_b32;
wire StbSlv2SerWB, AckSlv2SerWB;
Slv2SerWB i_Slv2SerWB(
.Rst_irq(Rst_rq),
.Clk_ik(Clk_k),
.Cyc_i(Cyc),
.We_i(We),
.Adr_ib21(Adr_b22[20:0]),
.Dat_ib32(DatMasterO_b32),
.Stb_i(StbSlv2SerWB),
.Dat_ob32(DatSlv2SerWBO_b32),
.Ack_o(AckSlv2SerWB),
.SerClk_ok(SysAppClk_o),
.SerDat_o(SysAppSlow_iob2[1]),
.SerCntrl_o(SysAppSlow_iob2[2]),
.Stb_o(AFpgaProgD_iob8[7]),
.SerClk_ik(AFpgaProgD_iob8[6]),
.SerDat_i(AFpgaProgD_iob8[5]),
.Ack_i(AFpgaProgD_iob8[4]));
//#####################################
// SPI master
//#####################################
wire [31:0] SpiSS_b32, SpiMiSo_b32;
wire SpiMoSi, SpiSClk_k;
wire StbSpiMaster, AckSpiMaster;
wire [31:0] DatSpiMaster_b32;
assign SpiMiSo_b32[31] = SpiMoSi;
SpiMasterWB i_SpiMasterWB(
.Rst_irq(Rst_rq),
.Clk_ik(Clk_k),
.Cyc_i(Cyc),
.We_i(We),
.Adr_ib3(Adr_b22[2:0]),
.Dat_ib32(DatMasterO_b32),
.Stb_i(StbSpiMaster),
.Dat_oab32(DatSpiMaster_b32),
.Ack_oa(AckSpiMaster),
.SClk_o(SpiSClk_k),
.MoSi_o(SpiMoSi),
.MiSo_ib32(SpiMiSo_b32),
.SS_onb32(SpiSS_b32));
endmodule
`timescale 1ns/1ns
module VmeInterfaceWB(
input rst_i,
input clk_i,
output [21:0] adr_o,
output [31:0] dat_o,
input [31:0] dat_i,
output we_o,
output stb_o,
input ack_i,
output cyc_o,
input UseGa_i,
input [4:0] ManualAddress_i,
input [4:0] vme_ga,
input vme_gap,
input vme_as,
input vme_ds1,
input vme_ds2,
input [5:0] vme_am,
input vme_wr,
output reg vme_dtack,
input vme_lword,
input [31:1] vme_addr,
inout [31:0] vme_data,
output reg VmeDOe_o,
output reg VmeDDirFpgaToVme_o,
input vme_iackinn,
input vme_iackn,
output reg vme_iack_outn,
output reg [7:1] vme_irqn,
input [2:0] intlev_reg,
input [7:0] IrqVector_i,
input assert_interrupt,
output reg clear_int);
parameter dly = 1;
reg [21:0] adr_o;
reg [31:0] dat_o;
reg we_o;
reg stb_o;
reg cyc_o;
reg oe_vme_data;
reg [1:0] ds1_shr, ds2_shr;
reg [1:0] as_shr;
wire as_int, pre_as_int, ds_int;
wire [4:0] base_addr;
wire gap_error;
wire selected;
reg dav_reg;
reg [31:0] data_in_reg;
wire valid_am;
reg [2:0] state;
parameter s_idle = 3'h0;
parameter s_read = 3'h1;
parameter s_write = 3'h2;
parameter s_ack_int = 3'h3;
assign gap_error = ^{vme_ga, ~vme_gap};
assign base_addr = (gap_error | ~UseGa_i) ? ManualAddress_i : ~vme_ga;
assign valid_am = (vme_am==6'h0F) || (vme_am==6'h0D) || (vme_am==6'h0B) || (vme_am==6'h09);
reg [7:0] VmeBaseAddr;
always @(posedge clk_i)
if (rst_i) VmeBaseAddr <= # dly 'h0;
else if (as_int && ~pre_as_int) VmeBaseAddr <= # dly vme_addr[31:24];
assign selected = vme_iackn && ~as_int && ~ds_int && ~vme_lword && valid_am && (VmeBaseAddr=={3'b0, base_addr});
//******************************
//ADD OF A DEFAULT REPLAY IN CASE OF MISSING ANSWER FROM THE EXTERNAL MODULES
//******************************
reg [8:0] AckTimeout_c;
reg ack_d, stb_d;
reg [31:0] DataReg;
always @(posedge clk_i) ack_d <= # dly rst_i ? 1'b0 : ack_i;
always @(posedge clk_i) stb_d <= # dly rst_i ? 1'b0 : stb_o;
wire NewAck_a = ack_i && ~ack_d;
wire NewStb_i = stb_o && ~stb_d;
always @(posedge clk_i) begin
if (rst_i) begin
AckTimeout_c <= # dly 'h0;
end else begin
if (NewAck_a) begin
AckTimeout_c <= # dly 'h0;
end else if (NewStb_i) begin
AckTimeout_c <= # dly 'h1;
end else if (|AckTimeout_c) begin
AckTimeout_c <= # dly AckTimeout_c + 1'b1;
end
end
end
always @(posedge clk_i) if (NewAck_a || &AckTimeout_c) DataReg <= # dly &AckTimeout_c ? 32'hdead_beef : dat_i;
//******************************
reg SendIrqVector;
assign vme_data = oe_vme_data ? (SendIrqVector ? {24'h0, IrqVector_i} : DataReg) : 32'hz;
assign pre_as_int = as_shr[0];
assign as_int = as_shr[1];
assign ds_int = ds1_shr[1] && ds2_shr[1];
always @(posedge clk_i) begin
as_shr <= # dly {as_shr[0], vme_as};
ds1_shr <= # dly {ds1_shr[0], vme_ds1};
ds2_shr <= # dly {ds2_shr[0], vme_ds2};
end
always @(posedge clk_i) begin
if (rst_i) begin
vme_irqn <= # dly 7'h7f;
end else begin
vme_irqn <= # dly 7'h7f;
if (assert_interrupt) begin
vme_irqn[intlev_reg] <= # dly 1'b0;
end
end
end
always @(posedge clk_i) begin
if (rst_i) begin
state <= # dly s_idle;
oe_vme_data <= # dly 1'b0;
vme_dtack <= # dly 1'b1;
vme_iack_outn <= # dly 1'b1;
clear_int <= # dly 1'b0;
VmeDOe_o <= # dly 1'b0;
VmeDDirFpgaToVme_o <= # dly 1'b1;
SendIrqVector <= # dly 1'b0;
adr_o <= # dly 22'h0;
dat_o <= # dly 32'h0;
we_o <= # dly 1'b0;
stb_o <= # dly 1'b0;
cyc_o <= # dly 1'b0;
end else case (state)
s_idle: begin
state <= # dly s_idle;
dat_o <= # dly 32'h0;
we_o <= # dly 1'b0;
stb_o <= # dly 1'b0;
cyc_o <= # dly 1'b0;
oe_vme_data <= # dly 1'b0;
VmeDOe_o <= # dly 1'b0;
VmeDDirFpgaToVme_o <= # dly 1'b1;
vme_dtack <= # dly 1'b1;
vme_iack_outn <= # dly 1'b1;
clear_int <= # dly 1'b0;
SendIrqVector <= # dly 1'b0;
if (as_int && ~pre_as_int) begin
adr_o <= # dly vme_addr[23:2];
end
if (selected && ~ack_i) begin
VmeDOe_o <= # dly 1'b1;
if (vme_wr) begin
state <= # dly s_read;
stb_o <= # dly 1'b1;
cyc_o <= # dly 1'b1;
end else begin
state <= # dly s_write;
VmeDDirFpgaToVme_o <= # dly 1'b0;
we_o <= # dly 1'b1;
cyc_o <= # dly 1'b1;
end
end else if (~vme_iackinn) begin
if (~as_int && vme_addr[3:1]==intlev_reg && ~&vme_irqn && ~ds1_shr[1]) begin
state <= # dly s_ack_int;
clear_int <= # dly 1'b1;
SendIrqVector <= # dly 1'b1;
oe_vme_data <= # dly 1'b1;
VmeDOe_o <= # dly 1'b1;
end else if (~as_int) begin
vme_iack_outn <= # dly 1'b0;
end
end
end
s_read: begin
oe_vme_data <= # dly 1'b1;
if (ack_i || &AckTimeout_c) begin
vme_dtack <= # dly 1'b0;
stb_o <= # dly 1'b0;
cyc_o <= # dly 1'b0;
end
if (~selected) begin
state <= # dly s_idle;
VmeDOe_o <= # dly 1'b0;
oe_vme_data <= # dly 1'b0;
adr_o <= # dly adr_o + 1'b1;
end
end
s_write: begin
if (~selected) begin
VmeDOe_o <= # dly 1'b0;
VmeDDirFpgaToVme_o <= # dly 1'b1;
state <= # dly s_idle;
adr_o <= # dly adr_o + 1'b1;
end
if (ack_i || &AckTimeout_c) begin
cyc_o <= # dly 1'b0;
we_o <= # dly 1'b0;
stb_o <= # dly 1'b0;
vme_dtack <= # dly 1'b0;
end else if (vme_dtack) begin
stb_o <= # dly 1'b1;
dat_o <= # dly vme_data;
end
end
s_ack_int: begin
clear_int <= # dly 1'b0;
SendIrqVector <= # dly 1'b1;
if (ds1_shr[1] && vme_iackinn) begin
state <= # dly s_idle;
vme_dtack <= # dly 1'b1;
VmeDOe_o <= # dly 1'b0;
end else begin
vme_dtack <= # dly clear_int; //need to delay 1 clock cycle
end
end
default: begin
state <= # dly s_idle;
end
endcase
end
endmodule
......@@ -343,6 +343,14 @@ wire [1:0] a_Switch_b2 = i_Sw1_b8[8:7];
wire a_UseGa = i_Sw1_b8[6];
wire [4:0] a_NoGa_b5 = i_Sw1_b8[5:1];
wire SysAppClk;
wire [2:1] SysAppSlow_b2;
wire [7:0] AFpgaProgD_b8;
wire AFpgaProgClk;
wire [1:0] AFpgaProgM_b2;
wire AFpgaProgCsi, AFpgaProgRdWr, AFpgaProgInit;
wire Si57x_k;
assign Si57x_k = Si57xClk_kp;
......@@ -392,7 +400,38 @@ SystemFpga i_SystemFpga(
.FpGpIo1OutputMode_o(FpGpIo1OutputMode),
.FpGpIo2OutputMode_o(FpGpIo2OutputMode),
.FpGpIo34OutputMode_o(FpGpIo34OutputMode),
.FpGpIo_iob4(FpGpIo_b4)
.SysAppClk_o(SysAppClk),
.SysAppSlow_iob2(SysAppSlow_b2),
.AFpgaProgD_iob8(AFpgaProgD_b8),
.AFpgaProgClk_io(AFpgaProgClk),
.AFpgaProgM_iob2(AFpgaProgM_b2),
.AFpgaProgCsi_io(AFpgaProgCsi),
.AFpgaProgRdWr_io(AFpgaProgRdWr),
.AFpgaProgInit_io(AFpgaProgInit)
);
//##############################################################
// APPLICATIO FPGA
//##############################################################
ApplicationFpga i_ApplicationFpga(
.SysAppClk_i(SysAppClk),
.SysAppSlow_iob2(SysAppSlow_b2),
.AFpgaProgD_iob8(AFpgaProgD_b8),
.AFpgaProgClk_io(AFpgaProgClk),
.AFpgaProgM_iob2(AFpgaProgM_b2),
.AFpgaProgCsi_io(AFpgaProgCsi),
.AFpgaProgRdWr_io(AFpgaProgRdWr),
.AFpgaProgInit_io(AFpgaProgInit),
.PushButton_ion(a_PushButton_n),
.FpGpIo_iob4(FpGpIo_b4)
);
endmodule
......@@ -28,10 +28,11 @@ module VmeMaster (
inout LWord_b);
initial begin
Ds2_o = 1'b1;
Ds1_o = 1'b1;
As_o = 1'b1;
IAck_o = 1'b1;
Ds2_o = 1'b1;
Ds1_o = 1'b1;
As_o = 1'b1;
IAck_o = 1'b1;
SysReset_o = 1'b1;
end
parameter [31:0] gfd_FileOutput = 32'h8000_0001; //default is standard out
......@@ -236,7 +237,7 @@ endtask
integer fd_MyFifoIn, fd_MyFifoOut;
initial begin
fd_MyFifoIn = $fopen("../../../Test/Py2VFifo", "r");
fd_MyFifoIn = $fopen("Py2V.fifo", "r");
end
task VmePrompt;
......@@ -260,7 +261,7 @@ begin
end else if (command=="I" || command=="i") begin
// $display("Which level of interrupt(1 to 7)? 0x");
AcknowledgeInterrupt(IntLevel3, data32, command);
fd_MyFifoOut = $fopen("../../../Test/V2PyFifo", "w");
fd_MyFifoOut = $fopen("V2Py.fifo", "w");
$fwrite(fd_MyFifoOut, "%x\n", command);
$fwrite(fd_MyFifoOut, "%x\n", IntLevel3);
$fwrite(fd_MyFifoOut, "%x\n", data32);
......@@ -270,8 +271,13 @@ begin
// outcode=$fscanf(32'h8000_0000, "%d", data32);
// outcode=$fgetc(32'h8000_0000); //just to get rid of the nl
outcode=$fscanf(fd_MyFifoIn, "%d", data32);
outcode=$fgetc(fd_MyFifoIn); //just to get rid of the nl
# data32;
outcode=$fgetc(fd_MyFifoIn); //just to get rid of the nl
# data32;
end else if (command=="X" || command=="x") begin
SysReset_o = 1'b0;
#200;
SysReset_o = 1'b1;
#200;
end else if (command=="W" || command=="w") begin
// $display("At which address you want to write?");
// outcode=$fscanf(32'h8000_0000, "%h", address32);
......@@ -285,7 +291,7 @@ begin
outcode=$fgetc(fd_MyFifoIn); //just to get rid of the nl
SimpleWrite(address32, 6'h09, data32, command);
// $display("Executed with exit code %d", command);
fd_MyFifoOut = $fopen("../../../Test/V2PyFifo", "w");
fd_MyFifoOut = $fopen("V2Py.fifo", "w");
$fwrite(fd_MyFifoOut, "%x\n", command);
$fclose(fd_MyFifoOut);
end else if (command=="R" || command=="r") begin
......@@ -297,7 +303,7 @@ begin
SimpleRead(address32, 6'h09, data32, command);
// $display("Executed with exit code %d", command);
// $display("Read %x", data32);
fd_MyFifoOut = $fopen("../../../Test/V2PyFifo", "w");
fd_MyFifoOut = $fopen("V2Py.fifo", "w");
$fwrite(fd_MyFifoOut, "%x\n", command);
$fwrite(fd_MyFifoOut, "%x\n", data32);
$fclose(fd_MyFifoOut);
......@@ -307,12 +313,11 @@ end
endtask
always begin
#1000;
VmePrompt();
#1000;
end
reg [7:0] ExitCode;
/*
initial begin
SysReset_o = 1'b1;
#5;
......@@ -320,9 +325,6 @@ SysReset_o = 1'b0;
#50;
SysReset_o = 1'b1;
#200;
//SimpleWrite(32'h4000000, 6'h09, 32'hfedc_a987, ExitCode);
//#1000;
//$stop;
end
*/
endmodule
......@@ -83,7 +83,7 @@ end
assign FpGpIo_b4[0] = WaveformGeneratorOut;
VFCBoard i_VFCBoars(
VFCBoard i_VFCBoard(
.VmeIrq_ozb7(VmeIrq_b7),
.VmeD_iozb32(VmeD_b32),
.VmeSysClk_ik(VmeSysClk_k),
......
RM=rm -f
VerilogFiles=
# Components' models
VerilogFiles+= ../hdl/components/ivt3205c25mhz.v
VerilogFiles+= ../hdl/components/sn74vmeh22501.v
# Components with missing models
VerilogFiles+= ../hdl/components/blackboxes/si57x.v
# System FPGA's modules
VerilogFiles+= ../hdl/design/SystemFpga.v
VerilogFiles+= ../hdl/design/AddrDecoderWBSys.v
VerilogFiles+= ../hdl/design/Generic4RegsWB.v
VerilogFiles+= ../hdl/design/Monostable.v
VerilogFiles+= ../hdl/design/Debouncer.v
VerilogFiles+= ../hdl/design/InterruptManagerWB.v
VerilogFiles+= ../hdl/design/VmeInterfaceWB.v
VerilogFiles+= ../hdl/design/Slv2SerWB.v
VerilogFiles+= ../hdl/design/SpiMasterWB.v
# Application FPGA's modules
VerilogFiles+= ../hdl/design/ApplicationFpga.v
VerilogFiles+= ../hdl/design/Ser2MstWB.v
VerilogFiles+= ../hdl/design/AddrDecoderWBApp.v
# Board schematic
VerilogFiles+= ../hdl/schematic/VFCBoard.v
# Simulation modules
VerilogFiles+= ../hdl/testbench/VmeMaster.v
VerilogFiles+= ../hdl/testbench/tb_VFC.v
PythonFiles=
PythonFiles+= ../software/mysim.py
PythonFiles+= ../software/VmeFunctions.py
PythonFiles+= ../software/SimulationFunctions.py
PythonFiles+= ../software/VmeDriver.py
all: simplesim.o Py2V.fifo V2Py.fifo
./simplesim.o
sim: comp Py2V.fifo V2Py.fifo
@(cd ../software ; python mysim.py)
comp: simplesim.o
gtk: simout.vcd
gtkwave simout.vcd
clean:
@$(RM) simplesim.o
@$(RM) Py2V.fifo
@$(RM) V2Py.fifo
@$(RM) simout.vcd
simplesim.o: $(VerilogFiles)
@iverilog -o simplesim.o -s tb_VFC $(VerilogFiles)
%.fifo:
@mkfifo $@
simout.vcd: simplesim.o $(PythonFiles)
@(cd ../software ; python mysim.py)
mv simplesim.o simplesim.o.bkp
iverilog -stb_VFC -fmodulist -osimplesim.o
./simplesim.o >& /dev/null &
(cd ../software/src; python vmet.py)
#gtkwave simout.vcd >& /dev/null &
# Components' models
../hdl/components/ivt3205c25mhz.v
../hdl/components/sn74vmeh22501.v
# Components with missing models
../hdl/components/blackboxes/si57x.v
# System FPGA's modules
../hdl/design/SystemFpga.v
../hdl/design/CsGenerator.v
../hdl/design/Generic4Regs.v
../hdl/design/Monostable.v
../hdl/design/VmeDoutArbiter.v
../hdl/design/Debouncer.v
../hdl/design/InterruptManager.v
../hdl/design/VmeInterface.v
# Board schematic
../hdl/schematic/VFCBoard.v
# Simulation modules
../hdl/testbench/VmeMaster.v
../hdl/testbench/tb_VFC.v
def StartDumping():
MyString = 'D\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
def StopSimulation():
MyString = 'S\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
def WaitSimulation(Time):
MyString = 'A '+str(Time)+'\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
from VmeFunctions import *
import numpy as np
class VmeRegister:
def __init__(self, Addr):
self.VmeAddr = Addr
def Write(self, Data):
ExitCode = VmeWrite(self.VmeAddr, Data)
return ExitCode
def Read(self):
Value = VmeRead(self.VmeAddr)
return Value
class VFCInstance:
def __init__(self, Slot, IntLevel, IntVector):
self.Slot = Slot
self.IntLevel = IntLevel
self.IntVector = IntVector
BoardBaseAddress = Slot*2**24
#@@@@@@@@@@@@@@@@@@@@@@
#System FPGA
#@@@@@@@@@@@@@@@@@@@@@@
#Interrupt manager block registers
self.InterruptStatus = VmeRegister(BoardBaseAddress + 0x0)
self.InterruptConfig = VmeRegister(BoardBaseAddress + 0x4)
self.ReleaseID = VmeRegister(BoardBaseAddress + 0x8)
#Debug reg block (BA=0x10)
self.DebugReg0 = VmeRegister(BoardBaseAddress + 0x10)
self.DebugReg1 = VmeRegister(BoardBaseAddress + 0x14)
self.DebugReg2 = VmeRegister(BoardBaseAddress + 0x18)
self.DebugReg3 = VmeRegister(BoardBaseAddress + 0x1C)
#SPI Master (BA=0x20)
self.SpiMasterStatus = VmeRegister(BoardBaseAddress + 0x20)
self.SpiMasterConfig1 = VmeRegister(BoardBaseAddress + 0x24)
self.SpiMasterConfig2 = VmeRegister(BoardBaseAddress + 0x28)
self.SpiMasterShiftOut = VmeRegister(BoardBaseAddress + 0x2C)
self.SpiMasterShiftIn = VmeRegister(BoardBaseAddress + 0x30)
#@@@@@@@@@@@@@@@@@@@@@@@
#Appliation FPGA
#@@@@@@@@@@@@@@@@@@@@@@@
AFPGABaseAddress = 0x800000
#Debug reg block (BA=0x0)
self.ApplDebugReg0 = VmeRegister(BoardBaseAddress + AFPGABaseAddress + 0x0)
self.ApplDebugReg1 = VmeRegister(BoardBaseAddress + AFPGABaseAddress + 0x4)
self.ApplDebugReg2 = VmeRegister(BoardBaseAddress + AFPGABaseAddress + 0x8)
self.ApplDebugReg3 = VmeRegister(BoardBaseAddress + AFPGABaseAddress + 0xC)
def EnableInterrupts(self, Mask):
self.DebugReg0.Write(self.IntLevel*0x10000000+self.IntVector)
self.InterruptConfig.Write(0x200 + Mask)
def GenerateDebugInterrupt(self, Status):
self.DebugReg1.Write(0x0)
self.DebugReg1.Write(Status)
self.DebugReg1.Write(0x0)
def WaitInterrupt(self):
IntStatus = 'X'
[IntLevel, IntVector] = VmeWaitInterrupt()
if IntLevel==self.IntLevel :
if IntVector==self.IntVector :
IntStatus = self.InterruptStatus.Read()
else : print "Wrong Vector: expecting "+ Slot+ " received "+ IntVector
else : print "Wrong IntLevel: expecting ", self.IntLevel, " received ", IntLevel
return IntStatus
def SpiAccess(self, Channel, CPol, CPha, LSB1st, Lenght, Data, HalfPeriod, WaitTime):
if Channel>=32 or Channel<0 :
print "Error: SPI Channel out of range"
elif CPol>1 or CPol<0 :
print "Error: SPI CPol can be only 0 or 1"
elif CPha>1 or CPha<0 :
print "Error: SPI CPha can be only 0 or 1"
elif LSB1st>1 or LSB1st<0 :
print "Error: SPI LSB1st can be only 0 or 1"
elif Lenght>=2**12 or Lenght<0 :
print "Error: SPI Lenght out of range"
elif HalfPeriod>=2**16 or HalfPeriod<0 :
print "Error:SPI Half period out of range"
elif WaitTime>=2**16 or WaitTime<0 :
print "Error: SPI Half period out of range"
elif Data<0 :
print "SPI data cannot be negative"
else :
SpiStatusReg = self.SpiMasterStatus.Read()
SpiState = (SpiStatusReg/2**16)&0x7
SpiFree = SpiState==4 or SpiState==0
while SpiFree==False :
SpiStatusReg = self.SpiMasterStatus.Read()
SpiState = (SpiStatusReg/2**16)&0x7
SpiFree = SpiState==4 or SpiState==0
Config1 = CPol*2**31 + CPha*2**30 + LSB1st*2**29 + Channel*2**16 + Lenght
Config2 = HalfPeriod*2**16 + WaitTime
self.SpiMasterConfig1.Write(Config1)
self.SpiMasterConfig2.Write(Config2)
Cycles=int(np.ceil(Lenght/32.0))
ReadValue = 0
if LSB1st==0 :
Data = Data*2**(32-Lenght%32)
for i in range(Cycles):
if LSB1st :
DataToSend = Data%2**32
self.SpiMasterShiftOut.Write(DataToSend)
Data = Data/2**32
else:
DataToSend = Data/2**(32*(Cycles-(i+1)))
self.SpiMasterShiftOut.Write(DataToSend)
Data = Data%2**(32*(Cycles-(i+1)))
SpiStatusReg = self.SpiMasterStatus.Read()
SpiState = (SpiStatusReg/2**16)&0x7
SpiFree = SpiState==4 or SpiState==0
while SpiFree==False :
SpiStatusReg = self.SpiMasterStatus.Read()
SpiState = (SpiStatusReg/2**16)&0x7
SpiFree = SpiState==4 or SpiState==0
PartialShift = self.SpiMasterShiftIn.Read()
if LSB1st :
if i==Cycles-1 :
PartialShift = PartialShift/2**((32-Lenght%32)%32)
ReadValue = ReadValue + PartialShift*2**(32*i)
else :
if i==Cycles-1 :
ReadValue = ReadValue*2**(Lenght%32)+PartialShift
else :
ReadValue = ReadValue*2**32+PartialShift
return ReadValue
def VmeWrite(Addr, Data):
MyString = 'W '+hex(Addr)[2:]+' '+hex(Data)[2:]+'\n'
fd_Out=open('../../../../Test/Py2VFifo', 'w')
MyString = 'W '+hex(Addr)[2:].strip('L')+' '+hex(Data)[2:].strip('L')+'\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
fd_In=open('../../../../Test/V2PyFifo', 'r')
fd_In=open('../simulation/V2Py.fifo', 'r')
Strings=fd_In.readlines()
ExitCode=int(Strings[0], 16)
if ExitCode==1 :
......@@ -14,30 +14,34 @@ def VmeWrite(Addr, Data):
print "Retry request for Write @ Addr ", hex(Addr)
def VmeRead(Addr):
MyString = 'R '+hex(Addr)[2:]+'\n'
fd_Out=open('../../../../Test/Py2VFifo', 'w')
MyString = 'R '+hex(Addr)[2:].strip('L')+'\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
fd_In=open('../../../../Test/V2PyFifo', 'r')
fd_In=open('../simulation/V2Py.fifo', 'r')
Strings =fd_In.readlines()
fd_In.close()
[ExitCode, Value] =Strings[0:2]
ExitCode = int(ExitCode, 16)
Value = int(Value, 16)
try:
Value = int(Value, 16)
except:
Value = 0
print "Read out a not a number"
if (ExitCode==1):
print "Read Action Timed Out @ Addr ", hex(Addr)
print "Read Action Timed Out @ Addr ", hex(Addr).strip('L')
elif (ExitCode==1):
print "Bus Error during Read cycle @ Addr ", hex(Addr)
print "Bus Error during Read cycle @ Addr ", hex(Addr).strip('L')
elif (ExitCode==1):
print "Retry request for Read @ Addr ", hex(Addr)
print "Retry request for Read @ Addr ", hex(Addr).strip('L')
return Value
def VmeWaitInterrupt():
MyString = 'I\n'
fd_Out=open('../../../../Test/Py2VFifo', 'w')
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
fd_In=open('../../../../Test/V2PyFifo', 'r')
fd_In=open('../simulation/V2Py.fifo', 'r')
Strings=fd_In.readlines()
fd_In.close()
[IntLevel, IntVector]=['0', '0']
......@@ -52,3 +56,11 @@ def VmeWaitInterrupt():
print "Unknown status response from Wait Interrupt : "+ Strings[0]
return [int(IntLevel, 16), int(IntVector, 16)]
def VmeReset():
MyString = 'X\n'
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(MyString)
fd_Out.close()
from VmeDriver import *
from SimulationFunctions import *
import os
#os.system('mkfifo ../simulation/Py2V.fifo')
#os.system('mkfifo ../simulation/V2Py.fifo')
os.system('(cd ../simulation ; xterm make &)')
os.system('clear')
MyBoard = VFCInstance(4, 3, 4)
StartDumping()
WaitSimulation('1000')
VmeReset()
WaitSimulation('1000')
#SIMULATIN FLOW
print "Release: ", hex(MyBoard.ReleaseID.Read())
print""
print "Enabling all the interrupts"
MyBoard.EnableInterrupts(0x0)
print "Int Config reg: ", hex(MyBoard.InterruptConfig.Read())
print""
IntSource = 0xa
print "Sending a request to generate an interrupt with Satus(Source): ", hex(IntSource)
MyBoard.GenerateDebugInterrupt(IntSource)
print "Waiting for interrupt"
Status = MyBoard.WaitInterrupt()
if Status==IntSource : print "Received the expected interrupt (status: ", hex(Status), " )"
else : print "Wrong Status: expecting ", MyBoard.IntVector, " received " , hex(Status)
print""
print""
print "Setting the Application FPGA debug register 0 to 3 to: 0xa, 0xb, 0xc, 0xd"
MyBoard.ApplDebugReg0.Write(0xa)
MyBoard.ApplDebugReg1.Write(0xb)
MyBoard.ApplDebugReg2.Write(0xc)
MyBoard.ApplDebugReg3.Write(0xd)
Value = hex(MyBoard.ApplDebugReg0.Read())
print "Application FPGA debug register 0 is: ", Value
Value = hex(MyBoard.ApplDebugReg1.Read())
print "Application FPGA debug register 1 is: ", Value
Value = hex(MyBoard.ApplDebugReg2.Read())
print "Application FPGA debug register 2 is: ", Value
Value = hex(MyBoard.ApplDebugReg3.Read())
print "Application FPGA debug register 3 is: ", Value
WaitSimulation(10000)
print""
print""
print""
print"Starting to check the SPI using the SPI feedback channell (31)"
print""
print""
print "Checking the SPI master with short accesses with all the CPol CPha combinations and MSB 1st"
print""
print "SPI access CPol=0 CPha=0 MSB1st 8bit 0xaa halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 0, 8, 0xaa, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=0 CPha=1 MSB1st 8bit 0xcc halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 1, 0, 8, 0xcc, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=1 CPha=0 MSB1st 8bit 0x55 halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 1, 0, 0, 8, 0x55, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=1 CPha=1 MSB1st 8bit 0x66 halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 1, 1, 0, 8, 0x66, 4, 12)
print "Read ", hex(Value)
WaitSimulation(10000)
print""
print""
print "Checking the SPI master with short accesses with all the CPol CPha combinations and LSB 1st"
print""
print "SPI access CPol=0 CPha=0 LSB1st 8bit 0xaa halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 1, 8, 0xaa, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=0 CPha=1 LSB1st 8bit 0xcc halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 1, 1, 8, 0xcc, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=1 CPha=0 LSB1st 8bit 0x55 halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 1, 0, 1, 8, 0x55, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=1 CPha=1 LSB1st 8bit 0x66 halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 1, 1, 1, 8, 0x66, 4, 12)
print "Read ", hex(Value)
WaitSimulation(10000)
print""
print""
print "Checking with long access both CPha (only one CPol) MSB1st"
print""
print "SPI access CPol=0 CPha=0 MSB1st 68bit 0x1111222233334444a halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 0, 68, 0x1111222233334444a, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=0 CPha=1 MSB1st 68bit 0x1111222233334444a halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 0, 68, 0x1111222233334444a, 4, 12)
print "Read ", hex(Value)
WaitSimulation(10000)
print""
print""
print "Checking with long access both CPha (only one CPol) LSB1st"
print""
print "SPI access CPol=0 CPha=0 LSB1st 68bit 0x1111222233334444a halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 1, 68, 0x1111222233334444a, 4, 12)
print "Read ", hex(Value)
print""
print "SPI access CPol=0 CPha=1 LSB1st 68bit 0x1111222233334444a halfperiod=4 wait=12"
Value = MyBoard.SpiAccess(31, 0, 0, 1, 68, 0x1111222233334444a, 4, 12)
print "Read ", hex(Value)
WaitSimulation(10000)
StopSimulation()
exit()
# VMET ACCESS
import sys
def CommandPrompt() :
sys.stdout.write('Enter a command: \n')
sys.stdout.write('1: write\n')
sys.stdout.write('2: read\n')
sys.stdout.write('3: wait an interrupt\n')
MyString ="9: change base address["+hex(BaseAddress)+"]\n"
sys.stdout.write(MyString)
sys.stdout.write('e: exit\n\n')
sys.stdout.write('> ')
Command=sys.stdin.readline().strip('\n')
os.system('clear')
return Command
def BuildAddress (BaseAddress, RequestString) :
sys.stdout.write(RequestString)
return hex(BaseAddress + int(sys.stdin.readline().strip('\n'), 16)).lstrip('0x')
def SendCommand(CommandString) :
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(CommandString)
fd_Out.close()
def ReadResult():
fd_In=open('../simulation/V2Py.fifo', 'r')
ResultString = fd_In.read()
fd_In.close()
return ResultString
Command=' '
BaseAddress=0
Command = CommandPrompt()
while (Command!='e'):
if Command=='1' :
Address =BuildAddress(BaseAddress, 'Where do you want to write? 0x')
sys.stdout.write('What do you want to write? ')
Value =sys.stdin.readline().strip('\n')
MyString = 'W '+Address+' '+Value+'\n'
SendCommand(MyString)
print ReadResult()
sys.stdin.readline()
elif Command=='2' :
Address =BuildAddress(BaseAddress,'Where do you want to read? 0x' )
MyString = 'R '+Address+'\n'
SendCommand(MyString)
print ReadResult()
sys.stdin.readline()
elif Command=='3' :
MyString = 'I \n'
SendCommand(MyString)
print ReadResult()
sys.stdin.readline()
elif Command=='9' :
sys.stdout.write('What\'s the new base address? 0x')
BaseAddress =int(sys.stdin.readline().strip('\n'), 16)
Command = CommandPrompt()
StopSimulation()
from VmeFunctions import *
class VmeRegister:
def __init__(self, Addr):
self.VmeAddr = Addr
def Write(self, Data):
ExitCode = VmeWrite(self.VmeAddr, Data)
return ExitCode
def Read(self):
Value = VmeRead(self.VmeAddr)
return Value
class VFCInstance:
IntLevel = 3
def __init__(self, Slot):
self.Slot = Slot
BoardBaseAddress = Slot*2**24
#Interrupt manager block registers
self.InterruptStatus = VmeRegister(BoardBaseAddress + 0x0)
self.InterruptConfig = VmeRegister(BoardBaseAddress + 0x4)
self.ReleaseID = VmeRegister(BoardBaseAddress + 0x8)
#Debug reg block (BA=0x10)
self.DebugReg0 = VmeRegister(BoardBaseAddress + 0x10)
self.DebugReg1 = VmeRegister(BoardBaseAddress + 0x14)
self.DebugReg2 = VmeRegister(BoardBaseAddress + 0x18)
self.DebugReg3 = VmeRegister(BoardBaseAddress + 0x1C)
def EnableInterrupts(self, Mask):
self.InterruptConfig.Write(0x200 + Mask)
def GenerateDebugInterrupt(self, Status):
self.DebugReg0.Write(0x0)
self.DebugReg0.Write(Status)
self.DebugReg0.Write(0x0)
def WaitInterrupt(self):
IntStatus = 'X'
[IntLevel, IntVector] = VmeWaitInterrupt()
if IntLevel==self.IntLevel :
if IntVector==self.Slot :
IntStatus = self.InterruptStatus.Read()
else : print "Wrong Vector: expecting "+ Slot+ " received "+ IntVector
else : print "Wrong IntLevel: expecting "+ self.IntLevel+ " received "+ IntLevel
return IntStatus
from VmeDriver import *
MyBoard = VFCInstance(4)
MyBoard.EnableInterrupts(0x0)
IntConfig = hex(MyBoard.InterruptConfig.Read())
print "Int Config reg: ", IntConfig
Release = hex(MyBoard.ReleaseID.Read())
print "Release: ", Release
MyBoard.GenerateDebugInterrupt(0x5)
Status = MyBoard.WaitInterrupt()
if Status==5 : print "Received the expected interrupt (status: ", hex(Status), " )"
else : print "Wrong Status: expecting 5" + " received " + hex(Status)
......@@ -20,12 +20,12 @@ def BuildAddress (BaseAddress, RequestString) :
return hex(BaseAddress + int(sys.stdin.readline().strip('\n'), 16)).lstrip('0x')
def SendCommand(CommandString) :
fd_Out=open('../../../../Test/Py2VFifo', 'w')
fd_Out=open('../simulation/Py2V.fifo', 'w')
fd_Out.write(CommandString)
fd_Out.close()
def ReadResult():
fd_In=open('../../../../Test/V2PyFifo', 'r')
fd_In=open('../simulation/V2Py.fifo', 'r')
ResultString = fd_In.read()
fd_In.close()
return ResultString
......@@ -34,7 +34,7 @@ def ReadResult():
Command=' '
BaseAddress=0
Command = CommandPrompt()
Command = CommandPrompt()
while (Command!='e'):
if Command=='d' :
MyString = 'D\n'
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment