Commit a4102b78 authored by Alexey Grebenkin's avatar Alexey Grebenkin

Added MAXI bus monitor, some fixes to pass PIO read test

parent e4a8fdeb
...@@ -700,6 +700,7 @@ task linkTransmitFIS; ...@@ -700,6 +700,7 @@ task linkTransmitFIS;
$display("[Device] LINK: Transmission done with ERRORs, id = %d", id); $display("[Device] LINK: Transmission done with ERRORs, id = %d", id);
// L_IDLE // L_IDLE
linkSendPrim("SYNC"); linkSendPrim("SYNC");
@ (posedge clk);
end end
endtask endtask
......
...@@ -216,10 +216,10 @@ assign cmd_out = wdata; ...@@ -216,10 +216,10 @@ assign cmd_out = wdata;
assign sh_data_strobe = bram_regen & bram_raddr_r == 8'h00; reg [7:0] bram_raddr_r;
assign sh_data_strobe = bram_ren & bram_raddr[7:0] == 8'h00;
// read from registers. Interface's protocol assumes returning data with a delay // read from registers. Interface's protocol assumes returning data with a delay
reg [7:0] bram_raddr_r;
reg [31:0] bram_rdata_r; reg [31:0] bram_rdata_r;
always @ (posedge ACLK) begin always @ (posedge ACLK) begin
bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r; bram_raddr_r <= bram_ren ? bram_raddr[7:0] : bram_raddr_r;
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
* Takes commands from axi iface as a slave, transfers data with another axi iface as a master * Takes commands from axi iface as a slave, transfers data with another axi iface as a master
*/ */
module sata_top( module sata_top(
output wire sclk,
/* /*
* Commands interface * Commands interface
*/ */
...@@ -224,7 +225,7 @@ wire bram_regen; ...@@ -224,7 +225,7 @@ wire bram_regen;
// sata logic reset // sata logic reset
wire rst; wire rst;
// sata clk // sata clk
wire sclk; //wire sclk;
// dma_regs <-> dma_control // dma_regs <-> dma_control
wire [31:7] mem_address; wire [31:7] mem_address;
wire [31:0] lba; wire [31:0] lba;
...@@ -612,7 +613,7 @@ sata_host sata_host( ...@@ -612,7 +613,7 @@ sata_host sata_host(
// sata rst // sata rst
.rst (sata_rst), .rst (sata_rst),
// sata clk // sata clk
.clk (clk), .clk (sclk),
// temporary // temporary
.al_cmd_in (cmd_out), // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good; cmd_busy} .al_cmd_in (cmd_out), // == {cmd_type, cmd_port, cmd_val, cmd_done_bad, cmd_done_good; cmd_busy}
.al_cmd_val_in (cmd_val_out), .al_cmd_val_in (cmd_val_out),
......
...@@ -42,6 +42,7 @@ parameter REGISTERS_CNT = 20; ...@@ -42,6 +42,7 @@ parameter REGISTERS_CNT = 20;
wire [32*REGISTERS_CNT - 1:0] outmem; wire [32*REGISTERS_CNT - 1:0] outmem;
wire clrstart; wire clrstart;
wire sclk;
wire [3:0] fclk; wire [3:0] fclk;
wire [3:0] frst; wire [3:0] frst;
wire axi_aclk; wire axi_aclk;
...@@ -157,12 +158,13 @@ wire buf_rd; ...@@ -157,12 +158,13 @@ wire buf_rd;
wire [63:0] buf_rdata; wire [63:0] buf_rdata;
assign comb_rst=~frst[0] | frst[1]; assign comb_rst=~frst[0] | frst[1];
always @(posedge comb_rst or posedge axi_aclk) begin always @(posedge comb_rst or posedge axi_aclk0) begin
if (comb_rst) axi_rst_pre <= 1'b1; if (comb_rst) axi_rst_pre <= 1'b1;
else axi_rst_pre <= 1'b0; else axi_rst_pre <= 1'b0;
end end
BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(fclk[0])); BUFG bufg_axi_aclk_i (.O(axi_aclk),.I(/*fclk[0]*/ sclk));
BUFG bufg_axi_aclk0_i (.O(axi_aclk0),.I(fclk[0]));
BUFG bufg_axi_rst_i (.O(axi_rst),.I(axi_rst_pre)); BUFG bufg_axi_rst_i (.O(axi_rst),.I(axi_rst_pre));
axi_hp_clk #( axi_hp_clk #(
.CLKIN_PERIOD(20), .CLKIN_PERIOD(20),
...@@ -170,12 +172,13 @@ axi_hp_clk #( ...@@ -170,12 +172,13 @@ axi_hp_clk #(
.CLKFBOUT_DIV_AXIHP(6) .CLKFBOUT_DIV_AXIHP(6)
) axi_hp_clk_i ( ) axi_hp_clk_i (
.rst (axi_rst), // input .rst (axi_rst), // input
.clk_in (axi_aclk), // input .clk_in (axi_aclk0), // input
.clk_axihp (hclk), // output .clk_axihp (hclk), // output
.locked_axihp () // output // not controlled? .locked_axihp () // output // not controlled?
); );
sata_top sata_top( sata_top sata_top(
.sclk (sclk),
.ACLK (axi_aclk), .ACLK (axi_aclk),
.ARESETN (axi_rst), .ARESETN (axi_rst),
// AXI PS Master GP1: Read Address // AXI PS Master GP1: Read Address
......
...@@ -245,7 +245,7 @@ assign tl_data_val_out = 1'b0; ...@@ -245,7 +245,7 @@ assign tl_data_val_out = 1'b0;
always @ (posedge clk) always @ (posedge clk)
waddr <= rst ? 1'b0 : ~tl_data_val_in ? waddr : (raddr == waddr + 1'b1) ? waddr : waddr + 1'b1; waddr <= rst ? 1'b0 : ~tl_data_val_in ? waddr : (raddr == waddr + 1'b1) ? waddr : waddr + 1'b1;
always @ (posedge clk) always @ (posedge clk)
raddr <= rst ? 1'b0 : al_sh_data_strobe_in ? raddr + 1'b1 : waddr; raddr <= rst ? 1'b0 : al_sh_data_strobe_in ? raddr + 1'b1 : raddr;
ram_1kx32_1kx32 rbuf( ram_1kx32_1kx32 rbuf(
.rclk (clk), // clock for read port .rclk (clk), // clock for read port
......
...@@ -525,7 +525,7 @@ begin ...@@ -525,7 +525,7 @@ begin
data_out_r <= scrambler_out; data_out_r <= scrambler_out;
data_out_rr <= data_out_r; data_out_rr <= data_out_r;
data_val_out_r <= inc_is_data; data_val_out_r <= inc_is_data;
data_val_out_rr <= data_val_out_r; data_val_out_rr <= data_val_out_r & ~set_rcvr_eof; // means that @ previous clock cycle the delivered data was crc
end end
assign data_out = data_out_rr; assign data_out = data_out_rr;
assign data_mask_out = 2'b11;//{DATA_BYTE_WIDTH/2{1'b1}}; assign data_mask_out = 2'b11;//{DATA_BYTE_WIDTH/2{1'b1}};
...@@ -657,9 +657,9 @@ begin ...@@ -657,9 +657,9 @@ begin
$display("[Host] LINK: From device - received data = %h", data_out); $display("[Host] LINK: From device - received data = %h", data_out);
end end
if (inc_is_data) begin // if (inc_is_data) begin
$display("[Host] LINK: From device - received raw data = %h", phy_data_in); // $display("[Host] LINK: From device - received raw data = %h", phy_data_in);
end // end
end end
`endif `endif
......
#!/bin/bash #!/bin/bash
LOGFILE_PATH="sim.log" LOGFILE_PATH="sim.log"
/usr/local/bin/vvp a.out -v $1 #2>&1 | tee $LOGFILE_PATH /usr/local/bin/vvp a.out -v $1 | tee $LOGFILE_PATH
#2>&1 | tee $LOGFILE_PATH
...@@ -70,7 +70,8 @@ reg SIMUL_AXI_FULL; // some data available ...@@ -70,7 +70,8 @@ reg SIMUL_AXI_FULL; // some data available
wire SIMUL_AXI_EMPTY= ~rvalid && rready && (rid==LAST_ARID); //SuppressThisWarning VEditor : may be unused, just for simulation // use it to wait for? wire SIMUL_AXI_EMPTY= ~rvalid && rready && (rid==LAST_ARID); //SuppressThisWarning VEditor : may be unused, just for simulation // use it to wait for?
reg [31:0] registered_rdata; // here read data from task reg [31:0] registered_rdata; // here read data from task
reg CLK; //reg CLK;
wire CLK;
reg RST; reg RST;
reg AR_SET_CMD_r; reg AR_SET_CMD_r;
wire AR_READY; wire AR_READY;
...@@ -156,12 +157,13 @@ wire #(AXI_TASK_HOLD) AR_SET_CMD = AR_SET_CMD_r; ...@@ -156,12 +157,13 @@ wire #(AXI_TASK_HOLD) AR_SET_CMD = AR_SET_CMD_r;
wire #(AXI_TASK_HOLD) AW_SET_CMD = AW_SET_CMD_r; wire #(AXI_TASK_HOLD) AW_SET_CMD = AW_SET_CMD_r;
wire #(AXI_TASK_HOLD) W_SET_CMD = W_SET_CMD_r; wire #(AXI_TASK_HOLD) W_SET_CMD = W_SET_CMD_r;
always #(CLKIN_PERIOD/2) CLK = ~CLK; //always #(CLKIN_PERIOD/2) CLK = ~CLK;
assign CLK = dut.axi_aclk;
/* /*
* connect axi ports to the dut * connect axi ports to the dut
*/ */
assign dut.ps7_i.FCLKCLK= {4{CLK}}; assign dut.ps7_i.FCLKCLK= {4{EXTCLK_P}};
assign dut.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST}; assign dut.ps7_i.FCLKRESETN= {RST,~RST,RST,~RST};
// Read address // Read address
assign dut.ps7_i.MAXIGP1ARADDR= araddr; assign dut.ps7_i.MAXIGP1ARADDR= araddr;
...@@ -537,6 +539,75 @@ simul_axi_hp_wr #( ...@@ -537,6 +539,75 @@ simul_axi_hp_wr #(
`include "includes/x393_tasks01.vh" `include "includes/x393_tasks01.vh"
`include "includes/x393_tasks_afi.vh" `include "includes/x393_tasks_afi.vh"
/*
* Monitor maxi bus read data.
* No burst assumed, so we're interested only in 3 signals to monitor on.
* Every time something is on a bus, data and id of a transaction are pushed into a fifo
* Fifo can be read by maxiMonitorPop function. Check if fifo is empty by calling maxiMonitorIsEmpty()
*/
// path to these signals
wire [31:0] maxi_monitor_rdata;
wire [11:0] maxi_monitor_rid;
wire maxi_monitor_rvalid;
assign maxi_monitor_rdata = dut.ps7_i.MAXIGP1RDATA;
assign maxi_monitor_rid = dut.ps7_i.MAXIGP1RID;
assign maxi_monitor_rvalid = dut.ps7_i.MAXIGP1RVALID;
localparam maxi_monitor_fifo_size = 2049;
reg [43:0] maxi_monitor_fifo [maxi_monitor_fifo_size - 1:0];
integer maxi_monitor_raddr = 0;
integer maxi_monitor_waddr = 0;
reg maxi_monitor_fifo_empty = 1;
function maxiMonitorIsEmpty(
input dummy
);
begin
maxiMonitorIsEmpty = maxi_monitor_fifo_empty;
end
endfunction
task maxiMonitorPop;
output reg [31:0] data;
output integer id;
begin
if ((maxi_monitor_waddr == maxi_monitor_raddr) && maxi_monitor_fifo_empty) begin
$display("[Testbench] maxiMonitorPop: Trying to pop from an empty fifo");
$finish;
end
data = maxi_monitor_fifo[maxi_monitor_raddr][31:0]; // RDATA
id = maxi_monitor_fifo[maxi_monitor_raddr][43:32]; // RID
maxi_monitor_raddr = (maxi_monitor_raddr + 1) % maxi_monitor_fifo_size;
if (maxi_monitor_waddr == maxi_monitor_raddr) begin
maxi_monitor_fifo_empty = 1;
end
end
endtask
task maxiMonitorPush;
input [31:0] data;
input [11:0] id;
begin
if (maxi_monitor_raddr == (maxi_monitor_waddr + 1)) begin
$display("[Testbench] maxiMonitorPush: trying to push to a full fifo");
$finish;
end
maxi_monitor_fifo[maxi_monitor_waddr][31:0] = data;
maxi_monitor_fifo[maxi_monitor_waddr][43:32] = id;
maxi_monitor_fifo_empty = 1'b0;
$display("[Testbench] MAXI: Got data = %h, id = %h", data, id);
maxi_monitor_waddr = (maxi_monitor_waddr + 1) % maxi_monitor_fifo_size;
end
endtask
initial forever @ (posedge CLK) begin
if (~RST) begin
if (maxi_monitor_rvalid) begin
maxiMonitorPush(maxi_monitor_rdata, maxi_monitor_rid);
end
end
end
// testing itself // testing itself
`include "test_top.v" `include "test_top.v"
......
...@@ -32,10 +32,12 @@ end ...@@ -32,10 +32,12 @@ end
integer i; integer i;
integer status; integer status;
integer id;
reg [31:0] data;
// write registers // write registers
initial initial
begin begin
CLK =1'b0; // CLK =1'b0;
RST = 1'bx; RST = 1'bx;
AR_SET_CMD_r = 1'b0; AR_SET_CMD_r = 1'b0;
AW_SET_CMD_r = 1'b0; AW_SET_CMD_r = 1'b0;
...@@ -47,20 +49,20 @@ begin ...@@ -47,20 +49,20 @@ begin
NUM_WORDS_EXPECTED =0; NUM_WORDS_EXPECTED =0;
// #99000; // same as glbl // #99000; // same as glbl
#900; // same as glbl #900; // same as glbl
repeat (20) @(posedge CLK) ; repeat (20) @(posedge EXTCLK_P) ;
RST =1'b0; RST =1'b0;
@ (negedge dut.sata_top.sata_rst); @ (negedge dut.sata_top.sata_rst);
repeat (20) repeat (20)
@ (posedge CLK); @ (posedge dev.clk);
// test MAXI1 inface // test MAXI1 inface
axi_set_rd_lag(0); axi_set_rd_lag(0);
axi_write_single(32'h4, 32'hdeadbeef); axi_write_single(32'h4, 32'hdeadbeef);
axi_read_addr(12'h777, 32'h4, 4'h3, 2'b01); // axi_read_addr(12'h777, 32'h4, 4'h3, 2'b01);
repeat (7) repeat (7)
@ (posedge CLK); @ (posedge dev.clk);
axi_write_single(32'h8, 32'hd34db33f); axi_write_single(32'h8, 32'hd34db33f);
axi_read_addr(12'h555, 32'h0, 4'h3, 2'b01); // axi_read_addr(12'h555, 32'h0, 4'h3, 2'b01);
for (i = 0; i < 2048; i = i + 1) begin for (i = 0; i < 2048; i = i + 1) begin
...@@ -81,7 +83,7 @@ begin ...@@ -81,7 +83,7 @@ begin
end end
if (dev.receive_status != 0) begin if (dev.receive_status != 0) begin
$display("[Test] Failed step"); $display("[Test] Failed");
$finish; $finish;
end end
...@@ -98,7 +100,11 @@ begin ...@@ -98,7 +100,11 @@ begin
dev.transmit_data[3] = 32'hdeadbeef; // whatever dev.transmit_data[3] = 32'hdeadbeef; // whatever
dev.transmit_data[4] = 32'hdeadbeef; // whatever dev.transmit_data[4] = 32'hdeadbeef; // whatever
dev.linkTransmitFIS(66, 4, 0, status); dev.linkTransmitFIS(66, 5, 0, status);
if (status != 0) begin
$display("[Test] Failed");
$finish;
end
$display("[Test] Dev sent BSY flag"); $display("[Test] Dev sent BSY flag");
// checks if BSY is set up // only on waves TODO // checks if BSY is set up // only on waves TODO
...@@ -106,20 +112,75 @@ begin ...@@ -106,20 +112,75 @@ begin
repeat (50) repeat (50)
@ (posedge dev.clk); @ (posedge dev.clk);
$display("[Test] Device sends PIO Setup");
dev.transmit_data[0] = 32'h0080205f; // direction d2h, type = 5f
dev.transmit_data[1] = 32'hdeadbeef; // whatever
dev.transmit_data[2] = 32'hdeadbeef; // whatever
dev.transmit_data[3] = 32'h00adbeef; // whatever
dev.transmit_data[4] = 32'h00000014; // let it be 20 bytes to be transfered
dev.linkTransmitFIS(11, 5, 0, status);
if (status != 0) begin
$display("[Test] Failed");
$finish;
end
$display("[Test] Device sends data FIS");
dev.transmit_data[0] = 32'h00000046; // type = 46
dev.transmit_data[1] = 32'hfeeddeaf;
dev.transmit_data[2] = 32'ha114bea7;
dev.transmit_data[3] = 32'hca110911;
dev.transmit_data[4] = 32'hCA715F1E;
dev.transmit_data[5] = 32'hdeadbeef;
dev.linkTransmitFIS(22, 6, 0, status);
if (status != 0) begin
$display("[Test] Failed");
$finish;
end
repeat (20)
@ (posedge dev.clk);
// prepare monitor - clean it before actual usage
while (~maxiMonitorIsEmpty(0)) begin
maxiMonitorPop(data, id);
end
// imitating PIO reads
$display("[Test] Read data word 0");
axi_read_addr(12'h660, {30'h00, 2'b00}, 4'h0, 2'b01);
$display("[Test] Read data word 1");
axi_read_addr(12'h661, {30'h00, 2'b00}, 4'h0, 2'b01);
$display("[Test] Read data word 2");
axi_read_addr(12'h662, {30'h00, 2'b00}, 4'h0, 2'b01);
$display("[Test] Read data word 3");
axi_read_addr(12'h663, {30'h00, 2'b00}, 4'h0, 2'b01);
repeat (1000) $display("[Test] Read data word 4");
axi_read_addr(12'h664, {30'h00, 2'b00}, 4'h0, 2'b01);
// check if all ok
i = 0;
while (~maxiMonitorIsEmpty(0)) begin
maxiMonitorPop(data, id);
if (dev.transmit_data[i] != data) begin
$display("[Test] Data check failed");
$finish;
end
i = i + 1;
end
$display("[Test] Data check OK");
repeat (30)
@ (posedge dev.clk); @ (posedge dev.clk);
for (i = 0; i < 32; i = i + 1) begin /* for (i = 0; i < 32; i = i + 1) begin
$display("data received : %h", dev.receive_data[i]); $display("data received : %h", dev.receive_data[i]);
end end*/
$display("============= DONE ============="); $display("============= DONE =============");
$finish; $finish;
...@@ -174,6 +235,7 @@ end ...@@ -174,6 +235,7 @@ end
*/ */
initial begin initial begin
#100000; #100000;
$display("[Test] Failed");
$display("============= TIMELIMIT ============="); $display("============= TIMELIMIT =============");
$finish; $finish;
end end
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