mirror of
https://github.com/MPSU/APS.git
synced 2025-09-15 09:10:10 +00:00
113 lines
4.5 KiB
Systemverilog
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 |