Added JTAG interface with testbench

This commit is contained in:
2026-02-23 15:37:49 +01:00
parent 20cfece6e3
commit 8f4e887b9d
12 changed files with 731 additions and 24 deletions

2
.gitignore vendored
View File

@@ -1,3 +1,5 @@
out out
build build
env env
__pycache*
_impactbatch.log

View File

@@ -25,3 +25,28 @@ NET "r2r[2]" IOSTANDARD = LVCMOS33;
NET "r2r[3]" IOSTANDARD = LVCMOS33; NET "r2r[3]" IOSTANDARD = LVCMOS33;
NET "r2r[4]" IOSTANDARD = LVCMOS33; NET "r2r[4]" IOSTANDARD = LVCMOS33;
NET "r2r[5]" IOSTANDARD = LVCMOS33; NET "r2r[5]" IOSTANDARD = LVCMOS33;
NET "LED[0]" LOC = P119;
NET "LED[0]" IOSTANDARD = LVCMOS33;
NET "LED[0]" DRIVE = 8;
NET "LED[1]" LOC = P118;
NET "LED[1]" IOSTANDARD = LVCMOS33;
NET "LED[1]" DRIVE = 8;
NET "LED[2]" LOC = P117;
NET "LED[2]" IOSTANDARD = LVCMOS33;
NET "LED[2]" DRIVE = 8;
NET "LED[3]" LOC = P116;
NET "LED[3]" IOSTANDARD = LVCMOS33;
NET "LED[3]" DRIVE = 8;
NET "LED[4]" LOC = P115;
NET "LED[4]" IOSTANDARD = LVCMOS33;
NET "LED[4]" DRIVE = 8;
NET "LED[5]" LOC = P114;
NET "LED[5]" IOSTANDARD = LVCMOS33;
NET "LED[5]" DRIVE = 8;
NET "LED[6]" LOC = P112;
NET "LED[6]" IOSTANDARD = LVCMOS33;
NET "LED[6]" DRIVE = 8;
NET "LED[7]" LOC = P111;
NET "LED[7]" IOSTANDARD = LVCMOS33;
NET "LED[7]" DRIVE = 8;

View File

@@ -4,6 +4,15 @@ version = 0.1
out_dir = out out_dir = out
build_dir = build build_dir = build
[target.ip]
toolchain = ISE_IP
ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh
family = spartan6
device = xc6slx9
package = tqg144
speedgrade = -2
files_def = boards/mimas_v1/ip/clk_gen.xco
[target.synth] [target.synth]
toolchain = ISE toolchain = ISE
ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh
@@ -56,31 +65,25 @@ files_other = rtl/util/rc_alpha_q15.vh
rtl/util/clog2.vh rtl/util/clog2.vh
sw/blinky/blinky.hex sw/blinky/blinky.hex
[target.ip] [target.jtag]
toolchain = ISE_IP toolchain = ISE
ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh ise_settings = /opt/Xilinx/14.7/ISE_DS/settings64.sh
family = spartan6 family = spartan6
device = xc6slx9 device = xc6slx9
package = tqg144 package = tqg144
speedgrade = -2 speedgrade = -2
files_def = boards/mimas_v1/ip/clk_gen.xco toplevel = top_jtag
xst_opts = -vlgincdir rtl/util
files_other =
files_con = boards/mimas_v1/constraints.ucf
files_verilog = rtl/arch/spartan-6/jtag_if.v
rtl/arch/spartan-6/clk_gen.v
rtl/toplevel/top_jtag.v
[target.sim] [target.svftest]
toolchain = iverilog toolchain = iverilog
runtime = all runtime = all
toplevel = tb_sigmadelta toplevel = tb_svf
ivl_opts = -Irtl/util files_verilog = sim/tb/tb_svf.v
files_verilog = sim/tb/tb_nco_q15.v sim/overrides/jtag_if.v
sim/tb/tb_sigmadelta.v files_other = sim/other/test.svf
sim/tb/tb_mul_const.v
rtl/core/nco_q15.v
rtl/core/lvds_comparator.v
rtl/core/sigmadelta_rcmodel_q15.v
rtl/core/sigmadelta_input_q15.v
rtl/core/mul_const.v
rtl/core/lpf_iir_q15_k.v
rtl/core/decimate_by_r_q15.v
sim/overrides/sigmadelta_sampler.v
sim/overrides/clk_gen.v
files_other = rtl/util/conv.vh
rtl/util/rc_alpha_q15.vh

