B
BobH
Guest
On 11/30/2015 6:32 PM, Simon wrote:
I am not clear what you are trying to do with the stack here. Do you
have a relatively complete CPU implemented?
I would expect something like:
module CPU6502
(
output wire [ 7:0] data_out,
output wire [15:0] address_out,
input wire [ 7:0] data_in,
output wire write_enable,
output wire read_enable,
input wire irq_in,
input wire nmi_in,
input wire clk,
input wire rstn
)
I would expect that you would have an 8 bit stack pointer that would get
muxed onto the address bus, possibly with offsets from the instruction
stream. The newSP value would go into the stack pointer when you are
updating the stack.
RAM would get hung on the address and data buses with block decode logic
to decode the upper address bits into a chip select for the RAM and
peripherals. Since FPGA's don't do tri-state buses, there will be a read
data in mux to select the data source from the addressed bus target for
reads.
sort of like:
module mcu
(
output uart_txd,
input uart_rxd,
input clk,
input rstn
)
wire [15:0] address;
wire [ 7:0] data_out;
wire [ 7:0] ram_data, rom_data, uart_data;
reg [ 7:0] data_in;
wire ram_block_sel, rom_block_sel, uart_block_sel;
wire write_enable, read_enable;
CPU6502 cpu
(
.data_out (data_out),
.data_in (data_in),
.address_out (address),
.write_enable (write_enable),
.read_enable (read_enable),
.irq_in (irq),
.nmi_in (1'b0),
.clk (clk),
.rstn (rstn)
);
RAM_1Kx8 ram
(
.address_in (address[9:0]),
.data_in (data_out),
.data_out (ram_data),
.write_enable (write_enable),
.chip_sel (ram_block_sel)
);
ROM_1Kx8 rom
(
..address_in (address[9:0]),
..data_out (rom_data),
..read_enable (read_enable),
..chip_sel (rom_block_sel)
);
UART uart
(
..txd (uart_txd),
..rxd (uart_rxd),
..reg_select (address[1:0]), // 2 bits of address
..data_in (data_out),
..data_out (uart_data),
..write_enable (write_enable),
..read_enable (read_enable),
..irq_out (irq),
..clk (clk),
..rstn (rstn)
)
// address block decode
assign rom_block_sel = address [15:13] == 3'b111; // top address
assign ram_block_sel = address [15:13] == 3'b000; // bottom address
assign uart_block_sel = address [15:13] == 3'b001;
// read data path mux
always @( * )
begin
case (address[15:13])
3'b000: data_in = ram_data;
3'b001: data_in = uard_data;
3'b111: data_in = rom_data;
default: data_in = 8'h0;
endcase
end
endmodule
Just to follow up, it definitely is because it's being optimised away. If I
add a port which links to a byte of the stack register space, and link it
to the top-level test bench...
module cpu_6502
(
...
output reg [`NW:0] stackff
);
////////////////////////////////////////////////////////////////////////////
// Set up the stack as a register array
////////////////////////////////////////////////////////////////////////////
reg [`NW:0] stack[0:255]; // Stack-page
always @ (posedge(clk))
stackff <= stack[255];
... the report tells me that bits [31:8] of 'newSPData' are optimised away, but bits [7:0]
are not.
Aside: The report is also saying: "INFO: [Synth 8-5545] ROM "stack_reg[255]" won't be
mapped to RAM because address size (32) is larger than maximum supported(25)"
Am I misunderstanding this, or is my declaration wrong ? I'm trying to
declare 256 8-bit (`NW is defined to be 7) registers to represent a single
page (the 6502 uses page-1 as a stack, so its stack pointer is only 8-bits in size).
256 bytes ought to fit into a 4K-byte block-ram...
Cheers
Simon.
I am not clear what you are trying to do with the stack here. Do you
have a relatively complete CPU implemented?
I would expect something like:
module CPU6502
(
output wire [ 7:0] data_out,
output wire [15:0] address_out,
input wire [ 7:0] data_in,
output wire write_enable,
output wire read_enable,
input wire irq_in,
input wire nmi_in,
input wire clk,
input wire rstn
)
I would expect that you would have an 8 bit stack pointer that would get
muxed onto the address bus, possibly with offsets from the instruction
stream. The newSP value would go into the stack pointer when you are
updating the stack.
RAM would get hung on the address and data buses with block decode logic
to decode the upper address bits into a chip select for the RAM and
peripherals. Since FPGA's don't do tri-state buses, there will be a read
data in mux to select the data source from the addressed bus target for
reads.
sort of like:
module mcu
(
output uart_txd,
input uart_rxd,
input clk,
input rstn
)
wire [15:0] address;
wire [ 7:0] data_out;
wire [ 7:0] ram_data, rom_data, uart_data;
reg [ 7:0] data_in;
wire ram_block_sel, rom_block_sel, uart_block_sel;
wire write_enable, read_enable;
CPU6502 cpu
(
.data_out (data_out),
.data_in (data_in),
.address_out (address),
.write_enable (write_enable),
.read_enable (read_enable),
.irq_in (irq),
.nmi_in (1'b0),
.clk (clk),
.rstn (rstn)
);
RAM_1Kx8 ram
(
.address_in (address[9:0]),
.data_in (data_out),
.data_out (ram_data),
.write_enable (write_enable),
.chip_sel (ram_block_sel)
);
ROM_1Kx8 rom
(
..address_in (address[9:0]),
..data_out (rom_data),
..read_enable (read_enable),
..chip_sel (rom_block_sel)
);
UART uart
(
..txd (uart_txd),
..rxd (uart_rxd),
..reg_select (address[1:0]), // 2 bits of address
..data_in (data_out),
..data_out (uart_data),
..write_enable (write_enable),
..read_enable (read_enable),
..irq_out (irq),
..clk (clk),
..rstn (rstn)
)
// address block decode
assign rom_block_sel = address [15:13] == 3'b111; // top address
assign ram_block_sel = address [15:13] == 3'b000; // bottom address
assign uart_block_sel = address [15:13] == 3'b001;
// read data path mux
always @( * )
begin
case (address[15:13])
3'b000: data_in = ram_data;
3'b001: data_in = uard_data;
3'b111: data_in = rom_data;
default: data_in = 8'h0;
endcase
end
endmodule