blob: 88e19446700fc74bb8867dec5bfb4e55de8fa30b [file] [log] [blame]
// SPDX-FileCopyrightText: 2020 Efabless Corporation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// SPDX-License-Identifier: Apache-2.0
`timescale 1ns / 1ps
module uartprog #(
parameter FILENAME="program.hex"
)(
input mprj_ready,
output reg r_Rx_Serial // used by task UART_WRITE_BYTE
);
reg r_Clock = 0;
parameter c_BIT_PERIOD = 8681; // used by task UART_WRITE_BYTE
parameter c_CLOCK_PERIOD_NS = 100;
reg [7:0] INSTR [16384-1:0];
integer instr_count = 0;
reg ready;
reg test;
always @ ( posedge r_Clock ) begin
if (mprj_ready) begin
ready <= 1'b1;
end else begin
ready <= 1'b0;
end
end
initial begin
$readmemh(FILENAME,INSTR);
end
task UART_WRITE_BYTE;
input [7:0] i_Data;
integer ii;
begin
// Send Start Bit
r_Rx_Serial <= 1'b0;
#(c_BIT_PERIOD);
#1000;
// Send Data Byte
for (ii=0; ii<8; ii=ii+1) begin
r_Rx_Serial <= i_Data[ii];
#(c_BIT_PERIOD);
end
// Send Stop Bit
r_Rx_Serial <= 1'b1;
#(c_BIT_PERIOD);
end
endtask // UART_WRITE_BYTE
initial begin
test = 1'b0;
#1000 test = 1'b1;
end
always
#(c_CLOCK_PERIOD_NS/2) r_Clock <= !r_Clock;
initial begin
r_Rx_Serial <= 1'b1;
#2000;
while (!ready && test) begin
@(posedge r_Clock)
r_Rx_Serial <= 1'b1;
end
while ((instr_count < 16384) && ({INSTR[instr_count],INSTR[instr_count+1],INSTR[instr_count+2],INSTR[instr_count+3]} != 32'h00000FFF)) begin
@(posedge r_Clock);
UART_WRITE_BYTE(INSTR[instr_count][7:0]);
@(posedge r_Clock);
UART_WRITE_BYTE(INSTR[instr_count+1][7:0]);
@(posedge r_Clock);
UART_WRITE_BYTE(INSTR[instr_count+2][7:0]);
@(posedge r_Clock);
UART_WRITE_BYTE(INSTR[instr_count+3][7:0]);
@(posedge r_Clock);
instr_count = instr_count + 32'd4;
end
@(posedge r_Clock);
UART_WRITE_BYTE(8'h00);
@(posedge r_Clock);
UART_WRITE_BYTE(8'h00);
@(posedge r_Clock);
UART_WRITE_BYTE(8'h0F);
@(posedge r_Clock);
UART_WRITE_BYTE(8'hFF);
@(posedge r_Clock);
end
endmodule