View File

@@ -0,0 +1,34 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface
// Spartan-6 BSCAN primitive wrapper (USER1 chain).
// =============================================================================
module jtag_if #(
parameter chain = 1
)(
input wire i_tdo,
output wire o_tck,
output wire o_tdi,
output wire o_drck,
output wire o_capture,
output wire o_shift,
output wire o_update,
output wire o_runtest,
output wire o_reset,
output wire o_sel
);
BSCAN_SPARTAN6 #(
.JTAG_CHAIN(chain)
) bscan_i (
.CAPTURE(o_capture),
.DRCK(o_drck),
.RESET(o_reset),
.RUNTEST(o_runtest),
.SEL(o_sel),
.SHIFT(o_shift),
.TCK(o_tck),
.TDI(o_tdi),
.UPDATE(o_update)
);
endmodule

34
rtl/core/jtag_if.v Normal file
View File

@@ -0,0 +1,34 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface
// Generic stub model with inactive/tied-off outputs.
// =============================================================================
module jtag_if #(
parameter chain = 1
)(
input wire i_tdo,
output wire o_tck,
output wire o_tdi,
output wire o_drck,
output wire o_capture,
output wire o_shift,
output wire o_update,
output wire o_runtest,
output wire o_reset,
output wire o_sel
);
assign o_tck = 1'b0;
assign o_tdi = 1'b0;
assign o_drck = 1'b0;
assign o_capture = 1'b0;
assign o_shift = 1'b0;
assign o_update = 1'b0;
assign o_runtest = 1'b0;
assign o_reset = 1'b0;
assign o_sel = 1'b0;
// Keep lint tools quiet in generic builds where TDO is unused.
wire _unused_tdo;
assign _unused_tdo = i_tdo;
endmodule

131
rtl/toplevel/top_jtag.v Normal file
View File

