mirror of
https://github.com/mopfel-winrux/NockPU.git
synced 2024-10-06 01:37:16 +03:00
commit
dd4bd97213
@ -7,12 +7,12 @@ module execute_tb();
|
||||
//Test Parameters
|
||||
//parameter MEM_INIT_FILE = "./memory/slot_tb.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/inc_slot.hex";
|
||||
parameter MEM_INIT_FILE = "./memory/evaluate.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/evaluate.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/evaluate2.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/evaluate3.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/cell_tb.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/constant_tb.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/nested_increment.hex";
|
||||
parameter MEM_INIT_FILE = "./memory/nested_increment.hex";
|
||||
//parameter MEM_INIT_FILE = "./memory/increment.hex";
|
||||
|
||||
//Signal Declarations
|
||||
@ -67,7 +67,7 @@ wire [`tag_width - 1:0] error;
|
||||
wire [3:0] execute_return_sys_func;
|
||||
wire [3:0] execute_return_state;
|
||||
|
||||
// Instantiate Memory Unit
|
||||
// Instantiate Memory Unit
|
||||
memory_unit mem(.func (mem_func),
|
||||
.execute (mem_execute),
|
||||
.address (address),
|
||||
@ -112,67 +112,65 @@ mem_traversal traversal(.power (power),
|
||||
.finished(traversal_finished),
|
||||
.error(error),
|
||||
.mux_controller(select),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.execute_finished(execute_finished),
|
||||
.execute_return_sys_func(execute_return_sys_func),
|
||||
.execute_return_state(execute_return_state));
|
||||
|
||||
//Instantiate Nock Execute Module
|
||||
execute execute(.clk(clk),
|
||||
.rst(reset),
|
||||
.error(error),
|
||||
.execute_start(select),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.rst(reset),
|
||||
.error(error),
|
||||
.execute_start(select),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.mem_ready(mem_ready),
|
||||
.mem_execute(mem_execute_nem),
|
||||
.mem_func(mem_func_nem),
|
||||
.address(address_nem),
|
||||
.free_addr(free_addr),
|
||||
.mem_execute(mem_execute_nem),
|
||||
.mem_func(mem_func_nem),
|
||||
.address(address_nem),
|
||||
.free_addr(free_addr),
|
||||
.read_data(read_data),
|
||||
.write_data(write_data_nem),
|
||||
.write_data(write_data_nem),
|
||||
.finished(execute_finished),
|
||||
.execute_return_sys_func(execute_return_sys_func),
|
||||
.execute_return_state(execute_return_state));
|
||||
|
||||
// Setup Clock
|
||||
initial begin
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
end
|
||||
|
||||
integer idx;
|
||||
|
||||
// Perform Test
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
$dumpfile("waveform.vcd");
|
||||
$dumpvars(0, execute_tb);
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
$dumpfile("waveform.vcd");
|
||||
$dumpvars(0, execute_tb);
|
||||
|
||||
for (idx = 0; idx < 1023; idx = idx+1) begin
|
||||
$dumpvars(0,mem.ram.ram[idx]);
|
||||
end
|
||||
for (idx = 0; idx < 1023; idx = idx+1) begin
|
||||
$dumpvars(0,mem.ram.ram[idx]);
|
||||
end
|
||||
|
||||
start_addr = 1;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
traversal_execute = 1;
|
||||
|
||||
start_addr = 1;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
wait (traversal_finished == 1'b1);
|
||||
repeat (2) @(posedge clk);
|
||||
|
||||
traversal_execute = 1;
|
||||
|
||||
wait (traversal_finished == 1'b1);
|
||||
repeat (2) @(posedge clk);
|
||||
|
||||
$stop;
|
||||
$stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -36,8 +36,8 @@ wire traversal_finished;
|
||||
|
||||
reg [`memory_addr_width - 1:0] start_addr;
|
||||
|
||||
|
||||
// Instantiate MTU
|
||||
|
||||
// Instantiate MTU
|
||||
memory_unit mem(.func (mem_func),
|
||||
.execute (mem_execute),
|
||||
.address (address),
|
||||
@ -51,50 +51,48 @@ memory_unit mem(.func (mem_func),
|
||||
.mem_data_out(mem_data_out),
|
||||
.rst (reset));
|
||||
|
||||
mem_traversal traversal(.power (power),
|
||||
.clk (clk),
|
||||
.rst (reset),
|
||||
.start_addr (start_addr),
|
||||
.execute (traversal_execute),
|
||||
.mem_ready (mem_ready),
|
||||
.address(address),
|
||||
.read_data (read_data),
|
||||
.mem_execute (mem_execute),
|
||||
.mem_func (mem_func),
|
||||
.free_addr (free_addr),
|
||||
.write_data (write_data),
|
||||
.finished(traversal_finished),
|
||||
.error(),
|
||||
.mux_controller());
|
||||
mem_traversal traversal(.power (power),
|
||||
.clk (clk),
|
||||
.rst (reset),
|
||||
.start_addr (start_addr),
|
||||
.execute (traversal_execute),
|
||||
.mem_ready (mem_ready),
|
||||
.address(address),
|
||||
.read_data (read_data),
|
||||
.mem_execute (mem_execute),
|
||||
.mem_func (mem_func),
|
||||
.free_addr (free_addr),
|
||||
.write_data (write_data),
|
||||
.finished(traversal_finished),
|
||||
.error(),
|
||||
.mux_controller());
|
||||
|
||||
// Setup Clock
|
||||
initial begin
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
end
|
||||
|
||||
|
||||
// Perform Test
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
|
||||
start_addr = 1;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
start_addr = 1;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
traversal_execute = 1;
|
||||
traversal_execute = 1;
|
||||
|
||||
wait (traversal_finished == 1'b1);
|
||||
repeat (2) @(posedge clk);
|
||||
wait (traversal_finished == 1'b1);
|
||||
repeat (2) @(posedge clk);
|
||||
|
||||
|
||||
|
||||
$stop;
|
||||
$stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -37,7 +37,7 @@ wire mem_ready;
|
||||
wire [3:0] state;
|
||||
|
||||
|
||||
// Instantiate Memory Unit
|
||||
// Instantiate Memory Unit
|
||||
memory_unit mem(.func (mem_func),
|
||||
.execute (mem_execute),
|
||||
.address (addr),
|
||||
@ -53,85 +53,85 @@ memory_unit mem(.func (mem_func),
|
||||
|
||||
// Setup Clock
|
||||
initial begin
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
MAX10_CLK1_50 =0;
|
||||
forever MAX10_CLK1_50 = #10 ~MAX10_CLK1_50;
|
||||
end
|
||||
|
||||
integer idx;
|
||||
|
||||
// Perform Test
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
$dumpfile("memory_unit_tb.vcd");
|
||||
$dumpvars(0, memory_unit_tb);
|
||||
initial begin
|
||||
if (MEM_INIT_FILE != "") begin
|
||||
$readmemh(MEM_INIT_FILE, mem.ram.ram);
|
||||
end
|
||||
$dumpfile("memory_unit_tb.vcd");
|
||||
$dumpvars(0, memory_unit_tb);
|
||||
|
||||
for (idx = 0; idx < 1023; idx = idx+1) begin
|
||||
$dumpvars(0,mem.ram.ram[idx]);
|
||||
end
|
||||
for (idx = 0; idx < 1023; idx = idx+1) begin
|
||||
$dumpvars(0,mem.ram.ram[idx]);
|
||||
end
|
||||
|
||||
|
||||
mem_execute = 0;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
mem_execute = 0;
|
||||
// Reset
|
||||
reset = 1'b0;
|
||||
repeat (2) @(posedge clk);
|
||||
reset = 1'b1;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
|
||||
// Get Next Free Memory Location
|
||||
mem_func = `GET_FREE;
|
||||
write_data <= 1;
|
||||
// Get Next Free Memory Location
|
||||
mem_func = `GET_FREE;
|
||||
write_data <= 1;
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
mem_execute = 0;
|
||||
free_addr_reg = free_addr;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
|
||||
|
||||
// Write to Free Addr
|
||||
write_data = MEM_WRITE_DATA;
|
||||
addr = free_addr_reg;
|
||||
mem_func = `SET_CONTENTS;
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
mem_execute = 0;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
|
||||
// Get Next Free Memory Location
|
||||
mem_func = `GET_FREE;
|
||||
write_data <= 4;
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
mem_execute = 0;
|
||||
free_addr_reg = free_addr;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
|
||||
// Begin Read
|
||||
mem_func = `GET_CONTENTS;
|
||||
|
||||
addr = 0;
|
||||
|
||||
while(addr < free_addr_reg +1) begin
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
|
||||
mem_execute = 0;
|
||||
free_addr_reg = free_addr;
|
||||
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
|
||||
|
||||
// Write to Free Addr
|
||||
write_data = MEM_WRITE_DATA;
|
||||
addr = free_addr_reg;
|
||||
mem_func = `SET_CONTENTS;
|
||||
mem_execute = 1;
|
||||
addr = addr +1;
|
||||
repeat (2) @(posedge clk);
|
||||
mem_execute = 0;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
end
|
||||
|
||||
// Get Next Free Memory Location
|
||||
mem_func = `GET_FREE;
|
||||
write_data <= 4;
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
mem_execute = 0;
|
||||
free_addr_reg = free_addr;
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
repeat (1) @(posedge clk);
|
||||
|
||||
// Begin Read
|
||||
mem_func = `GET_CONTENTS;
|
||||
|
||||
addr = 0;
|
||||
|
||||
while(addr < free_addr_reg +1)
|
||||
begin
|
||||
mem_execute = 1;
|
||||
repeat (2) @(posedge clk);
|
||||
|
||||
mem_execute = 0;
|
||||
|
||||
wait (mem_ready == 1'b1);
|
||||
|
||||
addr = addr +1;
|
||||
repeat (2) @(posedge clk);
|
||||
end
|
||||
$stop;
|
||||
$stop;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -59,7 +59,7 @@ wire [7:0] error;
|
||||
wire [3:0] execute_return_sys_func;
|
||||
wire [3:0] execute_return_state;
|
||||
|
||||
// Instantiate Memory Unit
|
||||
// Instantiate Memory Unit
|
||||
memory_unit mem(.func (mem_func),
|
||||
.execute (mem_execute),
|
||||
.address (address),
|
||||
@ -104,9 +104,9 @@ mem_traversal traversal(.power (power),
|
||||
.finished(traversal_finished),
|
||||
.error(error),
|
||||
.mux_controller(select),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.execute_address(execute_address),
|
||||
.execute_tag(execute_tag),
|
||||
.execute_data(execute_data),
|
||||
.execute_finished(execute_finished),
|
||||
.execute_return_sys_func(execute_return_sys_func),
|
||||
.execute_return_state(execute_return_state));
|
||||
@ -131,7 +131,7 @@ execute execute(.clk(clk),
|
||||
.execute_return_state(execute_return_state));
|
||||
|
||||
// Perform Test
|
||||
initial begin
|
||||
initial begin
|
||||
|
||||
start_addr = 1;
|
||||
// Reset
|
||||
|
@ -4,51 +4,34 @@
|
||||
|
||||
|
||||
module execute (
|
||||
clk,
|
||||
rst,
|
||||
error,
|
||||
execute_start,
|
||||
execute_address,
|
||||
execute_tag,
|
||||
execute_data,
|
||||
mem_ready,
|
||||
mem_execute,
|
||||
mem_func,
|
||||
address,
|
||||
free_addr,
|
||||
read_data,
|
||||
write_data,
|
||||
finished,
|
||||
execute_return_sys_func,
|
||||
execute_return_state
|
||||
input clk,
|
||||
input rst,
|
||||
output reg [7:0] error,
|
||||
input execute_start, // wire to begin execution (mux_conroller from traversal)
|
||||
input [`memory_addr_width - 1:0] execute_address,
|
||||
input [`tag_width - 1:0] execute_tag,
|
||||
input [`memory_data_width - 1:0] execute_data,
|
||||
output reg [3:0] execute_return_sys_func,
|
||||
output reg [3:0] execute_return_state,
|
||||
input mem_ready,
|
||||
input [`memory_data_width - 1:0] read_data,
|
||||
input [`memory_addr_width - 1:0] free_addr,
|
||||
output reg mem_execute,
|
||||
output reg [`memory_addr_width - 1:0] address,
|
||||
output reg [`memory_addr_width - 1:0] write_addr_reg,
|
||||
output reg [1:0] mem_func,
|
||||
output reg [`memory_data_width - 1:0] write_data,
|
||||
output wire finished
|
||||
);
|
||||
input clk, rst;
|
||||
output reg [7:0] error;
|
||||
|
||||
reg [7:0] debug_sig;
|
||||
|
||||
// Interface with memory traversal
|
||||
input execute_start; // wire to begin execution (mux_conroller from traversal)
|
||||
reg execute_start_ff;
|
||||
input [`memory_addr_width - 1:0] execute_address;
|
||||
input [`tag_width - 1:0] execute_tag;
|
||||
input [`memory_data_width - 1:0] execute_data;
|
||||
output reg [3:0] execute_return_sys_func;
|
||||
output reg [3:0] execute_return_state;
|
||||
reg is_finished_reg;
|
||||
output wire finished;
|
||||
assign finished = is_finished_reg;
|
||||
|
||||
//Interface with memory unit
|
||||
input mem_ready;
|
||||
input [`memory_data_width - 1:0] read_data;
|
||||
reg [`memory_data_width - 1:0] read_data_reg;
|
||||
input [`memory_addr_width - 1:0] free_addr;
|
||||
|
||||
output reg mem_execute;
|
||||
output reg [`memory_addr_width - 1:0] address;
|
||||
output reg [`memory_addr_width - 1:0] write_addr_reg;
|
||||
output reg [1:0] mem_func;
|
||||
output reg [`memory_data_width - 1:0] write_data;
|
||||
|
||||
//Registers to treat opcodes as "Functions"
|
||||
reg [`noun_width - 1:0] a, opcode, b, c, d;
|
||||
@ -87,30 +70,32 @@ module execute (
|
||||
|
||||
//Execute Functions
|
||||
parameter EXE_FUNC_SLOT = 4'h0,
|
||||
EXE_FUNC_CONSTANT = 4'h1,
|
||||
EXE_FUNC_EVAL = 4'h2,
|
||||
EXE_FUNC_CELL = 4'h3,
|
||||
EXE_FUNC_INCR = 4'h4,
|
||||
EXE_FUNC_EQUAL = 4'h5,
|
||||
EXE_FUNC_IF = 4'h6,
|
||||
EXE_FUNC_COMPOSE = 4'h7,
|
||||
EXE_FUNC_EXTEND = 4'h8,
|
||||
EXE_FUNC_INVOKE = 4'h9,
|
||||
EXE_FUNC_REPLACE = 4'hA,
|
||||
EXE_FUNC_HINT = 4'hB,
|
||||
EXE_FUNC_INIT = 4'hC,
|
||||
EXE_FUNC_STACK = 4'hD,
|
||||
EXE_FUNC_ERROR = 4'hF;
|
||||
EXE_FUNC_CONSTANT = 4'h1,
|
||||
EXE_FUNC_EVAL = 4'h2,
|
||||
EXE_FUNC_CELL = 4'h3,
|
||||
EXE_FUNC_INCR = 4'h4,
|
||||
EXE_FUNC_EQUAL = 4'h5,
|
||||
EXE_FUNC_IF = 4'h6,
|
||||
EXE_FUNC_COMPOSE = 4'h7,
|
||||
EXE_FUNC_EXTEND = 4'h8,
|
||||
EXE_FUNC_INVOKE = 4'h9,
|
||||
EXE_FUNC_REPLACE = 4'hA,
|
||||
EXE_FUNC_HINT = 4'hB,
|
||||
EXE_FUNC_INIT = 4'hC,
|
||||
EXE_FUNC_STACK = 4'hD,
|
||||
EXE_FUNC_ERROR = 4'hF;
|
||||
|
||||
// slot states
|
||||
parameter EXE_SLOT_INIT = 4'h0,
|
||||
EXE_SLOT_PREP = 4'h1,
|
||||
EXE_SLOT_CHECK = 4'h2,
|
||||
EXE_SLOT_DONE = 4'h3,
|
||||
EXE_SLOT_CELL_OF_NIL = 4'h4;
|
||||
parameter EXE_SLOT_INIT = 4'h0,
|
||||
EXE_SLOT_PREP = 4'h1,
|
||||
EXE_SLOT_CHECK = 4'h2,
|
||||
EXE_SLOT_DONE = 4'h3,
|
||||
EXE_SLOT_CELL_OF_NIL = 4'h4;
|
||||
|
||||
// Constant states
|
||||
parameter EXE_CONSTANT_INIT = 4'h0, EXE_CONSTANT_READ_B = 4'h1, EXE_CONSTANT_WRITE_WAIT = 4'h2;
|
||||
parameter EXE_CONSTANT_INIT = 4'h0,
|
||||
EXE_CONSTANT_READ_B = 4'h1,
|
||||
EXE_CONSTANT_WRITE_WAIT = 4'h2;
|
||||
|
||||
//eval states
|
||||
parameter EXE_EVAL_INIT = 4'h0,
|
||||
@ -120,10 +105,14 @@ module execute (
|
||||
EXE_EVAL_DONE = 4'h4;
|
||||
|
||||
//cell states
|
||||
parameter EXE_CELL_INIT = 4'h0, EXE_CELL_CHECK = 4'h1, EXE_CELL_WRITE_WAIT = 4'h2;
|
||||
parameter EXE_CELL_INIT = 4'h0,
|
||||
EXE_CELL_CHECK = 4'h1,
|
||||
EXE_CELL_WRITE_WAIT = 4'h2;
|
||||
|
||||
//increment states
|
||||
parameter EXE_INCR_INIT = 4'h0, EXE_INCR_A = 4'h1, EXE_INCR_WAIT = 4'h2;
|
||||
parameter EXE_INCR_INIT = 4'h0,
|
||||
EXE_INCR_A = 4'h1,
|
||||
EXE_INCR_WAIT = 4'h2;
|
||||
|
||||
//equal states
|
||||
parameter EXE_EQUAL_INIT = 4'h0;
|
||||
@ -151,23 +140,23 @@ module execute (
|
||||
|
||||
// Init States
|
||||
parameter EXE_INIT_INIT = 4'h0,
|
||||
EXE_INIT_READ_TEL = 4'h1,
|
||||
EXE_INIT_DECODE = 4'h2,
|
||||
EXE_INIT_WRIT_TEL = 4'h3,
|
||||
EXE_INIT_FINISHED = 4'hF;
|
||||
EXE_INIT_READ_TEL = 4'h1,
|
||||
EXE_INIT_DECODE = 4'h2,
|
||||
EXE_INIT_WRIT_TEL = 4'h3,
|
||||
EXE_INIT_FINISHED = 4'hF;
|
||||
|
||||
//Stacking States
|
||||
parameter EXE_STACK_INIT = 4'h0,
|
||||
EXE_STACK_READ_WAIT = 4'h1,
|
||||
EXE_STACK_READ_WAIT_2 = 4'h2,
|
||||
EXE_STACK_WRITE_WAIT = 4'h3,
|
||||
EXE_STACK_CHECK_NEXT = 4'h4,
|
||||
EXE_STACK_CHECK_WAIT = 4'h5,
|
||||
EXE_STACK_POP = 4'h6,
|
||||
EXE_STACK_POP_READ = 4'h7,
|
||||
EXE_STACK_POP_WAIT = 4'h8,
|
||||
EXE_STACK_POP_ERR = 4'h9;
|
||||
|
||||
EXE_STACK_READ_WAIT = 4'h1,
|
||||
EXE_STACK_READ_WAIT_2 = 4'h2,
|
||||
EXE_STACK_WRITE_WAIT = 4'h3,
|
||||
EXE_STACK_CHECK_NEXT = 4'h4,
|
||||
EXE_STACK_CHECK_WAIT = 4'h5,
|
||||
EXE_STACK_POP = 4'h6,
|
||||
EXE_STACK_POP_READ = 4'h7,
|
||||
EXE_STACK_POP_WAIT = 4'h8,
|
||||
EXE_STACK_POP_ERR = 4'h9;
|
||||
|
||||
always @(posedge clk) begin
|
||||
// Flip-flop to store the previous state of execute_start
|
||||
execute_start_ff <= execute_start;
|
||||
@ -188,14 +177,15 @@ module execute (
|
||||
mem_execute<=0;
|
||||
debug_sig <= 0;
|
||||
address <=0;
|
||||
end else if (execute_start) begin
|
||||
end
|
||||
else if (execute_start) begin
|
||||
case (exec_func)
|
||||
EXE_FUNC_INIT: begin
|
||||
case (state)
|
||||
EXE_INIT_INIT: begin
|
||||
is_finished_reg <=0;
|
||||
if (execute_start) begin
|
||||
if (execute_tag[0] == 1) begin
|
||||
if (execute_tag[0] == `ATOM) begin
|
||||
error <= `ERROR_TEL_NOT_CELL;
|
||||
state <= EXE_ERROR_INIT;
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
@ -206,8 +196,6 @@ module execute (
|
||||
execute_address_reg <= execute_address;
|
||||
trav_P <= execute_address;
|
||||
|
||||
b<= 16'hDEAD;
|
||||
|
||||
a <= execute_data[`hed_start:`hed_end];
|
||||
|
||||
address <= execute_data[`tel_start:`tel_end];
|
||||
@ -240,11 +228,9 @@ module execute (
|
||||
|
||||
end else begin
|
||||
mem_data <= read_data;
|
||||
mem_tag <= read_data[`tag_start:`tag_end]; // read first 4 bits and store into tag for easier access
|
||||
|
||||
mem_tag <= read_data[`tag_start:`tag_end];
|
||||
opcode <= read_data[`hed_start:`hed_end];
|
||||
b <= read_data[`tel_start:`tel_end];
|
||||
|
||||
state <= EXE_INIT_DECODE;
|
||||
end
|
||||
end else begin
|
||||
@ -253,17 +239,15 @@ module execute (
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
EXE_INIT_WRIT_TEL: begin
|
||||
if (mem_ready) begin
|
||||
write_addr_reg <= execute_address;
|
||||
mem_execute <= 1;
|
||||
write_data <= {execute_data[`tag_start:`tag_end],
|
||||
execute_data[`hed_start:`hed_end],
|
||||
18'b0,address};//data[`tel_start:`tel_end]};
|
||||
18'b0,address};
|
||||
address <= execute_address;
|
||||
mem_func <= `SET_CONTENTS;
|
||||
|
||||
mem_execute <= 1;
|
||||
state <= EXE_INIT_READ_TEL;
|
||||
end else begin
|
||||
@ -275,14 +259,12 @@ module execute (
|
||||
EXE_INIT_DECODE: begin
|
||||
if ((opcode < 0) || (opcode > 11)) begin //If invalid opcode
|
||||
error <= `ERROR_INVALID_OPCODE;
|
||||
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
state <= EXE_ERROR_INIT;
|
||||
|
||||
end else begin
|
||||
case (opcode)
|
||||
`slot: begin
|
||||
if (mem_tag[1] == 1) begin // if b is an atom
|
||||
if (mem_tag[1] == `ATOM) begin // if b is an atom
|
||||
stack_P <= trav_P;
|
||||
exec_func <= EXE_FUNC_SLOT;
|
||||
state <= EXE_SLOT_INIT;
|
||||
@ -426,7 +408,6 @@ module execute (
|
||||
|
||||
EXE_SLOT_CELL_OF_NIL: begin
|
||||
if (mem_ready) begin
|
||||
debug_sig <= 6;
|
||||
state <= EXE_SLOT_DONE;
|
||||
mem_func <= `SET_CONTENTS;
|
||||
address <= func_addr;
|
||||
@ -459,8 +440,6 @@ module execute (
|
||||
EXE_SLOT_CHECK: begin
|
||||
if (mem_ready) begin
|
||||
if ( b == 28'h8000000) begin
|
||||
debug_sig <= 5;
|
||||
|
||||
// need to do check to make sure the cell isn't [atom NIL]
|
||||
if(subject_tag == `CELL) begin
|
||||
state <= EXE_SLOT_CELL_OF_NIL;
|
||||
@ -479,17 +458,15 @@ module execute (
|
||||
1'b1,
|
||||
subject,
|
||||
`NIL};
|
||||
//1'b0,
|
||||
//read_data[62:0]};
|
||||
state <= EXE_SLOT_DONE;
|
||||
a<=1;
|
||||
end
|
||||
end
|
||||
end
|
||||
else if (execute_data[`hed_tag] == `ATOM) begin
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
state <= EXE_ERROR_INIT;
|
||||
error <= `ERROR_INVALID_SLOT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if (b[`noun_width-1] == 0) begin
|
||||
if(read_data[`hed_tag] == `CELL) begin
|
||||
@ -511,7 +488,6 @@ module execute (
|
||||
1'b1,
|
||||
read_data[`hed_start:`hed_end],
|
||||
`NIL};
|
||||
//28'h0000};
|
||||
state <= EXE_SLOT_DONE;
|
||||
end else begin
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
@ -538,7 +514,6 @@ module execute (
|
||||
1'b1,
|
||||
read_data[`tel_start:`tel_end],
|
||||
`NIL};
|
||||
//28'h0000};
|
||||
state <= EXE_SLOT_DONE;
|
||||
end else begin
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
@ -602,7 +577,6 @@ module execute (
|
||||
1'b1,
|
||||
read_data_reg[`tel_start:`tel_end],
|
||||
`NIL};
|
||||
//write_data <= read_data_reg;
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
@ -643,7 +617,6 @@ module execute (
|
||||
execute_data[`tel_tag],
|
||||
read_data[`tel_start:`tel_end],
|
||||
execute_data[`tel_start:`tel_end]};
|
||||
|
||||
end
|
||||
|
||||
EXE_EVAL_READ_TEL_TEL: begin
|
||||
@ -669,7 +642,6 @@ module execute (
|
||||
read_data[`hed_tag],
|
||||
subject,
|
||||
read_data[`hed_start:`hed_end]};
|
||||
|
||||
state <= EXE_EVAL_WRIT_2_EXE;
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
@ -784,11 +756,9 @@ module execute (
|
||||
mem_execute <= 1;
|
||||
write_data <= {6'b000000,
|
||||
read_data[`hed_tag],
|
||||
1'b1,
|
||||
1'b1,
|
||||
read_data[`hed_start:`hed_end] + 28'h1,
|
||||
`NIL};
|
||||
//exec_func <= func_return_exec_func;
|
||||
//state <= func_return_state;
|
||||
state <= EXE_INCR_WAIT;
|
||||
end
|
||||
end else begin
|
||||
@ -875,7 +845,6 @@ module execute (
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= EXE_STACK_READ_WAIT_2;
|
||||
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
@ -924,10 +893,7 @@ module execute (
|
||||
mem_execute <= 1;
|
||||
state <= EXE_STACK_CHECK_NEXT;
|
||||
trav_B <= trav_P;
|
||||
|
||||
|
||||
end else begin
|
||||
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
@ -939,7 +905,6 @@ module execute (
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= EXE_STACK_CHECK_WAIT;
|
||||
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
@ -948,7 +913,9 @@ module execute (
|
||||
|
||||
EXE_STACK_CHECK_WAIT: begin //D5
|
||||
if (mem_ready) begin
|
||||
if((read_data[`hed_start:`hed_end] < 0) || (read_data[`hed_start:`hed_end] > 11)) begin //If invalid opcode
|
||||
//If invalid opcode
|
||||
if((read_data[`hed_start:`hed_end] < 0) ||
|
||||
(read_data[`hed_start:`hed_end] > 11)) begin
|
||||
error <= `ERROR_INVALID_OPCODE;
|
||||
exec_func <= EXE_FUNC_ERROR;
|
||||
state <= EXE_ERROR_INIT;
|
||||
@ -956,24 +923,18 @@ module execute (
|
||||
exec_func <= EXE_FUNC_SLOT;
|
||||
state <= EXE_SLOT_INIT;
|
||||
a <= stack_a;
|
||||
|
||||
b <= read_data[`tel_start:`tel_end];
|
||||
|
||||
func_addr <= address;
|
||||
trav_P <= stack_P_tel;
|
||||
|
||||
func_return_exec_func <= EXE_FUNC_STACK;
|
||||
func_return_state <= EXE_STACK_POP;
|
||||
end else if (read_data[`hed_start:`hed_end] == `constant) begin
|
||||
exec_func <= EXE_FUNC_CONSTANT;
|
||||
state <= EXE_CONSTANT_INIT;
|
||||
a <= stack_a;
|
||||
|
||||
b <= read_data[`tel_start:`tel_end];
|
||||
|
||||
func_addr <= stack_P_tel;
|
||||
trav_P <= stack_P_tel;
|
||||
|
||||
func_return_exec_func <= EXE_FUNC_STACK;
|
||||
func_return_state <= EXE_STACK_POP;
|
||||
end else begin
|
||||
@ -1002,7 +963,6 @@ module execute (
|
||||
EXE_STACK_POP_READ: begin //D7
|
||||
if (mem_ready) begin
|
||||
a <= read_data[`hed_start:`hed_end];
|
||||
|
||||
address <= trav_B;
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
@ -1018,8 +978,8 @@ module execute (
|
||||
opcode <= read_data[`hed_start:`hed_end];
|
||||
trav_B <= read_data[`tel_start:`tel_end];
|
||||
func_addr <= trav_B;
|
||||
|
||||
if(read_data[`tel_end+9:`tel_end] == 1023) begin // mem_addr is only max when you reach the end and use trav_b's inital value
|
||||
if(read_data[`tel_end+9:`tel_end] == 1023) begin
|
||||
// mem_addr is only max when you reach the end and use trav_b's inital value
|
||||
func_return_exec_func <= EXE_FUNC_INIT;
|
||||
func_return_state <= EXE_INIT_FINISHED;
|
||||
end else begin
|
||||
@ -1027,52 +987,15 @@ module execute (
|
||||
func_return_state <= EXE_STACK_POP;
|
||||
end
|
||||
|
||||
if(read_data[`tel_start:`tel_end] == `NIL && read_data[`tel_tag] == `ATOM) begin
|
||||
if(read_data[`tel_start:`tel_end] == `NIL &&
|
||||
read_data[`tel_tag] == `ATOM) begin
|
||||
exec_func <= EXE_FUNC_INIT;
|
||||
state <= EXE_INIT_FINISHED;
|
||||
end else begin
|
||||
|
||||
case (read_data[`hed_start:`hed_end])
|
||||
`slot: begin
|
||||
end
|
||||
|
||||
`constant: begin
|
||||
end
|
||||
|
||||
`evaluate: begin
|
||||
end
|
||||
|
||||
`cell: begin
|
||||
exec_func <= EXE_FUNC_CELL;
|
||||
state <= EXE_CELL_INIT;
|
||||
end
|
||||
|
||||
`increment: begin
|
||||
exec_func <= EXE_FUNC_INCR;
|
||||
state <= EXE_INCR_INIT;
|
||||
end
|
||||
|
||||
`equality: begin
|
||||
end
|
||||
|
||||
`if_then_else: begin
|
||||
end
|
||||
|
||||
`compose: begin
|
||||
end
|
||||
|
||||
`extend: begin
|
||||
end
|
||||
|
||||
`invoke: begin
|
||||
end
|
||||
|
||||
`replace: begin
|
||||
end
|
||||
|
||||
`hint: begin
|
||||
end
|
||||
endcase
|
||||
// THis only works because the exec_functions are defined as
|
||||
// the same numer as an opcode
|
||||
exec_func <= read_data[`hed_start:`hed_end];
|
||||
state <= 0;
|
||||
end
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
|
@ -3,507 +3,444 @@
|
||||
`include "execute.vh"
|
||||
|
||||
|
||||
module mem_traversal(power, clk, rst, start_addr, execute,
|
||||
mem_ready, address, read_data, mem_execute, mem_func, free_addr, write_data,
|
||||
finished, error, mux_controller, execute_address, execute_tag, execute_data, execute_finished, execute_return_sys_func, execute_return_state);
|
||||
input power, clk, rst;
|
||||
input [`memory_addr_width - 1:0] start_addr; //Address to start traversal at
|
||||
input execute; // wire to begin traversal
|
||||
reg is_finished_reg;
|
||||
output wire finished;
|
||||
assign finished = is_finished_reg;
|
||||
module mem_traversal(
|
||||
input power, clk, rst,
|
||||
input [`memory_addr_width - 1:0] start_addr,
|
||||
input execute,
|
||||
output wire finished,
|
||||
input mem_ready,
|
||||
input [`memory_data_width - 1:0] read_data,
|
||||
input [`memory_addr_width - 1:0] free_addr,
|
||||
output reg mem_execute,
|
||||
output reg [`memory_addr_width - 1:0] address,
|
||||
output reg [1:0] mem_func,
|
||||
output reg [`memory_data_width - 1:0] write_data,
|
||||
input [7:0] error,
|
||||
output reg [`memory_addr_width - 1:0] execute_address,
|
||||
output reg [`tag_width - 1:0] execute_tag,
|
||||
output reg [`memory_data_width - 1:0] execute_data,
|
||||
output reg mux_controller,
|
||||
input execute_finished,
|
||||
input [3:0] execute_return_sys_func,
|
||||
input [3:0] execute_return_state
|
||||
);
|
||||
// finish signal
|
||||
reg is_finished_reg;
|
||||
assign finished = is_finished_reg;
|
||||
|
||||
//Interface with memory unit
|
||||
input mem_ready;
|
||||
input [`memory_data_width - 1:0] read_data;
|
||||
input [`memory_addr_width - 1:0] free_addr; // Not sure if needed
|
||||
// Internal registers needed
|
||||
reg [3:0] sys_func;
|
||||
reg [3:0] state;
|
||||
reg [`tag_width - 1:0] mem_tag;
|
||||
reg [`noun_width - 1:0] hed, tel;
|
||||
reg [`memory_addr_width - 1:0] mem_addr;
|
||||
reg [`memory_data_width - 1:0] mem_data;
|
||||
reg [7:0] debug_sig;
|
||||
wire is_running;
|
||||
assign is_running = !finished && execute;
|
||||
|
||||
output reg mem_execute;
|
||||
output reg [`memory_addr_width - 1:0] address;
|
||||
output reg [1:0] mem_func;
|
||||
output reg [`memory_data_width - 1:0] write_data; // Not sure if needed
|
||||
|
||||
// Internal registers needed
|
||||
reg [3:0] sys_func;
|
||||
reg [3:0] state;
|
||||
reg [`tag_width - 1:0] mem_tag;
|
||||
reg [`noun_width - 1:0] hed, tel;
|
||||
reg [`memory_addr_width - 1:0] mem_addr;
|
||||
reg [`memory_data_width - 1:0] mem_data;
|
||||
reg [7:0] debug_sig;
|
||||
wire is_running;
|
||||
assign is_running = !finished && execute;
|
||||
input [7:0] error;
|
||||
// General Purpose Regsiters
|
||||
reg [`memory_addr_width - 1:0] address_gp;
|
||||
reg [`memory_data_width - 1:0] mem_data_gp;
|
||||
reg [`noun_width - 1:0] noun_gp;
|
||||
reg [`noun_tag_width - 1:0] noun_tag_gp;
|
||||
|
||||
// Execute Registers needed
|
||||
output reg [`memory_addr_width - 1:0] execute_address;
|
||||
output reg [`tag_width - 1:0] execute_tag;
|
||||
output reg [`memory_data_width - 1:0] execute_data;
|
||||
output reg mux_controller;
|
||||
input execute_finished;
|
||||
input [3:0] execute_return_sys_func;
|
||||
input [3:0] execute_return_state;
|
||||
// Traversal Registers needed
|
||||
reg [`noun_width - 1:0] trav_P;
|
||||
reg [`noun_width - 1:0] trav_B;
|
||||
|
||||
// General Purpose Regsiters
|
||||
output reg [`memory_addr_width - 1:0] address_gp;
|
||||
output reg [`memory_data_width - 1:0] mem_data_gp;
|
||||
output reg [`noun_width - 1:0] noun_gp;
|
||||
output reg [`noun_tag_width - 1:0] noun_tag_gp;
|
||||
// [[50 51] [2 [0 3] [1 [4 0 1]]]]
|
||||
// Write Registers needed
|
||||
reg [3:0] write_return_sys_func;
|
||||
reg [3:0] write_return_state;
|
||||
|
||||
//System Level Functions
|
||||
parameter SYS_FUNC_READ = 4'h0,
|
||||
SYS_FUNC_WRITE = 4'h1,
|
||||
SYS_FUNC_TRAVERSE = 4'h2,
|
||||
SYS_FUNC_EXECUTE = 4'h3;
|
||||
|
||||
// Traversal Registers needed
|
||||
reg [`noun_width - 1:0] trav_P;
|
||||
reg [`noun_width - 1:0] trav_B;
|
||||
// Read States
|
||||
parameter SYS_READ_INIT = 4'h0,
|
||||
SYS_READ_WAIT = 4'h1,
|
||||
SYS_READ_DECODE = 4'h2;
|
||||
|
||||
// Write Registers needed
|
||||
reg [3:0] write_return_sys_func;
|
||||
reg [3:0] write_return_state;
|
||||
|
||||
//System Level Functions
|
||||
parameter SYS_FUNC_READ = 4'h0,
|
||||
SYS_FUNC_WRITE = 4'h1,
|
||||
SYS_FUNC_TRAVERSE = 4'h2,
|
||||
SYS_FUNC_EXECUTE = 4'h3;
|
||||
|
||||
// Read States
|
||||
parameter SYS_READ_INIT = 4'h0,
|
||||
SYS_READ_WAIT = 4'h1,
|
||||
SYS_READ_DECODE = 4'h2;
|
||||
|
||||
// Write States
|
||||
parameter SYS_WRITE_INIT = 4'h0,
|
||||
SYS_WRITE_WAIT = 4'h1;
|
||||
|
||||
// Traverse States
|
||||
parameter SYS_TRAVERSE_INIT = 4'h0,
|
||||
SYS_TRAVERSE_PUSH = 4'h1,
|
||||
SYS_TRAVERSE_POP = 4'h2,
|
||||
SYS_TRAVERSE_TEL = 4'h3;
|
||||
|
||||
// Execute States
|
||||
parameter SYS_EXECUTE_INIT = 4'h0,
|
||||
SYS_EXECUTE_READ_HED = 4'h1,
|
||||
SYS_EXECUTE_READ_TEL = 4'h2,
|
||||
SYS_EXECUTE_WAIT = 4'h3,
|
||||
SYS_EXECUTE_DECODE = 4'h4,
|
||||
SYS_EXECUTE_READ_ADDR = 4'h5,
|
||||
SYS_EXECUTE_ERROR = 4'hF;
|
||||
|
||||
always@(posedge clk or negedge rst) begin
|
||||
if(!rst) begin
|
||||
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
mem_addr <= start_addr;
|
||||
trav_B <= `NIL;
|
||||
trav_P <= start_addr;
|
||||
mem_execute <= 0;
|
||||
debug_sig <= 0;
|
||||
mux_controller <= 0;
|
||||
|
||||
end
|
||||
else if (execute) begin
|
||||
case (sys_func)
|
||||
// Write States
|
||||
parameter SYS_WRITE_INIT = 4'h0,
|
||||
SYS_WRITE_WAIT = 4'h1;
|
||||
|
||||
SYS_FUNC_EXECUTE: begin
|
||||
case(state)
|
||||
SYS_EXECUTE_INIT: begin
|
||||
if(read_data[`hed_tag] == `CELL) begin
|
||||
//Read head and check if it is execute
|
||||
mem_data_gp <= read_data;
|
||||
address <= read_data[`hed_start:`hed_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_HED;
|
||||
// Traverse States
|
||||
parameter SYS_TRAVERSE_INIT = 4'h0,
|
||||
SYS_TRAVERSE_PUSH = 4'h1,
|
||||
SYS_TRAVERSE_POP = 4'h2,
|
||||
SYS_TRAVERSE_TEL = 4'h3;
|
||||
|
||||
end else if (read_data[`tel_tag] == `CELL) begin
|
||||
//Read head and check if it is execute
|
||||
mem_data_gp <= read_data;
|
||||
address <= read_data[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_TEL;
|
||||
end
|
||||
else begin
|
||||
address <= mem_data[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= mem_data;
|
||||
execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
debug_sig <= 3;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
// Execute States
|
||||
parameter SYS_EXECUTE_INIT = 4'h0,
|
||||
SYS_EXECUTE_READ_HED = 4'h1,
|
||||
SYS_EXECUTE_READ_TEL = 4'h2,
|
||||
SYS_EXECUTE_WAIT = 4'h3,
|
||||
SYS_EXECUTE_DECODE = 4'h4,
|
||||
SYS_EXECUTE_READ_ADDR = 4'h5,
|
||||
SYS_EXECUTE_ERROR = 4'hF;
|
||||
|
||||
always@(posedge clk or negedge rst) begin
|
||||
if(!rst) begin
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
mem_addr <= start_addr;
|
||||
trav_B <= `NIL;
|
||||
trav_P <= start_addr;
|
||||
mem_execute <= 0;
|
||||
debug_sig <= 0;
|
||||
mux_controller <= 0;
|
||||
end
|
||||
else if (execute) begin
|
||||
case (sys_func)
|
||||
SYS_FUNC_EXECUTE: begin
|
||||
case(state)
|
||||
SYS_EXECUTE_INIT: begin
|
||||
if(read_data[`hed_tag] == `CELL) begin
|
||||
//Read head and check if it is execute
|
||||
mem_data_gp <= read_data;
|
||||
address <= read_data[`hed_start:`hed_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_HED;
|
||||
end else if (read_data[`tel_tag] == `CELL) begin
|
||||
//Read head and check if it is execute
|
||||
mem_data_gp <= read_data;
|
||||
address <= read_data[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_TEL;
|
||||
end
|
||||
else begin
|
||||
address <= mem_data[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= mem_data;
|
||||
execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
debug_sig <= 3;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_HED: begin
|
||||
if(mem_ready) begin
|
||||
if(read_data[`execute_bit]==1) begin
|
||||
// If we need to execute the hed
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end
|
||||
else if (mem_data_gp[`tel_tag]==`CELL) begin
|
||||
// if the tel of the parent is a cell
|
||||
mem_data_gp <= read_data;
|
||||
address <= mem_data_gp[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_TEL;
|
||||
end
|
||||
else begin
|
||||
// if not executing hed and parent then pass data to
|
||||
// the execute block
|
||||
address <= mem_data_gp[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= mem_data;
|
||||
execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
debug_sig <= 2;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_TEL: begin
|
||||
if(mem_ready) begin
|
||||
if(read_data[`execute_bit]==1) begin
|
||||
// If we need to execute the tel
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end
|
||||
else begin
|
||||
// if not executing hed and parent then pass data to
|
||||
// the execute block
|
||||
if(trav_B != `NIL) mem_addr <= trav_B;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= {mem_tag,hed,tel};
|
||||
execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_ADDR: begin
|
||||
if(mem_ready) begin
|
||||
if(trav_B != `NIL) mem_addr <= trav_B;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= {mem_tag,hed,tel};//read_data;
|
||||
execute_tag <= mem_tag;//read_data[`tag_start:`tag_end];
|
||||
mux_controller <= 1;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_WAIT: begin
|
||||
if(execute_finished) begin
|
||||
sys_func = execute_return_sys_func;
|
||||
state = execute_return_state;
|
||||
mux_controller <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_ERROR: begin
|
||||
state <= SYS_EXECUTE_ERROR;
|
||||
is_finished_reg <= 1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
SYS_FUNC_READ: begin
|
||||
case(state)
|
||||
SYS_READ_INIT: begin
|
||||
// mem_addr is only max when you reach the end and use
|
||||
// trav_b's inital value
|
||||
if(mem_addr == 1023) begin
|
||||
is_finished_reg <= 1;
|
||||
end
|
||||
else begin
|
||||
is_finished_reg <= 0;
|
||||
address <= mem_addr;
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_READ_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_READ_WAIT: begin
|
||||
if(mem_ready) begin
|
||||
mem_data <= read_data;
|
||||
mem_tag <= read_data[`tag_start:`tag_end];
|
||||
hed <= read_data[`hed_start:`hed_end];
|
||||
tel <= read_data[`tel_start:`tel_end];
|
||||
if(read_data[`execute_bit] == 1) begin
|
||||
if (read_data[`tel_start:`tel_end] == `NIL) begin
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end else begin
|
||||
sys_func <= SYS_FUNC_EXECUTE;
|
||||
state <= SYS_EXECUTE_INIT;
|
||||
end
|
||||
end else begin
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
SYS_FUNC_WRITE: begin
|
||||
case(state)
|
||||
SYS_WRITE_INIT: begin
|
||||
address <= mem_addr;
|
||||
write_data <= {mem_tag, hed, tel};
|
||||
mem_func <= `SET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_WRITE_WAIT;
|
||||
end
|
||||
|
||||
SYS_WRITE_WAIT: begin
|
||||
if(mem_ready) begin
|
||||
sys_func <= write_return_sys_func;
|
||||
state <= write_return_state;
|
||||
end
|
||||
else begin
|
||||
address <= 0;
|
||||
write_data <= 0;
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
SYS_FUNC_TRAVERSE: begin
|
||||
case(state)
|
||||
SYS_TRAVERSE_INIT: begin
|
||||
case(mem_tag[1:0])
|
||||
`CELL_CELL: begin
|
||||
// if the hed cell hasn't been visited we push into it
|
||||
if(mem_tag[3:2] == 2'b00) begin
|
||||
// Verified
|
||||
// Set the command after write to traverse the hed
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
//set tag to visited hed
|
||||
mem_tag[3] <= 1;
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= hed;
|
||||
hed <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
else if(mem_tag[3:2] == 2'b10) begin // if hed was visited and tel wasnt
|
||||
// Verified
|
||||
// Set the command after write to traverse the tel
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
//pop the hed
|
||||
trav_B <= hed;
|
||||
trav_P <= trav_B;
|
||||
hed <= trav_P;
|
||||
//Wait for a clock cycle to push the tel
|
||||
state <= SYS_TRAVERSE_TEL;
|
||||
end
|
||||
else if(mem_tag[3:2] == 2'b11) begin // if both were visited
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
trav_B <= tel;
|
||||
trav_P <= trav_B;
|
||||
tel <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_HED: begin
|
||||
if(mem_ready) begin
|
||||
if(read_data[`execute_bit]==1) begin
|
||||
// If we need to execute the hed
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end
|
||||
else begin
|
||||
if (mem_data_gp[`tel_tag]==`CELL) begin
|
||||
// if the tel of the parent is a cell
|
||||
mem_data_gp <= read_data;
|
||||
address <= mem_data_gp[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
state <= SYS_EXECUTE_READ_TEL;
|
||||
end
|
||||
else begin
|
||||
// if not executing hed and parent then pass data to
|
||||
// the execute block
|
||||
address <= mem_data_gp[`tel_start:`tel_end];
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= mem_data;
|
||||
execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
debug_sig <= 2;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end
|
||||
end
|
||||
`ATOM_ATOM: begin
|
||||
// Pop
|
||||
mem_addr <= trav_B;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
|
||||
`ATOM_CELL: begin
|
||||
if(mem_tag[2] == 1'b0) begin // if both were visited
|
||||
// Set the command after write to traverse the tel
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
//set tag to visited tel
|
||||
mem_tag[2] <= 1;
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= tel;
|
||||
tel <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_TEL: begin
|
||||
if(mem_ready) begin
|
||||
if(read_data[`execute_bit]==1) begin
|
||||
// If we need to execute the tel
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
debug_sig <= 2;
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
else begin
|
||||
// if not executing hed and parent then pass data to
|
||||
// the execute block
|
||||
debug_sig <= 1;
|
||||
if(trav_B != `NIL) mem_addr <= trav_B;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= {mem_tag,hed,tel};//read_data;
|
||||
execute_tag <= mem_tag;//read_data[`tag_start:`tag_end];
|
||||
//execute_data <= mem_data;
|
||||
//execute_tag <= mem_tag;
|
||||
mux_controller <= 1;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
//address <= mem_addr;
|
||||
//mem_func <= `GET_CONTENTS;
|
||||
//mem_execute <= 1;
|
||||
|
||||
//state <= SYS_EXECUTE_READ_ADDR;
|
||||
end
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
trav_B <= tel;
|
||||
trav_P <= trav_B;
|
||||
tel <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
`CELL_ATOM: begin
|
||||
// if the hed cell hasn't been visited we push into it
|
||||
if(mem_tag[3] == 0) begin
|
||||
// Set the command after write to traverse the hed
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
//set tag to visited hed
|
||||
mem_tag[3] <= 1;
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= hed;
|
||||
hed <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
else begin
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
trav_B <= hed;
|
||||
trav_P <= trav_B;
|
||||
hed <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
SYS_EXECUTE_READ_ADDR: begin
|
||||
if(mem_ready) begin
|
||||
debug_sig <= 6;
|
||||
if(trav_B != `NIL) mem_addr <= trav_B;
|
||||
execute_address <= mem_addr;
|
||||
execute_data <= {mem_tag,hed,tel};//read_data;
|
||||
execute_tag <= mem_tag;//read_data[`tag_start:`tag_end];
|
||||
mux_controller <= 1;
|
||||
state <= SYS_EXECUTE_WAIT;
|
||||
end else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_WAIT: begin
|
||||
if(execute_finished) begin
|
||||
debug_sig <= 0;
|
||||
sys_func = execute_return_sys_func;
|
||||
state = execute_return_state;
|
||||
mux_controller <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_EXECUTE_ERROR: begin
|
||||
state <= SYS_EXECUTE_ERROR;
|
||||
is_finished_reg <= 1;
|
||||
end
|
||||
|
||||
endcase
|
||||
|
||||
endcase
|
||||
end
|
||||
SYS_TRAVERSE_PUSH: begin
|
||||
mem_addr <= trav_P;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
|
||||
SYS_FUNC_READ: begin
|
||||
case(state)
|
||||
SYS_READ_INIT: begin
|
||||
if(mem_addr == 1023) begin // mem_addr is only max when you reach the end and use trav_b's inital value
|
||||
is_finished_reg <= 1;
|
||||
end
|
||||
else begin
|
||||
is_finished_reg <= 0;
|
||||
address <= mem_addr;
|
||||
mem_func <= `GET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
|
||||
state <= SYS_READ_WAIT;
|
||||
end
|
||||
end
|
||||
|
||||
SYS_READ_WAIT: begin
|
||||
|
||||
if(mem_ready) begin
|
||||
mem_data <= read_data;
|
||||
mem_tag <= read_data[`tag_start:`tag_end]; // read first 4 bits and store into tag for easier access
|
||||
|
||||
hed <= read_data[`hed_start:`hed_end];
|
||||
tel <= read_data[`tel_start:`tel_end];
|
||||
//if tel is nil do soemthing?
|
||||
// If cell is marked for execution
|
||||
if(read_data[`execute_bit] == 1) begin
|
||||
if (read_data[`tel_start:`tel_end] == `NIL) begin
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end else begin
|
||||
sys_func <= SYS_FUNC_EXECUTE;
|
||||
state <= SYS_EXECUTE_INIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
sys_func <= SYS_FUNC_TRAVERSE;
|
||||
state <= SYS_TRAVERSE_INIT;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
|
||||
end
|
||||
endcase
|
||||
|
||||
|
||||
end
|
||||
|
||||
SYS_FUNC_WRITE: begin
|
||||
case(state)
|
||||
SYS_WRITE_INIT: begin
|
||||
address <= mem_addr;
|
||||
write_data <= {mem_tag, hed, tel};
|
||||
mem_func <= `SET_CONTENTS;
|
||||
mem_execute <= 1;
|
||||
|
||||
state <= SYS_WRITE_WAIT;
|
||||
end
|
||||
|
||||
SYS_WRITE_WAIT: begin
|
||||
if(mem_ready) begin
|
||||
sys_func <= write_return_sys_func;
|
||||
state <= write_return_state;
|
||||
end
|
||||
else begin
|
||||
address <= 0;
|
||||
write_data <= 0;
|
||||
mem_func <= 0;
|
||||
mem_execute <= 0;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
SYS_FUNC_TRAVERSE: begin
|
||||
case(state)
|
||||
SYS_TRAVERSE_INIT: begin
|
||||
case(mem_tag[1:0])
|
||||
`CELL_CELL: begin
|
||||
if(mem_tag[3:2] == 2'b00) begin // if the hed cell hasn't been visited we push into it
|
||||
// Verified
|
||||
// Set the command after write to traverse the hed
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
|
||||
//set tag to visited hed
|
||||
mem_tag[3] <= 1;
|
||||
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= hed;
|
||||
hed <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
|
||||
end
|
||||
else if(mem_tag[3:2] == 2'b10) begin // if hed was visited and tel wasnt
|
||||
// Verified
|
||||
// Set the command after write to traverse the tel
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
|
||||
//pop the hed
|
||||
trav_B <= hed;
|
||||
trav_P <= trav_B;
|
||||
hed <= trav_P;
|
||||
|
||||
//Wait for a clock cycle to push the tel
|
||||
state <= SYS_TRAVERSE_TEL;
|
||||
end
|
||||
else if(mem_tag[3:2] == 2'b11) begin // if both were visited
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
|
||||
trav_B <= tel;
|
||||
trav_P <= trav_B;
|
||||
tel <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
`ATOM_ATOM: begin
|
||||
// Pop
|
||||
mem_addr <= trav_B;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
`ATOM_CELL: begin
|
||||
if(mem_tag[2] == 1'b0) begin // if both were visited
|
||||
|
||||
debug_sig <= 1;
|
||||
|
||||
// Set the command after write to traverse the tel
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
|
||||
//set tag to visited tel
|
||||
mem_tag[2] <= 1;
|
||||
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= tel;
|
||||
tel <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
else begin
|
||||
debug_sig <= 2;
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
//write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
//write_return_state <= SYS_TRAVERSE_POP;
|
||||
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
|
||||
trav_B <= tel;
|
||||
trav_P <= trav_B;
|
||||
tel <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
`CELL_ATOM: begin
|
||||
if(mem_tag[3] == 0) begin // if the hed cell hasn't been visited we push into it
|
||||
|
||||
// Set the command after write to traverse the hed
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_PUSH;
|
||||
|
||||
//set tag to visited hed
|
||||
mem_tag[3] <= 1;
|
||||
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= hed;
|
||||
hed <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
else begin
|
||||
// Set the command after write to pop
|
||||
if(mem_tag[7] == 1) begin // If we still need to execute
|
||||
write_return_sys_func <= SYS_FUNC_EXECUTE;
|
||||
write_return_state <= SYS_EXECUTE_INIT;
|
||||
end else begin
|
||||
write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
write_return_state <= SYS_TRAVERSE_POP;
|
||||
end
|
||||
//write_return_sys_func <= SYS_FUNC_TRAVERSE;
|
||||
//write_return_state <= SYS_TRAVERSE_POP;
|
||||
|
||||
mem_tag[3:2] <= 2'b00;
|
||||
|
||||
trav_B <= hed;
|
||||
trav_P <= trav_B;
|
||||
hed <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
SYS_TRAVERSE_PUSH: begin
|
||||
mem_addr <= trav_P;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
|
||||
SYS_TRAVERSE_POP: begin
|
||||
mem_addr <= trav_B;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
|
||||
SYS_TRAVERSE_TEL: begin
|
||||
//set tag to visited tel
|
||||
mem_tag[2] <= 1;
|
||||
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= tel;
|
||||
tel <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
endcase
|
||||
SYS_TRAVERSE_POP: begin
|
||||
mem_addr <= trav_B;
|
||||
sys_func <= SYS_FUNC_READ;
|
||||
state <= SYS_READ_INIT;
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
SYS_TRAVERSE_TEL: begin
|
||||
//set tag to visited tel
|
||||
mem_tag[2] <= 1;
|
||||
//Store pointer to previous value in B
|
||||
trav_P <= tel;
|
||||
tel <= trav_B;
|
||||
trav_B <= trav_P;
|
||||
//Write Data
|
||||
sys_func <= SYS_FUNC_WRITE;
|
||||
state <= SYS_WRITE_INIT;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -4,19 +4,21 @@ This module will allow a control signal to pick signals to control memory module
|
||||
|
||||
`include "memory_unit.vh"
|
||||
|
||||
module memory_mux(input [1:0] mem_func_a, input [1:0] mem_func_b,
|
||||
input execute_a, input execute_b,
|
||||
input [`memory_addr_width - 1:0] address_a, input [`memory_addr_width - 1:0] address_b,
|
||||
input [`memory_data_width - 1:0] write_data_a, input [`memory_data_width - 1:0] write_data_b,
|
||||
input sel,
|
||||
output [1:0] mem_func,
|
||||
output execute,
|
||||
output [`memory_addr_width - 1:0] address,
|
||||
output [`memory_data_width - 1:0] write_data);
|
||||
module memory_mux(
|
||||
input [1:0] mem_func_a, input [1:0] mem_func_b,
|
||||
input execute_a, input execute_b,
|
||||
input [`memory_addr_width - 1:0] address_a, input [`memory_addr_width - 1:0] address_b,
|
||||
input [`memory_data_width - 1:0] write_data_a, input [`memory_data_width - 1:0] write_data_b,
|
||||
input sel,
|
||||
output [1:0] mem_func,
|
||||
output execute,
|
||||
output [`memory_addr_width - 1:0] address,
|
||||
output [`memory_data_width - 1:0] write_data
|
||||
);
|
||||
|
||||
assign mem_func = sel ? mem_func_b : mem_func_a;
|
||||
assign execute = sel ? execute_b : execute_a;
|
||||
assign address = sel ? address_b : address_a;
|
||||
assign write_data = sel ? write_data_b : write_data_a;
|
||||
assign mem_func = sel ? mem_func_b : mem_func_a;
|
||||
assign execute = sel ? execute_b : execute_a;
|
||||
assign address = sel ? address_b : address_a;
|
||||
assign write_data = sel ? write_data_b : write_data_a;
|
||||
|
||||
endmodule
|
||||
endmodule
|
||||
|
@ -2,171 +2,171 @@
|
||||
Will have 3 main functions used by external modules.
|
||||
- Given an address of a cell, return its value
|
||||
- Given an address of a cell, the cell's value, and a type tag, write to memory
|
||||
- Request the a batch of emprt cells that have a length of write_data.
|
||||
These are garrenteed to be open and this will cause a GC to run if not.
|
||||
Memory is word addressable. When all the correct values are set,
|
||||
pull execute to high and wait for is_ready to go high. This will mark that your command is finished
|
||||
- Request the a batch of emprt cells that have a length of write_data.
|
||||
These are garrenteed to be open and this will cause a GC to run if not.
|
||||
Memory is word addressable. When all the correct values are set,
|
||||
pull execute to high and wait for is_ready to go high. This will mark that your command is finished
|
||||
*/
|
||||
|
||||
`include "memory_unit.vh"
|
||||
|
||||
module memory_unit(power, clk, rst, func, execute, address, write_data, free_addr, read_data, is_ready, state, mem_data_out);
|
||||
|
||||
input power, clk, rst;
|
||||
input power, clk, rst;
|
||||
|
||||
// Control wires for this module
|
||||
input [1:0] func;
|
||||
input execute;
|
||||
input [`memory_addr_width - 1:0] address;
|
||||
input [`memory_data_width - 1:0] write_data;
|
||||
// Control wires for this module
|
||||
input [1:0] func;
|
||||
input execute;
|
||||
input [`memory_addr_width - 1:0] address;
|
||||
input [`memory_data_width - 1:0] write_data;
|
||||
|
||||
// Signal wires for this module
|
||||
reg is_ready_reg;
|
||||
output wire is_ready;
|
||||
assign is_ready = !execute && is_ready_reg;
|
||||
output reg [`memory_addr_width - 1:0] free_addr;
|
||||
output reg [`memory_data_width - 1:0] read_data;
|
||||
|
||||
// Interface with the ram module
|
||||
reg [`memory_addr_width - 1:0] mem_addr;
|
||||
reg mem_write;
|
||||
reg [`memory_data_width - 1:0] mem_data_in;
|
||||
output wire [`memory_data_width - 1:0] mem_data_out;
|
||||
|
||||
// Internal regs and wires
|
||||
reg [`memory_addr_width - 1:0] free_mem;
|
||||
output reg [3:0] state;
|
||||
|
||||
// States
|
||||
parameter STATE_INIT_SETUP = 4'h0,
|
||||
STATE_INIT_WAIT_0 = 4'h1,
|
||||
STATE_INIT_STORE_FREE_MEM = 4'h2,
|
||||
STATE_INIT_CLEAR_NIL = 4'h3,
|
||||
STATE_INIT_WAIT_1 = 4'h4,
|
||||
STATE_WAIT = 4'h5,
|
||||
STATE_READ_WAIT_0 = 4'h6,
|
||||
STATE_READ_FINISH = 4'h7,
|
||||
STATE_WRITE_WAIT_0 = 4'h8,
|
||||
STATE_WRITE_FINISH = 4'h9,
|
||||
STATE_FREE_WAIT = 4'hA,
|
||||
STATE_GARBAGE_COLLECT = 4'hB;
|
||||
|
||||
ram ram(.address (mem_addr),
|
||||
.clock (clk),
|
||||
.data (mem_data_in),
|
||||
.wren (mem_write),
|
||||
.q (mem_data_out));
|
||||
|
||||
always@(posedge clk or negedge rst) begin
|
||||
if(!rst) begin
|
||||
state <= STATE_INIT_SETUP;
|
||||
|
||||
free_mem <= 0;
|
||||
|
||||
mem_addr <= 0;
|
||||
mem_data_in <= 0;
|
||||
|
||||
is_ready_reg <= 0;
|
||||
// Signal wires for this module
|
||||
reg is_ready_reg;
|
||||
output wire is_ready;
|
||||
assign is_ready = !execute && is_ready_reg;
|
||||
output reg [`memory_addr_width - 1:0] free_addr;
|
||||
output reg [`memory_data_width - 1:0] read_data;
|
||||
|
||||
// Interface with the ram module
|
||||
reg [`memory_addr_width - 1:0] mem_addr;
|
||||
reg mem_write;
|
||||
reg [`memory_data_width - 1:0] mem_data_in;
|
||||
output wire [`memory_data_width - 1:0] mem_data_out;
|
||||
|
||||
// Internal regs and wires
|
||||
reg [`memory_addr_width - 1:0] free_mem;
|
||||
output reg [3:0] state;
|
||||
|
||||
// States
|
||||
parameter STATE_INIT_SETUP = 4'h0,
|
||||
STATE_INIT_WAIT_0 = 4'h1,
|
||||
STATE_INIT_STORE_FREE_MEM = 4'h2,
|
||||
STATE_INIT_CLEAR_NIL = 4'h3,
|
||||
STATE_INIT_WAIT_1 = 4'h4,
|
||||
STATE_WAIT = 4'h5,
|
||||
STATE_READ_WAIT_0 = 4'h6,
|
||||
STATE_READ_FINISH = 4'h7,
|
||||
STATE_WRITE_WAIT_0 = 4'h8,
|
||||
STATE_WRITE_FINISH = 4'h9,
|
||||
STATE_FREE_WAIT = 4'hA,
|
||||
STATE_GARBAGE_COLLECT = 4'hB;
|
||||
|
||||
ram ram(.address (mem_addr),
|
||||
.clock (clk),
|
||||
.data (mem_data_in),
|
||||
.wren (mem_write),
|
||||
.q (mem_data_out));
|
||||
|
||||
always@(posedge clk or negedge rst) begin
|
||||
if(!rst) begin
|
||||
state <= STATE_INIT_SETUP;
|
||||
free_mem <= 0;
|
||||
|
||||
mem_addr <= 0;
|
||||
mem_data_in <= 0;
|
||||
|
||||
is_ready_reg <= 0;
|
||||
end
|
||||
else if (power) begin
|
||||
case (state)
|
||||
// Initialize the free memory register
|
||||
STATE_INIT_SETUP: begin
|
||||
state <= STATE_INIT_WAIT_0;
|
||||
mem_addr <= 0;
|
||||
end
|
||||
STATE_INIT_WAIT_0: begin
|
||||
state <= STATE_INIT_STORE_FREE_MEM;
|
||||
end
|
||||
// Record the start of the free memory store
|
||||
STATE_INIT_STORE_FREE_MEM: begin
|
||||
state <= STATE_INIT_CLEAR_NIL;
|
||||
free_mem <= mem_data_out[9:0];
|
||||
end
|
||||
// Clear the nil pointer
|
||||
STATE_INIT_CLEAR_NIL: begin
|
||||
state <= STATE_INIT_WAIT_1;
|
||||
mem_addr <= 0;
|
||||
mem_data_in <= 0;
|
||||
end
|
||||
STATE_INIT_WAIT_1: begin
|
||||
state <= STATE_WAIT;
|
||||
free_addr <= free_mem;
|
||||
|
||||
mem_write <= 0;
|
||||
end
|
||||
|
||||
// Wait for a command dispatch
|
||||
STATE_WAIT: begin
|
||||
if(execute) begin
|
||||
is_ready_reg <= 0;
|
||||
// Dispatch according to the function
|
||||
case (func)
|
||||
`GET_CONTENTS: begin
|
||||
mem_addr <= address;
|
||||
state <= STATE_READ_WAIT_0;
|
||||
end
|
||||
|
||||
`SET_CONTENTS: begin
|
||||
mem_addr <= address;
|
||||
mem_data_in <= write_data;
|
||||
mem_write<=1;
|
||||
state <= STATE_WRITE_WAIT_0;
|
||||
end
|
||||
|
||||
`GET_FREE: begin
|
||||
if(free_addr + write_data <= 1023) begin // if you have enough free memory
|
||||
free_addr <= free_mem;
|
||||
free_mem <= free_mem + write_data;
|
||||
state <= STATE_FREE_WAIT;
|
||||
end
|
||||
else begin
|
||||
state <= STATE_GARBAGE_COLLECT;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end else begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
end
|
||||
else if (power) begin
|
||||
case (state)
|
||||
// Initialize the free memory register
|
||||
STATE_INIT_SETUP: begin
|
||||
state <= STATE_INIT_WAIT_0;
|
||||
mem_addr <= 0;
|
||||
end
|
||||
STATE_INIT_WAIT_0: begin
|
||||
state <= STATE_INIT_STORE_FREE_MEM;
|
||||
end
|
||||
// Record the start of the free memory store
|
||||
STATE_INIT_STORE_FREE_MEM: begin
|
||||
state <= STATE_INIT_CLEAR_NIL;
|
||||
free_mem <= mem_data_out[9:0];
|
||||
end
|
||||
// Clear the nil pointer
|
||||
STATE_INIT_CLEAR_NIL: begin
|
||||
state <= STATE_INIT_WAIT_1;
|
||||
|
||||
mem_addr <= 0;
|
||||
mem_data_in <= 0;
|
||||
end
|
||||
STATE_INIT_WAIT_1: begin
|
||||
state <= STATE_WAIT;
|
||||
free_addr <= free_mem;
|
||||
|
||||
mem_write <= 0;
|
||||
end
|
||||
|
||||
// Wait for a command dispatch
|
||||
STATE_WAIT: begin
|
||||
if(execute) begin
|
||||
is_ready_reg <= 0;
|
||||
// Dispatch according to the function
|
||||
case (func)
|
||||
`GET_CONTENTS: begin
|
||||
mem_addr <= address;
|
||||
state <= STATE_READ_WAIT_0;
|
||||
end
|
||||
`SET_CONTENTS: begin
|
||||
mem_addr <= address;
|
||||
mem_data_in <= write_data;
|
||||
mem_write<=1;
|
||||
state <= STATE_WRITE_WAIT_0;
|
||||
end
|
||||
|
||||
end
|
||||
`GET_FREE: begin
|
||||
if(free_addr + write_data <= 1023) begin // if you have enough free memory
|
||||
free_addr <= free_mem;
|
||||
free_mem <= free_mem + write_data;
|
||||
state <= STATE_FREE_WAIT;
|
||||
end
|
||||
else begin
|
||||
state <= STATE_GARBAGE_COLLECT;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
end
|
||||
// Keep waiting
|
||||
else begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
//mem_addr <= 0;
|
||||
end
|
||||
end
|
||||
// Various wait states used when reading from memory
|
||||
STATE_READ_WAIT_0: begin
|
||||
state <= STATE_READ_FINISH;
|
||||
end
|
||||
STATE_READ_FINISH: begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
|
||||
read_data <= mem_data_out;
|
||||
end
|
||||
// Various wait states used when writing to memory
|
||||
STATE_WRITE_WAIT_0: begin
|
||||
state <= STATE_WRITE_FINISH;
|
||||
mem_write<=0;
|
||||
end
|
||||
|
||||
STATE_WRITE_FINISH: begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
end
|
||||
// Return a new cell
|
||||
STATE_FREE_WAIT: begin
|
||||
is_ready_reg <= 1;
|
||||
|
||||
state <= STATE_WAIT;
|
||||
end
|
||||
// Return a new cell
|
||||
STATE_GARBAGE_COLLECT: begin
|
||||
state <= STATE_GARBAGE_COLLECT;
|
||||
$stop;
|
||||
end
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
// Various wait states used when reading from memory
|
||||
STATE_READ_WAIT_0: begin
|
||||
state <= STATE_READ_FINISH;
|
||||
end
|
||||
|
||||
STATE_READ_FINISH: begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
read_data <= mem_data_out;
|
||||
end
|
||||
|
||||
// Various wait states used when writing to memory
|
||||
STATE_WRITE_WAIT_0: begin
|
||||
state <= STATE_WRITE_FINISH;
|
||||
mem_write<=0;
|
||||
end
|
||||
|
||||
STATE_WRITE_FINISH: begin
|
||||
state <= STATE_WAIT;
|
||||
is_ready_reg <= 1;
|
||||
end
|
||||
|
||||
// Return a new cell
|
||||
STATE_FREE_WAIT: begin
|
||||
is_ready_reg <= 1;
|
||||
state <= STATE_WAIT;
|
||||
end
|
||||
|
||||
// Return a new cell
|
||||
STATE_GARBAGE_COLLECT: begin
|
||||
state <= STATE_GARBAGE_COLLECT;
|
||||
$stop;
|
||||
end
|
||||
|
||||
default:;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
@ -21,7 +21,7 @@
|
||||
`define SET_CONTENTS 2'b01
|
||||
`define GET_FREE 2'b10
|
||||
|
||||
// Memory tag defines
|
||||
// Memory tag defines
|
||||
`define ATOM_ATOM 2'b11
|
||||
`define ATOM_CELL 2'b10
|
||||
`define CELL_ATOM 2'b01
|
||||
|
@ -1,22 +1,22 @@
|
||||
`include "memory_unit.vh"
|
||||
module ram(
|
||||
input wire clock,
|
||||
input wire [`memory_addr_width - 1:0] address,
|
||||
input wire [`memory_data_width - 1:0] data,
|
||||
input wire wren,
|
||||
output reg [`memory_data_width - 1:0] q
|
||||
input wire clock,
|
||||
input wire [`memory_addr_width - 1:0] address,
|
||||
input wire [`memory_data_width - 1:0] data,
|
||||
input wire wren,
|
||||
output reg [`memory_data_width - 1:0] q
|
||||
);
|
||||
|
||||
reg [`memory_data_width - 1:0] ram [1023:0];
|
||||
reg [`memory_data_width - 1:0] ram [1023:0];
|
||||
|
||||
always @(posedge clock) begin
|
||||
if (wren) begin
|
||||
// On a write cycle, store the input data at the specified address.
|
||||
ram[address] <= data;
|
||||
end else begin
|
||||
// On a read cycle, output the data at the specified address.
|
||||
q <= ram[address];
|
||||
end
|
||||
always @(posedge clock) begin
|
||||
if (wren) begin
|
||||
// On a write cycle, store the input data at the specified address.
|
||||
ram[address] <= data;
|
||||
end else begin
|
||||
// On a read cycle, output the data at the specified address.
|
||||
q <= ram[address];
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
// megafunction wizard: %RAM: 1-PORT%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram.v
|
||||
@ -19,12 +19,12 @@
|
||||
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
//the Intel FPGA IP License Agreement, or other applicable license
|
||||
//agreement, including, without limitation, that your use is for
|
||||
|
@ -1,7 +1,7 @@
|
||||
// megafunction wizard: %RAM: 1-PORT%VBB%
|
||||
// GENERATION: STANDARD
|
||||
// VERSION: WM1.0
|
||||
// MODULE: altsyncram
|
||||
// MODULE: altsyncram
|
||||
|
||||
// ============================================================
|
||||
// File Name: ram.v
|
||||
@ -18,12 +18,12 @@
|
||||
// ************************************************************
|
||||
|
||||
//Copyright (C) 2020 Intel Corporation. All rights reserved.
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Your use of Intel Corporation's design tools, logic functions
|
||||
//and other software and tools, and any partner logic
|
||||
//functions, and any output files from any of the foregoing
|
||||
//(including device programming or simulation files), and any
|
||||
//associated documentation or information are expressly subject
|
||||
//to the terms and conditions of the Intel Program License
|
||||
//Subscription Agreement, the Intel Quartus Prime License Agreement,
|
||||
//the Intel FPGA IP License Agreement, or other applicable license
|
||||
//agreement, including, without limitation, that your use is for
|
||||
|
@ -24,7 +24,7 @@ module single_port_ram
|
||||
|
||||
// Continuous assignment implies read returns NEW data.
|
||||
// This is the natural behavior of the TriMatrix memory
|
||||
// blocks in Single Port mode.
|
||||
// blocks in Single Port mode.
|
||||
assign q = ram[addr_reg];
|
||||
|
||||
endmodule
|
||||
|
Loading…
Reference in New Issue
Block a user