LoginSignup
0

More than 1 year has passed since last update.

vistaでquartus その7

Last updated at Posted at 2020-06-20

概要

vistaでquartusやってみた。
俺cpuやってみた。

環境

windows vista 32bit
quartus ii v13.0
ep2c5t144ボード

写真

image

サンプルコード





`define     IDLE    3'b000
`define     FETCHA  3'b001
`define     FETCHB  3'b010
`define     EXECA   3'b011
`define     EXECB   3'b100

`define     ADD     5'b00000
`define     SUB     5'b00001
`define     MUL     5'b00010
`define     SHL     5'b00011
`define     SHR     5'b00100
`define     BAND    5'b00101
`define     BOR     5'b00110
`define     BXOR    5'b00111
`define     AND     5'b01000
`define     OR      5'b01001
`define     EQ      5'b01010
`define     NE      5'b01011
`define     GE      5'b01100
`define     LE      5'b01101
`define     GT      5'b01110
`define     LT      5'b01111
`define     NEG     5'b10000
`define     BNOT    5'b10001
`define     NOT     5'b10010

`define     HALT        4'b0000
`define     PUSHI       4'b0001
`define     PUSH        4'b0010
`define     POP     4'b0011
`define     JMP     4'b0100
`define     JZ          4'b0101
`define     JNZ     4'b0110
`define     IN          4'b1101
`define     OUT     4'b1110
`define     OP          4'b1111

module counter(clk, rst, load, inc, d, q);
    parameter N = 16;
    input clk,
        rst,
        load,
        inc;
    input [N - 1:0] d;
    output [N - 1:0] q;
    reg [N - 1:0] q;
    always @(posedge clk or negedge rst)
        if (!rst)
            q <= 0;
        else if (load)
            q <= d;
        else if (inc)
            q <= q + 1;
endmodule

module stack(clk, rst, load, push, pop, d, qtop, qnext);
    parameter N = 8;
    input clk,
        rst,
        load,
        push,
        pop;
    input [15:0] d;
    output [15:0] qtop,
        qnext;
    reg [15:0] q[0:N - 1];
    assign qtop = q[0];
    assign qnext = q[1];
    always @(posedge clk or negedge rst)
        if (!rst)
            q[0] <= 0;
        else if (load)
            q[0] <= d;
        else if (pop)
            q[0] <= q[1];
    integer i;
    always @(posedge clk or negedge rst)
        for (i = 1; i < N - 1; i = i + 1)
            if (!rst)
                q[i] <= 0;
            else if (push)
                q[i] <= q[i - 1];
            else if (pop)
                q[i] <= q[i + 1];
    always @(posedge clk or negedge rst)
        if (!rst)
            q[N - 1] <= 0;
        else if (push)
            q[N - 1] <= q[N - 2];
endmodule

module ram(clk, load, addr, d, q);
    parameter DWIDTH = 16,
        AWIDTH = 12,
        WORDS = 4096;
    input clk,
        load;
    input [AWIDTH - 1:0] addr;
    input [DWIDTH - 1:0] d;
    output [DWIDTH - 1:0] q;
    reg [DWIDTH - 1:0] q;
    reg [DWIDTH - 1:0] mem[WORDS - 1:0];
    always @(posedge clk)
    begin
        if (load)
            mem[addr] <= d;
        q <= mem[addr];
    end
    initial
    begin
        mem[0] =  16'h1032;//push 9
        mem[1] =  16'h1005;//push 3
        mem[2] =  16'hf000;//+
        mem[3] =  16'he000;//out
        mem[4] =  16'hf000;//+
        mem[5] =  16'h4000;//jp 5
    end
endmodule

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 = y >= x;
        `LE:
            s = y <= x;
        `GT:
            s = y > x;
        `LT:
            s = y < x;
        `NEG:
            s = -a;
        `BNOT:
            s = ~a;
        `NOT:
            s = !a;
        default:
            s = 16'hxxxx;
        endcase
endmodule

module state(clk, rst, ed, cont, halt, cs);
    input clk,
        rst,
        ed,
        cont,
        halt;
    output [2:0] cs;
    reg [2:0] cs;
    always @(posedge clk or negedge rst)
        if (!rst)
            cs <= `IDLE;
        else if (!ed)
            cs <= `IDLE;
        else
            case (cs)
            `IDLE:
                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'bxxxx;
            endcase
endmodule

module test2(input clk, input rst, output tx, output [11:0] pcout, output reg led2 = 0);
    reg [15:0] in;
    wire [2:0] cs;
    wire [15:0] irout,
        qtop,
        dbus;
    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,
        alu2dbus,
        ram2dbus,
        in2dbus;
    reg send = 0;
    counter #(12) pcb0(.clk(clk), .rst(rst), .load(abus2pc), .inc(pcinc), .d(abus), .q(pcout));
    counter #(16) outb0(.clk(clk), .rst(rst), .load(dbus2obuf), .inc(0), .d(dbus), .q(out));
    counter #(16) irb0(.clk(clk), .rst(rst), .load(dbus2ir), .inc(0), .d(dbus), .q(irout));
    state irq0(.clk(clk), .rst(rst), .ed(ed), .cont(cont), .halt(halt), .cs(cs));
    stack stack0(.clk(clk), .rst(rst), .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 ram0(.clk(clk), .load(dbus2ram), .addr(abus[11:0]), .d(dbus), .q(ramout));
    tx1 tx1(.clk(clk), .rst(rst), .send(dbus2obuf), .data(dbus), .tx(tx), .ed(ed));
    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;
    always @(pc2abus or ir2abus or pcout or irout)
        if (pc2abus)
            abus <= pcout;
        else if (ir2abus)
            abus <= irout[11:0];
        else
            abus <= 12'hxxx;
    always @(cs or irout or qtop)
    begin
        halt = 0;
        pcinc = 0;
        push = 0;
        pop = 0;
        cont = 0;
        abus2pc = 0;
        dbus2ir = 0;
        dbus2qtop = 0;
        dbus2ram = 0;
        dbus2obuf = 0;
        pc2abus = 0;
        ir2abus = 0;
        ir2dbus = 0;
        qtop2dbus = 0;
        alu2dbus = 0;
        ram2dbus = 0;
        in2dbus = 0;
        send = 0;
        if (cs == `FETCHA)
        begin
            pcinc = 1;
            pc2abus = 1;
        end
        else if (cs == `FETCHB)
        begin
            ram2dbus = 1;
            dbus2ir = 1;
        end
        else if (cs == `EXECA)
            case (irout[15:12])
            `PUSHI:
            begin
                ir2dbus = 1;
                dbus2qtop = 1;
                push = 1;
            end
            `PUSH:
            begin
                ir2abus = 1;
                cont = 1;
            end
            `POP:
            begin
                ir2abus = 1;
                qtop2dbus = 1;
                dbus2ram = 1;
                pop = 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;
                send = 1;
            end
            `OP:
            begin
                alu2dbus = 1;
                dbus2qtop = 1;
                if (irout[4] == 0)
                    pop = 1;
            end
            default:
                halt = 1;
            endcase
        else if (cs == `EXECB)
            if (irout[15:12] == `PUSH)
            begin
                ram2dbus = 1;
                dbus2qtop = 1;
                push = 1;
            end

    end
endmodule



以上。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0