// $Id$ module Chip( input wire i_clk, input wire i_reset, output reg [0:4] o_ioaddr, input wire [0:8] i_iodata, output reg [0:8] o_iodata ); reg i_ramwrite = 0; reg [0:7] i_data; wire [0:7] o_data; reg [0:15] i_addr; reg [0:15] r0 = 0; reg [0:15] r1 = 0; reg [0:15] r2 = 0; reg [0:15] r3 = 0; reg [0:15] r4 = 0; reg [0:15] sp = 0; reg [0:15] pc = 0; task set_mode( input logic [0:7] register, input logic [0:15] setto, input logic [0:15] base ); reg [0:15] num = 0; reg [0:2] hla = 0; reg [0:15] tmp = 0; if((register >> 7) & 1) begin i_addr = base; num = o_data << 8; #1 i_addr = base + 1; num = num | o_data; #1 if((register >> 6) & 1) begin reg [0:15] tmp = 0; tmp = num; i_ramwrite = 1; i_addr = tmp; i_data = setto >> 8; #1 i_addr = tmp + 1; i_data = setto & 255; #1 i_ramwrite = 0; i_data = 0; end end else begin case(register & 7) 0: tmp = r0; 1: tmp = r1; 2: tmp = r2; 3: tmp = r3; 4: tmp = r4; 5: tmp = sp; 6: tmp = pc; endcase case(register & 7) 0: num = r0; 1: num = r1; 2: num = r2; 3: num = r3; 4: num = r4; 5: num = sp; 6: num = pc; endcase hla = hla | ((register >> 4) & 1); hla = hla | ((register >> 4) & 2); if((register >> 6) & 1) begin i_ramwrite = 1; if(hla & 2'b10) begin i_addr = num; i_data = setto >> 8; end #1 if(hla & 2'b01) begin i_addr = num + 1; i_data = setto & 255; end #1 i_ramwrite = 0; i_data = 0; end else begin if(hla & 2'b10) begin tmp = (tmp & 255) | (setto & 16'b1111111100000000); end if(hla & 2'b01) begin tmp = (tmp & 16'b1111111100000000) | (setto & 255); end case(register & 7) 0: r0 = tmp; 1: r1 = tmp; 2: r2 = tmp; 3: r3 = tmp; 4: r4 = tmp; 5: sp = tmp; 6: pc = tmp; endcase end end endtask reg [0:15] mode_result; task get_mode( input logic [0:7] register, input logic [0:15] base ); reg [0:15] num = 0; reg [0:2] hla = 0; if((register >> 7) & 1) begin i_addr = base; num = o_data << 8; #1 i_addr = base + 1; num = num | o_data; #1 if((register >> 6) & 1) begin reg [0:15] tmp = 0; tmp = num; i_addr = tmp; num = o_data << 8; #1 i_addr = tmp + 1; num = num | o_data; #1 ; end end else begin case(register & 7) 0: num = r0; 1: num = r1; 2: num = r2; 3: num = r3; 4: num = r4; 5: num = sp; 6: num = pc; endcase hla = hla | ((register >> 4) & 1); hla = hla | ((register >> 4) & 2); if((register >> 6) & 1) begin reg [0:15] tmp; i_addr = num; tmp = o_data; #1 i_addr = num + 1; tmp = (tmp << 8) | o_data; #1 num = tmp; end end mode_result = num; endtask Memory mem( .i_clk(i_clk), .i_reset(i_reset), .i_ramwrite(i_ramwrite), .i_addr(i_addr), .i_data(i_data), .o_data(o_data) ); always @(posedge i_clk) begin if(i_reset) begin i_addr <= 0; i_data <= 0; r0 <= 0; r1 <= 0; r2 <= 0; r3 <= 0; r4 <= 0; sp <= 0; pc <= 0; end else begin reg [0:7] to; reg [0:7] setfrom; reg [0:15] got_mode; reg [0:15] base1; reg [0:15] base2; reg [0:15] port; reg [0:15] data; i_addr = pc; case(o_data) 8'h00 : begin pc = pc + 1; end 8'h01 : begin pc = pc + 1; i_addr = pc; to = o_data; pc = pc + 1; base2 = pc; if((to >> 7) & 1) pc = pc + 2; #1 i_addr = pc; setfrom = o_data; pc = pc + 1; base1 = pc; if((setfrom >> 7) & 1) pc = pc + 2; #1 get_mode(setfrom, base1); got_mode = mode_result; set_mode(to, got_mode, base2); end 8'h02 : begin pc = pc + 1; i_addr = pc; to = o_data; pc = pc + 1; base1 = pc; if((to >> 7) & 1) pc = pc + 2; #1 get_mode(to, base1); got_mode = mode_result; pc = got_mode; end 8'h03 : begin pc = pc + 1; i_addr = pc; to = o_data; pc = pc + 1; base1 = pc; if((to >> 7) & 1) pc = pc + 2; #1 get_mode(to, base1); got_mode = mode_result; set_mode(to, got_mode + 1, base1); end 8'h04 : begin pc = pc + 1; i_addr = pc; to = o_data; pc = pc + 1; base1 = pc; if((to >> 7) & 1) pc = pc + 2; #1 get_mode(to, base1); got_mode = mode_result; set_mode(to, got_mode - 1, base1); end 8'h05 : begin pc = pc + 1; i_addr = pc; to = o_data; pc = pc + 1; base2 = pc; if((to >> 7) & 1) pc = pc + 2; #1 i_addr = pc; setfrom = o_data; pc = pc + 1; base1 = pc; if((setfrom >> 7) & 1) pc = pc + 2; #1 get_mode(setfrom, base1); data = mode_result; get_mode(to, base2); port = mode_result; o_ioaddr = port; o_iodata = data; #1 ; end default: begin end endcase end end endmodule