§ Код ядра
Ядро не завершено и не протестировано.
module cpu
(
input clock,
input reset_n,
input ce,
output [31:0] address,
input [ 7:0] in,
output reg [ 7:0] out,
output reg we,
output reg [ 7:0] rd,
output reg [ 7:0] rs,
input [31:0] rd_in,
input [31:0] rs_in,
output reg [31:0] rd_out,
output reg rdw,
output reg [ 9:0] sp,
input [31:0] sp_in,
output reg [31:0] sp_out,
output reg spw
);
localparam
ADD = 0, SUB = 1, ADC = 2, SBC = 3, AND = 4, XOR = 5, OR = 6, CMP = 7,
ROL = 0, ROR = 1, SHL = 2, SHR = 3, RCL = 4, RCR = 5, SAR = 7,
OF = 3, SF = 2, ZF = 1, CF = 0;
assign address = sw ? cp : pc;
reg sw;
reg [ 3:0] t;
reg [31:0] pc, cp;
reg [ 3:0] flags = 4'b0000;
reg [ 7:0] opcode, n;
wire [31:0] pcn = pc + 1;
wire [31:0] cpn = cp + 1;
wire [ 2:0] op = opcode[2:0];
wire [32:0] ar =
op == ADD ? rd_in + rs_in :
op == ADC ? rd_in + rs_in + flags[CF] :
op == SBC ? rd_in - rs_in - flags[CF] :
op == AND ? rd_in & rs_in :
op == XOR ? rd_in ^ rs_in :
op == OR ? rd_in | rs_in :
rd_in - rs_in;
wire is_add = op == ADD || op == ADC;
wire is_arh = op != AND && op != XOR && op != OR;
wire of = (rd_in[31] ^ rs_in[31] ^ is_add) ^ (rd_in[31] ^ ar[31]);
wire [3:0] af = { of & is_arh, ar[31], ~|ar[31:0], ar[32] & is_arh};
wire [64:0] srd =
op == ROR ? {rd_in, rd_in, rd_in[0]} :
op == ROL ? {rd_in[31], rd_in, rd_in} :
op == SAR ? {{32{rd_in[31]}}, rd_in, rd_in[0]} :
op == SHR ? {32'b0, rd_in, rd_in[0]} :
op == RCR ? {rd_in[30:0],flags[CF], rd_in, rd_in[0]} :
op == RCL ? {rd_in[31], rd_in, flags[CF], rd_in[31:1]} :
{rd_in[31], rd_in, 32'b0};
wire [32:0] shr = srd >> rs_in[3:0];
wire [63:0] shl = srd << rs_in[3:0];
always @(posedge clock)
if (reset_n == 1'b0) begin
sw <= 0;
pc <= 0;
sp <= 0;
t <= 0;
out <= 0;
end else if (ce) begin
we <= 0;
rdw <= 0;
spw <= 0;
t <= t + 1;
if (t == 0) begin opcode <= in; pc <= pcn; end
casex (t ? opcode : in)
8'h00:
case (t)
1: begin rd <= in; pc <= pcn; end
2: begin rd_out[ 7:0] <= in; pc <= pcn; end
3: begin rd_out[ 15:8] <= in; pc <= pcn; end
4: begin rd_out[23:16] <= in; pc <= pcn; end
5: begin rd_out[31:24] <= in; pc <= pcn; rdw <= 1; t <= 0; end
endcase
8'h01:
case (t)
1: begin rs <= in; pc <= pcn; end
2: begin rd <= in; rd_out <= rs_in; rdw <= 1; t <= 0; end
endcase
8'h02,
8'h03,
8'h04:
case (t)
1: begin rs <= in; pc <= pcn; end
2: begin rd <= in; pc <= pcn; cp <= rs_in; sw <= 1; end
3: begin rd_out <= in; cp <= cpn; rdw <= 1; if (opcode == 8'h02) begin t <= 0; sw <= 0; end end
4: begin rd_out[ 15:8] <= in; cp <= cpn; rdw <= 1; if (opcode == 8'h03) begin t <= 0; sw <= 0; end end
5: begin rd_out[23:16] <= in; cp <= cpn; end
6: begin rd_out[31:24] <= in; cp <= cpn; rdw <= 1; t <= 0; sw <= 0; end
endcase
8'h05,
8'h06,
8'h07:
case (t)
1: begin rs <= in; pc <= pcn; end
2: begin rd <= in; pc <= pcn; cp <= rs_in; sw <= 1; end
3: begin out <= rd_in[ 7:0]; we <= 1; if (opcode == 8'h05) t <= 7; end
4: begin out <= rd_in[ 15:8]; we <= 1; cp <= cpn; if (opcode == 8'h06) t <= 7; end
5: begin out <= rd_in[23:16]; we <= 1; cp <= cpn; end
6: begin out <= rd_in[31:24]; we <= 1; cp <= cpn; end
7: begin t <= 0; sw <= 0; end
endcase
8'h20,
8'h21:
case (t)
1: begin rd <= in; pc <= pcn; end
2: begin rd_out <= {{24{in[7] & opcode[0]}}, in}; rdw <= 1; pc <= pcn; t <= 0; end
endcase
8'h0C:
case (t)
1: begin rd_out[ 7:0] <= in; pc <= pcn; end
2: begin rd_out[ 15:8] <= in; pc <= pcn; end
3: begin rd_out[23:16] <= in; pc <= pcn; end
4: begin pc <= {in, rd_out[23:0]}; sp_out <= pcn; spw <= 1; sp <= sp - 1; t <= 0; end
endcase
8'h0D:
case (t)
0: begin pc <= sp_in; sp <= sp + 1; t <= 0; end
endcase
8'h0E:
case (t)
1: begin n <= in; pc <= pcn; end
2: begin rs <= in; pc <= pcn; end
3: begin
sp_out <= rs_in;
sp <= sp - 1;
spw <= 1;
rs <= in;
pc <= n ? pcn : pc;
n <= n - 1;
t <= n ? 3 : 0;
end
endcase
8'h0F:
case (t)
1: begin n <= in; pc <= pcn; end
2: begin
rd <= in;
pc <= pcn;
rd_out <= sp_in;
rdw <= 1;
n <= n - 1;
sp <= sp + 1;
t <= n ? 2 : 0;
end
endcase
8'b0001_0xxx:
case (t)
1: begin rd <= in; pc <= pcn; end
2: begin rs <= in; pc <= pcn; end
3: begin rd <= in; pc <= pcn; rd_out <= ar; flags <= af; rdw <= 1; t <= 0; end
endcase
8'b0001_1xxx:
case (t)
1: begin pc <= pcn; rd <= in; end
2: begin pc <= pcn; rs <= in; end
3: begin rd_out <= opcode[0] ? shr[32:1] : shl[64:32]; rdw <= 1; t <= 0; end
endcase
endcase
end
endmodule