@@ -0,0 +1,131 @@
module top_jtag(
input wire aclk,
input wire aresetn,
output wire led_green,
output wire led_red,
output wire [7:0] LED,
output wire [5:0] r2r
);
// Clocking
wire clk_100;
wire clk_15;
assign clk_100 = aclk;
clk_gen clocking(
.clk_in(clk_100),
.clk_out_15(clk_15)
);
localparam integer JTAG_DATA_BITS = 8;
wire [JTAG_DATA_BITS-1:0] jtag_data;
jtag_write_reg #(
.DATA_BITS(JTAG_DATA_BITS),
.CHAIN(1)
) jtag_writer (
.clk_i(clk_15),
.rst_n_i(aresetn),
.data_o(jtag_data)
);
assign LED = jtag_data[7:0];
assign led_green = jtag_data[0];
assign led_red = jtag_data[7];
assign r2r = jtag_data[5:0];
endmodule
module jtag_write_reg #(
parameter integer DATA_BITS = 8,
parameter integer CHAIN = 1
)(
input wire clk_i,
input wire rst_n_i,
output reg [DATA_BITS-1:0] data_o
);
wire jtag_tck;
wire jtag_tdi;
wire jtag_drck;
wire jtag_capture;
wire jtag_shift;
wire jtag_update;
wire jtag_runtest;
wire jtag_reset;
wire jtag_sel;
reg [DATA_BITS-1:0] shift_q;
reg [DATA_BITS-1:0] data_jtag_q;
reg update_toggle_jtag_q;
reg update_toggle_meta_q;
reg update_toggle_sync_q;
reg update_toggle_sync_d_q;
reg [DATA_BITS-1:0] data_meta_q;
reg [DATA_BITS-1:0] data_sync_q;
jtag_if #(
.chain(CHAIN)
) jtag (
.i_tdo(shift_q[0]),
.o_tck(jtag_tck),
.o_tdi(jtag_tdi),
.o_drck(jtag_drck),
.o_capture(jtag_capture),
.o_shift(jtag_shift),
.o_update(jtag_update),
.o_runtest(jtag_runtest),
.o_reset(jtag_reset),
.o_sel(jtag_sel)
);
always @(posedge jtag_drck or posedge jtag_reset or negedge rst_n_i) begin
if (!rst_n_i || jtag_reset) begin
shift_q <= {DATA_BITS{1'b0}};
end else if (jtag_sel && jtag_capture) begin
shift_q <= data_jtag_q;
end else if (jtag_sel && jtag_shift) begin
if (DATA_BITS == 1) begin
shift_q <= jtag_tdi;
end else begin
shift_q <= {jtag_tdi, shift_q[DATA_BITS-1:1]};
end
end
end
always @(posedge jtag_update or posedge jtag_reset or negedge rst_n_i) begin
if (!rst_n_i || jtag_reset) begin
data_jtag_q <= {DATA_BITS{1'b0}};
update_toggle_jtag_q <= 1'b0;
end else if (jtag_sel) begin
data_jtag_q <= shift_q;
update_toggle_jtag_q <= ~update_toggle_jtag_q;
end
end
// CDC into clk_i domain: toggle synchronize + stable data sampling.
always @(posedge clk_i or negedge rst_n_i) begin
if (!rst_n_i) begin
update_toggle_meta_q <= 1'b0;
update_toggle_sync_q <= 1'b0;
update_toggle_sync_d_q <= 1'b0;
data_meta_q <= {DATA_BITS{1'b0}};
data_sync_q <= {DATA_BITS{1'b0}};
data_o <= {DATA_BITS{1'b0}};
end else begin
update_toggle_meta_q <= update_toggle_jtag_q;
update_toggle_sync_q <= update_toggle_meta_q;
update_toggle_sync_d_q <= update_toggle_sync_q;
data_meta_q <= data_jtag_q;
data_sync_q <= data_meta_q;
if (update_toggle_sync_q ^ update_toggle_sync_d_q) begin
data_o <= data_sync_q;
end
end
end
// Not used for this simple write-register, but kept for completeness.
wire _unused_tck;
wire _unused_runtest;
assign _unused_tck = jtag_tck;
assign _unused_runtest = jtag_runtest;
endmodule

167
scripts/jtag_write_user_impact.py Executable file
View File

@@ -0,0 +1,167 @@
#!/usr/bin/env python3
"""Write USER JTAG data via iMPACT using SVF + play flow."""
from __future__ import annotations
import argparse
import os
import shutil
import subprocess
import sys
import tempfile
DEFAULT_IMPACT = "/opt/Xilinx/14.7/ISE_DS/ISE/bin/lin64/impact"
DEFAULT_SETTINGS = "/opt/Xilinx/14.7/ISE_DS/settings64.sh"
def _parse_int(value: str) -> int:
return int(value, 0)
def _resolve_impact(binary: str | None) -> str | None:
if binary:
return binary if os.path.isfile(binary) else shutil.which(binary)
if os.path.isfile(DEFAULT_IMPACT):
return DEFAULT_IMPACT
return shutil.which("impact")
def _fmt_hex_for_bits(value: int, bits: int) -> str:
masked = value & ((1 << bits) - 1)
nibbles = (bits + 3) // 4
return f"{masked:0{nibbles}X}"
def main() -> int:
parser = argparse.ArgumentParser(
description="Write USER JTAG data to Spartan-6 via iMPACT play (SVF)."
)
parser.add_argument(
"--input",
required=True,
help="Input file to stream over USER JTAG (written byte-by-byte).",
)
parser.add_argument("--output", type=str, default=None)
parser.add_argument("--dr-bits", type=int, default=8, help="DR width in bits (default: 8).")
parser.add_argument("--ir-value", type=_parse_int, default=0x02, help="IR opcode (default USER1: 0x02).")
parser.add_argument("--ir-bits", type=int, default=6, help="IR width in bits (default: 6).")
parser.add_argument("--serial", default=None, help="Cable ESN/serial (example: D306180FABCD).")
parser.add_argument("--impact", default=None, help=f"Path/name of impact binary (default: {DEFAULT_IMPACT}).")
parser.add_argument(
"--settings",
default=DEFAULT_SETTINGS,
help=f"Xilinx settings script sourced for this run only (default: {DEFAULT_SETTINGS}).",
)
parser.add_argument("--dry-run", action="store_true", help="Print generated SVF/CMD and exit.")
args = parser.parse_args()
if args.dr_bits <= 0 or args.ir_bits <= 0:
print("error: --dr-bits and --ir-bits must be > 0", file=sys.stderr)
return 2
if args.dr_bits != 8:
print("error: this file-stream mode currently supports only --dr-bits 8", file=sys.stderr)
return 2
impact = _resolve_impact(args.impact)
if impact is None:
print("error: impact binary not found", file=sys.stderr)
return 127
if not os.path.isfile(args.input):
print(f'error: input file not found: "{args.input}"', file=sys.stderr)
return 2
ir_hex = _fmt_hex_for_bits(args.ir_value, args.ir_bits)
with open(args.input, "rb") as f:
payload = f.read()
if len(payload) == 0:
print("error: input file is empty", file=sys.stderr)
return 2
svf_lines = [
"! Auto-generated by jtag_write_user_impact.py",
f"! Source file: {args.input} ({len(payload)} bytes)",
"TRST ABSENT;",
"ENDIR IDLE;",
"ENDDR IDLE;",
"STATE RESET;",
"STATE IDLE;",
f"SIR {args.ir_bits} TDI ({ir_hex});",
]
for byte in payload:
svf_lines.append(f"SDR 8 TDI ({byte:02X});")
svf_lines += [
"RUNTEST 16 TCK;",
"STATE IDLE;",
"",
]
svf_text = "\n".join(svf_lines)
cable_cmd = "setCable -port auto"
if args.serial:
cable_cmd += f" -esn {args.serial}"
if args.dry_run:
print("### SVF ###")
preview_limit = 64
if len(payload) <= preview_limit:
print(svf_text, end="")
else:
preview = "\n".join(svf_lines[:8 + preview_limit])
print(preview)
print(f"... ({len(payload) - preview_limit} more SDR lines omitted)")
print("### iMPACT CMD ###")
print("setMode -bs")
print(cable_cmd)
print("addDevice -p 1 -file <generated.svf>")
print("play")
print("quit")
return 0
svf_path = None
cmd_path = None
try:
with tempfile.NamedTemporaryFile("w", suffix=".svf", delete=False) as sf:
sf.write(svf_text)
svf_path = sf.name
if args.output is not None:
with open(args.output, "w") as sf:
sf.write(svf_text)
cmd_text = "\n".join(
[
"setMode -bs",
cable_cmd,
f'addDevice -p 1 -file "{svf_path}"',
"play",
"quit",
"",
]
)
with tempfile.NamedTemporaryFile("w", suffix=".cmd", delete=False) as cf:
cf.write(cmd_text)
cmd_path = cf.name
shell_cmd = (
f'source "{args.settings}" >/dev/null 2>&1 && '
f'"{impact}" -batch "{cmd_path}"'
)
proc = subprocess.run(["bash", "-lc", shell_cmd], text=True, capture_output=True)
output = (proc.stdout or "") + (proc.stderr or "")
print(output, end="")
return proc.returncode
finally:
if cmd_path is not None:
try:
os.unlink(cmd_path)
except OSError:
pass
if svf_path is not None:
try:
os.unlink(svf_path)
except OSError:
pass
if __name__ == "__main__":
raise SystemExit(main())

25
sim/other/test.svf Normal file
View File

@@ -0,0 +1,25 @@
TRST ABSENT;
ENDIR IDLE;
ENDDR IDLE;
STATE RESET;
STATE IDLE;
SIR 6 TDI (02);
SDR 8 TDI (07);
SDR 8 TDI (4C);
SDR 8 TDI (43);
SDR 8 TDI (D1);
SDR 8 TDI (97);
SDR 8 TDI (6B);
SDR 8 TDI (3D);
SDR 8 TDI (E4);
SDR 8 TDI (20);
SDR 8 TDI (3A);
SDR 8 TDI (8E);
SDR 8 TDI (1D);
SDR 8 TDI (9D);
SDR 8 TDI (E4);
RUNTEST 16 TCK;
STATE RESET;
STATE IDLE;

196
sim/overrides/jtag_if.v Normal file
View File

@@ -0,0 +1,196 @@
`timescale 1ns/1ps
// =============================================================================
// JTAG interface (simulation override)
// Behavioral SVF player for simple USER-chain simulation.
//
// Supported SVF commands (line-oriented, uppercase recommended):
// - SIR <n> TDI (<hex>);
// - SDR <n> TDI (<hex>);
// - RUNTEST <n> TCK;
// - STATE RESET;
// - STATE IDLE;
// Other lines are ignored.
// =============================================================================
module jtag_if #(
parameter integer chain = 1,
parameter [8*256-1:0] SVF_FILE = "write_jtag.svf",
parameter integer TCK_HALF_PERIOD_NS = 50,
parameter [31:0] USER_IR_OPCODE = 32'h00000002
)(
input wire i_tdo,
output reg o_tck,
output reg o_tdi,
output reg o_drck,
output reg o_capture,
output reg o_shift,
output reg o_update,
output reg o_runtest,
output reg o_reset,
output reg o_sel
);
integer fd;
integer got;
integer nbits;
integer cycles;
integer i;
integer line_no;
integer scan_bits;
reg [8*1024-1:0] line;
reg [8*32-1:0] cmd;
reg [8*32-1:0] arg1;
reg [8*256-1:0] svf_file_path;
reg [4095:0] scan_data;
reg [31:0] current_ir;
reg selected;
// Keep linters quiet: TDO is not consumed by this simple player.
wire _unused_tdo;
assign _unused_tdo = i_tdo;
task pulse_tck;
begin
#TCK_HALF_PERIOD_NS o_tck = 1'b1;
#TCK_HALF_PERIOD_NS o_tck = 1'b0;
end
endtask
task pulse_drck_shift;
input bit_in;
begin
o_tdi = bit_in;
o_shift = 1'b1;
#TCK_HALF_PERIOD_NS begin
o_tck = 1'b1;
o_drck = 1'b1;
end
#TCK_HALF_PERIOD_NS begin
o_tck = 1'b0;
o_drck = 1'b0;
end
end
endtask
task pulse_capture;
begin
o_capture = 1'b1;
#TCK_HALF_PERIOD_NS begin
o_tck = 1'b1;
o_drck = 1'b1;
end
#TCK_HALF_PERIOD_NS begin
o_tck = 1'b0;
o_drck = 1'b0;
o_capture = 1'b0;
end
end
endtask
task pulse_update;
begin
o_shift = 1'b0;
#TCK_HALF_PERIOD_NS o_update = 1'b1;
#TCK_HALF_PERIOD_NS o_update = 1'b0;
end
endtask
initial begin
// Default output levels
o_tck = 1'b0;
o_tdi = 1'b0;
o_drck = 1'b0;
o_capture = 1'b0;
o_shift = 1'b0;
o_update = 1'b0;
o_runtest = 1'b0;
o_reset = 1'b0;
o_sel = 1'b0;
selected = 1'b0;
current_ir = 32'h0;
line_no = 0;
svf_file_path = SVF_FILE;
// Deterministic startup reset pulse before consuming SVF.
o_reset = 1'b1;
#TCK_HALF_PERIOD_NS o_tck = 1'b1;
#TCK_HALF_PERIOD_NS o_tck = 1'b0;
#TCK_HALF_PERIOD_NS o_tck = 1'b1;
#TCK_HALF_PERIOD_NS o_tck = 1'b0;
o_reset = 1'b0;
fd = $fopen(svf_file_path, "r");
if (fd == 0) begin
$display("jtag_if(sim): could not open SVF file '%0s'", svf_file_path);
end else begin
while (!$feof(fd)) begin
line = {8*1024{1'b0}};
got = $fgets(line, fd);
line_no = line_no + 1;
if (got > 0) begin
cmd = {8*32{1'b0}};
arg1 = {8*32{1'b0}};
scan_data = {4096{1'b0}};
nbits = 0;
cycles = 0;
got = $sscanf(line, "%s", cmd);
if (got < 1) begin
// Empty line
end else if (cmd == "!") begin
// Comment line
end else if (cmd == "SIR") begin
got = $sscanf(line, "SIR %d TDI (%h);", nbits, scan_data);
if (got == 2) begin
current_ir = scan_data[31:0];
selected = (current_ir == USER_IR_OPCODE);
o_sel = selected;
// Emit TCK pulses for IR shift activity.
scan_bits = nbits;
if (scan_bits > 4096) scan_bits = 4096;
for (i = 0; i < scan_bits; i = i + 1) begin
o_tdi = scan_data[i];
pulse_tck;
end
end
end else if (cmd == "SDR") begin
got = $sscanf(line, "SDR %d TDI (%h);", nbits, scan_data);
if (got == 2) begin
if (selected) begin
pulse_capture;
end
scan_bits = nbits;
if (scan_bits > 4096) scan_bits = 4096;
for (i = 0; i < scan_bits; i = i + 1) begin
pulse_drck_shift(scan_data[i]);
end
if (selected) begin
pulse_update;
end
end
end else if (cmd == "RUNTEST") begin
got = $sscanf(line, "RUNTEST %d TCK;", cycles);
if (got == 1) begin
o_runtest = 1'b1;
for (i = 0; i < cycles; i = i + 1)
pulse_tck;
o_runtest = 1'b0;
end
end else if (cmd == "STATE") begin
got = $sscanf(line, "STATE %s", arg1);
if (got == 1) begin
if (arg1 == "RESET;") begin
o_reset = 1'b1;
#TCK_HALF_PERIOD_NS o_reset = 1'b0;
selected = 1'b0;
o_sel = 1'b0;
end
end
end
end
end
$fclose(fd);
end
end
endmodule

90
sim/tb/tb_svf.v Normal file
View File

@@ -0,0 +1,90 @@
`timescale 1ns/1ps
module tb_svf();
wire [7:0] led_out;
wire [31:0] update_count;
jtag_byte_sink #(
.SVF_FILE("sim/other/test.svf"),
.TCK_HALF_PERIOD_NS(50)
) dut (
.o_led(led_out),
.o_update_count(update_count)
);
initial begin
// Optional waveform dump.
$dumpfile("out.vcd");
$dumpvars;
// Timeout for large SVF playback.
#20_000;
$finish;
end
endmodule
module jtag_byte_sink #(
parameter [8*256-1:0] SVF_FILE = "",
parameter integer TCK_HALF_PERIOD_NS = 50
)(
output reg [7:0] o_led,
output reg [31:0] o_update_count
);
wire jtag_tck;
wire jtag_tdi;
wire jtag_drck;
wire jtag_capture;
wire jtag_shift;
wire jtag_update;
wire jtag_runtest;
wire jtag_reset;
wire jtag_sel;
wire jtag_tdo;
reg [7:0] shift_reg;
assign jtag_tdo = shift_reg[0];
jtag_if #(
.chain(1),
.SVF_FILE(SVF_FILE),
.TCK_HALF_PERIOD_NS(TCK_HALF_PERIOD_NS),
.USER_IR_OPCODE(32'h0000_0002)
) jtag (
.i_tdo(jtag_tdo),
.o_tck(jtag_tck),
.o_tdi(jtag_tdi),
.o_drck(jtag_drck),
.o_capture(jtag_capture),
.o_shift(jtag_shift),
.o_update(jtag_update),
.o_runtest(jtag_runtest),
.o_reset(jtag_reset),
.o_sel(jtag_sel)
);
always @(posedge jtag_drck or posedge jtag_reset) begin
if (jtag_reset) begin
shift_reg <= 8'h00;
end else if (jtag_sel && jtag_capture) begin
shift_reg <= o_led;
end else if (jtag_sel && jtag_shift) begin
shift_reg <= {jtag_tdi, shift_reg[7:1]};
end
end
always @(posedge jtag_update or posedge jtag_reset) begin
if (jtag_reset) begin
o_led <= 8'h00;
o_update_count <= 32'd0;
end else if (jtag_sel) begin
o_led <= shift_reg;
o_update_count <= o_update_count + 1'b1;
end
end
// Keep lint happy for currently unused outputs.
wire _unused_tck;
wire _unused_runtest;
assign _unused_tck = jtag_tck;
assign _unused_runtest = jtag_runtest;
endmodule

View File

@@ -3,7 +3,7 @@ ENTRY(_start)
MEMORY MEMORY
{ {
RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 8K RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 8064
} }
SECTIONS SECTIONS

View File

@@ -3,7 +3,7 @@ ENTRY(_start)
MEMORY MEMORY
{ {
RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 8K RAM (rwx) : ORIGIN = 0x00000000, LENGTH = 8064
} }
SECTIONS SECTIONS