I2C温度計その3
- minicpu.v
`include "defs.v"
module minicpu(clk, reset, run, in, cs, pcout, irout, qtop, abus, dbus, out, haltx
);
input clk,reset, run, haltx;
input [15:0] in;
output [2:0] cs;
output [15:0] irout, qtop, dbus, out;
output [11:0] pcout, abus;
wire [15:0] qnext, ramout, aluout;
reg [11:0] abus;
reg halt, cont, pcinc, push, pop, abus2pc, dbus2ir, dbus2qtop, dbus2ram,
dbus2obuf, pc2abus, ir2abus, ir2dbus, qtop2dbus, qnext2dbus, qtop2abus, qnext2abus, alu2dbus, ram2dbus, in2dbus;
counter #(12) pc0(.clk(clk), .reset(reset), .load(abus2pc),
.inc(pcinc), .d(abus), .q(pcout));
counter #(16) ir0(.clk(clk), .reset(reset), .load(dbus2ir),
.inc(0), .d(dbus), .q(irout));
state state0(.clk(clk), .reset(reset), .run(run),
.halt(halt), .cont(cont), .cs(cs));
stack stack0(.clk(clk), .reset(reset), .load(dbus2qtop), .push(push), .pop(pop),
.d(dbus), .qtop(qtop), .qnext(qnext));
alu alu0(.a(qtop), .b(qnext), .f(irout[4:0]), .s(aluout));
ram #(16,12,4096) ram0(.clk(clk), .load(dbus2ram),
.addr(abus), .d(dbus), .q(ramout));
counter #(16) obuf0(.clk(clk), .reset(reset), .load(dbus2obuf),
.inc(0), .d(dbus), .q(out));
always @(pc2abus or ir2abus or pcout or irout or qtop2abus or qnext2abus)
if(pc2abus) abus = pcout;
else if(ir2abus) abus = irout[11:0];
else if(qtop2abus) abus = qtop[11:0];
else if(qnext2abus) abus = qnext[11:0];
else abus = 12'hxxx;
assign dbus = ir2dbus ? {{4{irout[11]}},irout[11:0]} : 16'hzzzz;
assign dbus = qtop2dbus ? qtop : 16'hzzzz;
assign dbus = alu2dbus ? aluout : 16'hzzzz;
assign dbus = ram2dbus ? ramout : 16'hzzzz;
assign dbus = in2dbus ? in : 16'hzzzz;
assign dbus = qnext2dbus? qnext[11:0] : 16'hzzz;
always @(cs or irout or qtop)
begin
halt = 0; cont = 0; pcinc = 0; push = 0; pop = 0; abus2pc = 0; dbus2ir = 0;
dbus2qtop = 0; dbus2ram = 0; dbus2obuf = 0; pc2abus = 0; ir2abus = 0; qtop2abus = 0;
ir2dbus = 0; qtop2dbus = 0; alu2dbus = 0; ram2dbus = 0; in2dbus = 0; qnext2dbus=0; qnext2abus=0;
if(cs == `FETCHA)
begin
pcinc = 1; pc2abus = 1;
end
else if(cs == `FETCHB)
begin
ram2dbus = 1; dbus2ir = 1;
end
else if(cs == `EXECA)
begin
if(haltx) halt=1;
case(irout[15:12])
`PUSHI:
begin
ir2dbus = 1; dbus2qtop = 1; push = 1;
end
`PUSH:
begin
ir2abus = 1; cont = 1;
end
`LD:
begin
qtop2abus = 1; cont = 1; pop=1;
end
`POP:
begin
ir2abus = 1; qtop2dbus =1; dbus2ram = 1; pop = 1;
end
`ST:
begin
qtop2dbus = 1; dbus2ram=1; qnext2abus=1; pop = 1; cont=1;
end
`JMP:
begin
ir2abus = 1; abus2pc = 1;
end
`JZ:
begin
if(qtop==0)
begin
ir2abus = 1; abus2pc = 1;
end
pop = 1;
end
`JNZ:
begin
if(qtop !=0)
begin
ir2abus = 1; abus2pc = 1;
end
pop = 1;
end
`IN:
begin
in2dbus = 1; dbus2qtop = 1; push = 1;
end
`OUT:
begin
qtop2dbus = 1; dbus2obuf = 1; pop = 1;
end
`OP:
begin
alu2dbus = 1; dbus2qtop = 1;
if(irout[4] ==0) pop = 1;
end
default:
halt = 1;
endcase
end
else if(cs == `EXECB)
begin
if(irout[15:12] == `PUSH|| irout[15:12] == `LD)
begin
ram2dbus = 1; dbus2qtop = 1; push = 1;
end
else
if(irout[15:12] == `ST)
begin
pop = 1;
end
end
end
endmodule
- state.v
`include "defs.v"
module state(clk, reset, run, cont, halt, cs
);
input clk, reset, run, cont, halt;
output [2:0] cs;
reg [2:0] cs;
always @(posedge clk or negedge reset)
if(!reset) cs<= `IDLE;
else
case(cs)
`IDLE: if(run) cs <= `FETCHA;
`FETCHA: cs <= `FETCHB;
`FETCHB: cs <= `EXECA;
`EXECA: if(halt) cs <= `IDLE;
else if(cont) cs <= `EXECB;
else cs <= `FETCHA;
`EXECB: cs <= `FETCHA;
default: cs <= 3'bxxx;
endcase
endmodule
- stack.v
module stack(clk, reset, load, push, pop, d, qtop, qnext );
parameter N=8;
input clk, reset, load, push, pop;
input [15:0] d;
output [15:0] qtop, qnext;
reg [15:0] q [N-1:0];
assign qtop = q[0];
assign qnext = q[1];
always @(posedge clk or negedge reset)
if(!reset) q[0] <= 0;
else if(load) q[0] <= d;
else if(pop) q[0] <= q[1];
//integer i;
generate
genvar i;
for(i=1;i<N-1; i=i+1)
begin : for_i
always @(posedge clk or negedge reset)
if(!reset) q[i] <=0;
else if(push) q[i] <=q[i-1];
else if(pop) q[i] <=q[i+1];
end
endgenerate
always @(posedge clk or negedge reset)
if(!reset) q[N-1] <= 0;
else if(push) q[N-1] <= q[N-2];
endmodule
- alu.v
`include "defs.v"
module alu(a,b,f,s);
input [15:0] a,b;
input [4:0] f;
output [15:0] s;
reg [15:0] s;
wire [15:0] x,y;
assign x=a+16'h8000;
assign y=b+16'h8000;
always @(a or b or x or y or f)
case(f)
`ADD : s = b + a;
`SUB : s = b - a;
`MUL : s = b * a;
`SHL : s = b << a;
`SHR : s = b >> a;
`BAND : s = b & a;
`BOR : s = b | a;
`BXOR : s = b ^ a;
`AND : s = b && a;
`OR : s = b || a;
`EQ : s = b == a;
`NE : s = b != a;
`GE : s = x >= y;
`LE : s = x <= y;
`GT : s = x > y;
`LT : s = x < y;
`NEG : s= -a;
`BNOT : s= ~a;
`NOT : s = !a;
default : s = 16'hxxxx;
endcase
endmodule
- counter.v
module counter(clk, reset, load, inc, d, q );
parameter N=16;
input clk, reset, load, inc;
input [N-1:0] d;
output [N-1:0] q;
reg [N-1:0] q;
always @(posedge clk or negedge reset)
if(!reset) q <=0;
else if(load) q<=d;
else if(inc) q<=q+1;
endmodule
|