📄 tiny16.v
字号:
/****************************************************************************/
//
// Instruction Set
//
// 0000 0000 nnnn nnnn pfx
// 0000 1aaa nnnn nnnn alui
// 0001 0aaa nnnn nnnn alua
// 0001 1aaa 0000 0000 alux
// 0010 0000 0000 0000 psha
// 0010 0000 0000 0001 pshp
// 0010 0000 0000 0010 pula
// 0010 0000 0000 0011 pulp
// 0010 0000 0000 010c ldc
// 0010 0000 0000 0110 ldsx
// 0010 0000 0000 0111 ldxs
// 0010 0000 0000 1000 inx
// 0010 0000 0000 1001 dex
// 0010 0000 0000 1010 swap
// 0010 0000 0000 1100 ror
// 0010 0000 0000 1101 rol
// 0010 001n nnnn nnnn stix
// 0010 010n nnnn nnnn ldai
// 0010 011n nnnn nnnn ldxi
// 0010 100n nnnn nnnn lda
// 0010 101n nnnn nnnn ldx
// 0010 110n nnnn nnnn sta
// 0010 111n nnnn nnnn stx
// 0011 000n nnnn nnnn ldix
// 01cc nnnn nnnn nnnn jprc
// 10cc nnnn nnnn nnnn jrsc
// 11cc 0000 0000 0000 retc
//
/****************************************************************************/
module tiny16(
clock,
address,
data_in,
data_out,
go_read,
go_write,
complete,
cond_true);
parameter reset = 0;
parameter fetch = 1;
parameter exec_1 = 2;
parameter exec_2 = 3;
input clock;
input [15:0] data_in;
input complete;
output [15:0] address;
output [15:0] data_out;
output go_read;
output go_write;
output cond_true;
reg go_read;
reg go_write;
reg [15:0] address;
reg [15:0] data_out;
reg [5:0] fsm, next_state;
reg pc_ena;
reg [15:0] pc, pc_data;
reg sp_ena;
reg [15:0] sp, sp_data;
reg k_ena;
reg [7:0] k, k_data, preserve_k;
reg ra_ena;
reg cflag, cflag_data, cflag_ena, zflag, zflag_data, zflag_ena;
reg [15:0] ra, ra_data;
reg rx_ena;
reg [15:0] rx, rx_data;
reg ir_ena;
reg [15:0] ir, ir_data;
wire cond_true;
reg [15:0] alu_b;
wire [16:0] alu_result;
reg add_sub_cout;
wire add_sub_carry;
reg [15:0] add_sub_result;
lpm_add_sub add_sub(.dataa(ra), .datab(alu_b), .cin(add_sub_carry), .add_sub(~ir[9]),
.result(add_sub_result), .cout(add_sub_cout));
defparam add_sub.lpm_width = 16;
defparam add_sub.lpm_representation = "UNSIGNED";
assign add_sub_carry = (ir[10:8] == 0) ? 1'b0 :
(ir[10:8] == 1) ? cflag :
(ir[10:8] == 2) ? 1'b1 :
(ir[10:8] == 3) ? ~cflag : 1'b1;
assign cond_true = (ir[13:12] == 0) ? cflag :
(ir[13:12] == 1) ? zflag :
(ir[13:12] == 2) ? ~zflag : 1'b1;
assign alu_result = (ir[10:8] == 0) ? {add_sub_cout, add_sub_result} :
(ir[10:8] == 1) ? {add_sub_cout, add_sub_result} :
(ir[10:8] == 2) ? {~add_sub_cout, add_sub_result} :
(ir[10:8] == 3) ? {~add_sub_cout, add_sub_result} :
(ir[10:8] == 4) ? {cflag, (ra & alu_b)} :
(ir[10:8] == 5) ? {cflag, (ra | alu_b)} :
(ir[10:8] == 6) ? {cflag, (ra ^ alu_b)} : {~add_sub_cout, ra};
always @ (posedge clock) begin
fsm <= next_state;
if(pc_ena == 1'b1)
pc <= pc_data;
if(sp_ena == 1'b1)
sp <= sp_data;
if(k_ena == 1'b1)
k <= k_data;
if(cflag_ena == 1'b1)
cflag <= cflag_data;
if(zflag_ena == 1'b1)
zflag <= zflag_data;
if(ra_ena == 1'b1)
ra <= ra_data;
if(rx_ena == 1'b1)
rx <= rx_data;
if(ir_ena == 1'b1)
ir <= data_in;
end
always @ (fsm, data_in, pc, sp, k, cflag, zflag, cond_true, alu_result, ra, rx, ir, complete) begin
address <= 0;
data_out <= 0;
pc_data <= 0;
pc_ena <= 1'b0;
sp_data <= 0;
sp_ena <= 1'b0;
k_data <= 0;
k_ena <= 1'b0;
cflag_data <= 1'b0;
cflag_ena <= 1'b0;
zflag_data <= 1'b0;
zflag_ena <= 1'b0;
ra_data <= 0;
ra_ena <= 1'b0;
rx_data <= 0;
rx_ena <= 1'b0;
alu_b <= 0;
go_read <= 1'b0;
go_write <= 1'b0;
ir_ena <= 1'b0;
next_state <= fsm;
case(fsm)
reset:begin
pc_data <= 16'b0;
pc_ena <= 1'b1;
sp_data <= 16'b0;
sp_ena <= 16'b0;
next_state <= fetch;
end
fetch:begin
address <= pc;
pc_data <= pc + 1;
go_read <= 1'b1;
if(complete == 1'b1) begin
ir_ena <= 1'b1;
pc_ena <= 1'b1;
next_state <= exec_1;
end
end
exec_1:begin
casex(ir)
16'b0000_0000_xxxx_xxxx:begin // pfx
k_data <= ir[7:0];
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0000_1xxx_xxxx_xxxx:begin // alui
alu_b <= {k, ir[7:0]};
ra_data <= alu_result[15:0];
ra_ena <= 1'b1;
cflag_data <= alu_result[16];
cflag_ena <= 1'b1;
zflag_data <= {alu_result[15:0] == 0};
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0001_0xxx_xxxx_xxxx:begin // alua
address <= {k, ir[7:0]};
go_read <= 1'b1;
alu_b <= data_in;
ra_data <= alu_result[15:0];
cflag_data <= alu_result[16];
zflag_data <= {alu_result[15:0] == 0};
if(complete == 1'b1) begin
ra_ena <= 1'b1;
cflag_ena <= 1'b1;
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
end
16'b0001_1xxx_xxxx_xxxx:begin // alux
alu_b <= rx;
ra_data <= alu_result[15:0];
ra_ena <= 1'b1;
cflag_data <= alu_result[16];
cflag_ena <= 1'b1;
zflag_data <= {alu_result[15:0] == 0};
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_000x:begin // psha, pshp
address <= sp;
if(ir[0] == 1'b0)
data_out <= ra;
else
data_out[1:0] <= {cflag, zflag};
sp_data <= sp + 1;
go_write <= 1'b1;
k_ena <= 1'b1;
if(complete == 1'b1) begin
sp_ena <= 1'b1;
next_state <= fetch;
end
end
16'b0010_0000_0000_001x:begin // pula, pulp
sp_data <= sp - 1;
sp_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= exec_2;
end
16'b0010_0000_0000_010x:begin // clc, sec
cflag_data <= ir[0];
cflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_011x:begin // ldsx, ldsx
rx_data <= sp;
sp_data <= rx;
rx_ena <= ir[0];
sp_ena <= ~ir[0];
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_100x:begin // inx, dex
if(ir[0] == 1'b0) begin
rx_data <= rx + 1;
zflag_data <= {(rx + 1) == 0};
end
else begin
rx_data <= rx - 1;
zflag_data <= {(rx - 1) == 0};
end
rx_ena <= 1'b1;
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_1010:begin // swap
ra_data <= rx;
rx_data <= ra;
ra_ena <= 1'b1;
rx_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_1100:begin // ror
ra_data <= {cflag, ra[15:1]};
cflag_data <= ra[0];
ra_ena <= 1'b1;
cflag_ena <= 1'b1;
zflag_data <= ({cflag, ra[15:1]} == 0);
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_0000_0000_1101:begin // rol
ra_data <= {ra[14:0], cflag};
cflag_data <= ra[15];
ra_ena <= 1'b1;
cflag_ena <= 1'b1;
zflag_data <= ({ra[14:0], cflag} == 0);
zflag_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_001x_xxxx_xxxx:begin // stix
address <= rx;
data_out <= ra;
go_write <= 1'b1;
k_ena <= 1'b1;
if(complete == 1'b1)
next_state <= fetch;
end
16'b0010_01xx_xxxx_xxxx:begin // ldai, ldxi
ra_data <= {k[6:0], ir[8:0]};
rx_data <= {k[6:0], ir[8:0]};
ra_ena <= ~ir[9];
rx_ena <= ir[9];
k_ena <= 1'b1;
next_state <= fetch;
end
16'b0010_10xx_xxxx_xxxx:begin // lda, ldx
address <= {k[6:0], ir[8:0]};
ra_data <= data_in;
rx_data <= data_in;
go_read <= 1'b1;
if(complete == 1'b1) begin
ra_ena <= ~ir[9];
rx_ena <= ir[9];
k_ena <= 1'b1;
next_state <= fetch;
end
end
16'b0010_11xx_xxxx_xxxx:begin // sta, stx
address <= {k[6:0], ir[8:0]};
if(ir[9] == 1'b0)
data_out <= ra;
else
data_out <= rx;
go_write <= 1'b1;
if(complete == 1'b1) begin
k_ena <= 1'b1;
next_state <= fetch;
end
end
16'b0011_000x_xxxx_xxxx:begin // ldix
address <= rx;
go_read <= 1'b1;
ra_data <= data_in;
k_ena <= 1'b1;
if(complete == 1'b1) begin
ra_ena <= 1'b1;
next_state <= fetch;
end
end
16'b01xx_xxxx_xxxx_xxxx:begin // jprc
pc_data <= pc + {k[3:0], ir[11:0]};
pc_ena <= cond_true;
k_ena <= 1'b1;
next_state <= fetch;
end
16'b10xx_xxxx_xxxx_xxxx:begin // jrsc
address <= sp;
data_out <= pc;
go_write <= cond_true;
pc_data <= pc + {k[3:0], ir[11:0]};
sp_data <= sp + 1;
if(cond_true == 1'b1)
if(complete == 1'b1) begin
pc_ena <= 1'b1;
sp_ena <= 1'b1;
k_ena <= 1'b1;
next_state <= fetch;
end
else begin
pc_ena <= 1'b0;
sp_ena <= 1'b0;
k_ena <= 1'b0;
next_state <= exec_1;
end
else begin
k_ena <= 1'b1;
next_state <= fetch;
end
end
16'b11xx_xxxx_xxxx_xxxx:begin // retc
k_ena <= 1'b1;
if(cond_true == 1'b1) begin
sp_data <= sp - 1;
sp_ena <= 1'b1;
next_state <= exec_2;
end
else
next_state <= fetch;
end
endcase
end
exec_2:begin
casex(ir)
16'b0010_0000_0000_001x:begin // pula, pulp
address <= sp;
go_read <= 1'b1;
ra_data <= data_in;
cflag_data <= data_in[1];
zflag_data <= data_in[0];
if(complete == 1'b1) begin
ra_ena <= ~ir[0];
cflag_ena <= ir[0];
zflag_ena <= ir[0];
next_state <= fetch;
end
end
16'b11xx_xxxx_xxxx_xxxx:begin // retc
address <= sp;
go_read <= 1'b1;
pc_data <= data_in;
if(complete == 1'b1) begin
pc_ena <= 1'b1;
next_state <= fetch;
end
end
endcase
end
endcase
end
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -