Files
APS/Labs/15. Programming device/bluster_pkg.sv
Andrei Solodovnikov 5aeb054317 ЛР15. Хотфиксы
2024-07-28 12:54:35 +03:00

113 lines
4.5 KiB
Systemverilog

/* -----------------------------------------------------------------------------
* Project Name : Architectures of Processor Systems (APS) lab work
* Organization : National Research University of Electronic Technology (MIET)
* Department : Institute of Microdevices and Control Systems
* Author(s) : Andrei Solodovnikov
* Email(s) : hepoh@org.miet.ru
See https://github.com/MPSU/APS/blob/master/LICENSE file for licensing details.
* ------------------------------------------------------------------------------
*/
package bluster_pkg;
localparam INIT_MSG_SIZE = 41;
localparam FLASH_MSG_SIZE = 57;
localparam ACK_MSG_SIZE = 4;
/* -----------------------------------------------------------------------------
Lab_15 tb tasks
* -----------------------------------------------------------------------------
*/
task automatic send_data(input byte mem[$], ref logic clk_i, tx_valid, tx_busy, ref logic [7:0] tx_data);
for(int i = mem.size()-1; i >=0; i--) begin
tx_data = mem[i];
tx_valid = 1'b1;
@(posedge clk_i);
tx_valid = 1'b0;
@(posedge clk_i);
while(tx_busy) @(posedge clk_i);
end
endtask
task automatic rcv_data(input int size, ref logic clk_i, rx_valid, tx_o, ref logic [7:0] rx_data);
automatic logic [0:FLASH_MSG_SIZE-1][7:0] str;
automatic logic [3:0][7:0] size_val;
for(int i = 0; i < size; i++) begin
@(posedge clk_i);
while(!rx_valid)@(posedge clk_i);
str[i] = rx_data;
size_val[3-i] = rx_data;
end
case(size)
INIT_MSG_SIZE: begin
$display("%s", str[0:INIT_MSG_SIZE-2]);
assert(str[0:INIT_MSG_SIZE-10] == "ready for flash starting from 0x")begin end
else $error("Init message format is incorrect. Should be \"ready for flash starting from 0xADDR\"");
end
FLASH_MSG_SIZE: begin
$display("%s", str[0:FLASH_MSG_SIZE-2]);
assert((str[0:16] == "finished write 0x") && (str[25+:23] == " bytes starting from 0x"))begin end
else $error("finish message format is incorrect. Should be \"finished write 0xSIZE bytes starting from 0xADDR\"");
end
ACK_MSG_SIZE : $display("%0d", size_val);
endcase
wait(tx_o);
endtask
task automatic program_region(input string fname, ref logic clk_i, tx_valid, rx_valid, tx_o, tx_busy, reset, ref logic [7:0] rx_data, tx_data);
automatic int fd, start_addr;
automatic logic [31:0] data;
automatic byte mem[$];
automatic byte str [4];
automatic logic [3:0][7:0] size;
$display("\n%0t. Start programming %s", $time, fname);
fd = $fopen(fname, "r");
assert(fd)
else $fatal(1, "Can't open file %s", fname);
void'($fscanf(fd, "@%x\w", start_addr));
start_addr <<=2;
while(!$feof(fd)) begin
$fscanf(fd, "%x\w", data);
mem.push_back(data[ 7: 0]);
mem.push_back(data[15: 8]);
mem.push_back(data[23:16]);
mem.push_back(data[31:24]);
end
$fclose(fd);
size = mem.size();
str = {start_addr[7:0],start_addr[15:8],start_addr[23:16],start_addr[31:24]};
send_data(str, clk_i, tx_valid, tx_busy, tx_data);
rcv_data(INIT_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
str = {size[0],size[1],size[2],size[3]};
send_data(str, clk_i, tx_valid, tx_busy, tx_data);
rcv_data(ACK_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
send_data(mem, clk_i, tx_valid, tx_busy, tx_data);
rcv_data(FLASH_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
$display("%0t. Region has been programmed", $time);
assert(reset)
else $error("Reset must be equal 1 while flashing is not done.");
endtask
task automatic finish_programming(ref logic clk_i, tx_valid, tx_busy, reset, ref logic [7:0] tx_data);
automatic byte mem[$];
mem.push_back(8'hff);
mem.push_back(8'hff);
mem.push_back(8'hff);
mem.push_back(8'hff);
send_data(mem, clk_i, tx_valid, tx_busy, tx_data);
$display("Flashing is complete");
assert(!reset)
else $error("Reset must be equal 0 after flashing is complete.");
endtask
task automatic dummy_programming(ref logic clk_i, tx_valid, rx_valid, tx_o, tx_busy, reset, ref logic [7:0] rx_data, tx_data);
automatic byte str [4] = {8'd0, 8'd0, 8'd0, 8'd0};
rcv_data(INIT_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
send_data(str, clk_i, tx_valid, tx_busy, tx_data);
rcv_data(ACK_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
rcv_data(FLASH_MSG_SIZE, clk_i, rx_valid, tx_o, rx_data);
finish_programming(clk_i, tx_valid, tx_busy, reset, rx_data);
endtask
endpackage