Untitled

 avatar
unknown
verilog
a month ago
11 kB
6
Indexable
module counter_9_bits_on_sload (
    input         clk,
    input         resetn,
    input         enable,
    input         sload,
    input  [8:0]  D,
    output reg [8:0] Q
);
    always @(posedge clk, negedge resetn) begin
        if (!resetn)
            Q <= 9'b000000000;
        else if (sload)
            Q <= D;
        else if (enable)
            Q <= Q + 1;
    end
endmodule

module processor_2 (
    input  [8:0]  DIN,
    input         Resetn, Clock, Run,
    output reg    Done,
    output [8:0]  BusWires,
    output [8:0]  ADDR,
    output [8:0]  DOUT,
    output reg    W
);
    parameter T0 = 3'b000, T1 = 3'b001, T2 = 3'b010, 
              T3 = 3'b011, T4 = 3'b100;
    
    reg [2:0] Tstep_Q, Tstep_D;
    reg [8:0] IR;
    
    wire [2:0] I    = IR[8:6];
    wire [2:0] Xidx = IR[5:3];
    wire [2:0] Yidx = IR[2:0];
    
    reg [7:0] Rin, Rout;
    reg Ain, Gin, AddSub, DINout, Gout;
    reg ADDRin, DOUTin, W_D;
    reg PCout, incr_PC, PCin;
    reg IRin;
    
    reg [8:0] R [0:6];
    wire [8:0] PC;
    reg [8:0] A_reg, G_reg;
    reg [8:0] ADDR_reg, DOUT_reg;
    reg [8:0] sum;
    
    always @(posedge Clock, negedge Resetn) begin
        if (!Resetn)
            Tstep_Q <= T0;
        else
            Tstep_Q <= Tstep_D;
    end
    
    always @(*) begin
        case (Tstep_Q)
            T0: Tstep_D = Run ? T1 : T0;
            T1: Tstep_D = T2;
            T2: begin
                case (I)
                    3'b000, 3'b110: Tstep_D = T0;
                    3'b001: Tstep_D = T3;
                    3'b010, 3'b011: Tstep_D = T3;
                    3'b100, 3'b101: Tstep_D = T3;
                    default: Tstep_D = T0;
                endcase
            end
            T3: begin
                case (I)
                    3'b001, 3'b100, 3'b101: Tstep_D = T0;
                    3'b010, 3'b011: Tstep_D = T4;
                    default: Tstep_D = T0;
                endcase
            end
            T4: Tstep_D = T0;
            default: Tstep_D = T0;
        endcase
    end
    
    always @(*) begin
        IRin = 0; Rin = 0; Rout = 0;
        Ain = 0; Gin = 0; AddSub = 0;
        DINout = 0; Gout = 0;
        ADDRin = 0; DOUTin = 0; W_D = 0;
        PCout = 0; incr_PC = 0; PCin = 0;
        Done = 0;
        
        case (Tstep_Q)
            T0: begin
                PCout = 1;
                ADDRin = 1;
            end
            T1: begin
                IRin = 1;
                incr_PC = 1;
            end
            T2: begin
                case (I)
                    3'b000: begin
                        Rout[Yidx] = 1;
                        if (Xidx == 3'b111) PCin = 1;
                        else                Rin[Xidx] = 1;
                        Done = 1;
                    end
                    3'b001: begin
                        PCout = 1;
                        ADDRin = 1;
                    end
                    3'b010, 3'b011: begin
                        Rout[Xidx] = 1;
                        Ain = 1;
                    end
                    3'b100: begin
                        Rout[Yidx] = 1;
                        ADDRin = 1;
                    end
                    3'b101: begin
                        Rout[Yidx] = 1;
                        ADDRin = 1;
                    end
                    3'b110: begin
                        if (G_reg != 9'b000000000) begin
                            Rout[Yidx] = 1;
                            if (Xidx == 3'b111) PCin = 1;
                            else                Rin[Xidx] = 1;
                        end
                        Done = 1;
                    end
                endcase
            end
            T3: begin
                case (I)
                    3'b001: begin
                        DINout = 1;
                        if (Xidx == 3'b111) PCin = 1;
                        else                Rin[Xidx] = 1;
                        incr_PC = 1;
                        Done = 1;
                    end
                    3'b010: begin
                        Rout[Yidx] = 1;
                        Gin = 1;
                    end
                    3'b011: begin
                        Rout[Yidx] = 1;
                        Gin = 1;
                        AddSub = 1;
                    end
                    3'b100: begin
                        DINout = 1;
                        if (Xidx == 3'b111) PCin = 1;
                        else                Rin[Xidx] = 1;
                        Done = 1;
                    end
                    3'b101: begin
                        Rout[Xidx] = 1;
                        DOUTin = 1;
                        W_D = 1;
                        Done = 1;
                    end
                endcase
            end
            T4: begin
                case (I)
                    3'b010, 3'b011: begin
                        Gout = 1;
                        if (Xidx == 3'b111) PCin = 1;
                        else                Rin[Xidx] = 1;
                        Done = 1;
                    end
                endcase
            end
        endcase
    end
    
    integer k;
    always @(posedge Clock) begin
        for (k = 0; k < 7; k = k + 1)
            if (Rin[k])
                R[k] <= BusWires;
    end
    
    counter_9_bits_on_sload PC_inst (
        .clk(Clock),
        .resetn(Resetn),
        .enable(incr_PC),
        .sload(PCin),
        .D(BusWires),
        .Q(PC)
    );
    
    always @(posedge Clock) begin
        if (Ain)    A_reg    <= BusWires;
        if (Gin)    G_reg    <= sum;
        if (ADDRin) ADDR_reg <= BusWires;
        if (DOUTin) DOUT_reg <= BusWires;
        if (IRin)   IR       <= DIN;
    end
    
    always @(posedge Clock, negedge Resetn) begin
        if (!Resetn) W <= 0;
        else         W <= W_D;
    end
    
    always @(*) begin
        if (AddSub) sum = A_reg - BusWires;
        else        sum = A_reg + BusWires;
    end
    
    assign BusWires = Rout[0] ? R[0] :
                      Rout[1] ? R[1] :
                      Rout[2] ? R[2] :
                      Rout[3] ? R[3] :
                      Rout[4] ? R[4] :
                      Rout[5] ? R[5] :
                      Rout[6] ? R[6] :
                      PCout   ? PC :
                      DINout  ? DIN :
                      Gout    ? G_reg :
                      9'b000000000;
    
    assign ADDR = ADDR_reg;
    assign DOUT = DOUT_reg;
endmodule

DEPTH = 128;
WIDTH = 9;
ADDRESS_RADIX = HEX;
DATA_RADIX = BIN;
CONTENT
BEGIN
00 : 001010000;  % mvi R2, #LED_RS0_addr %
01 : 010000000;  % adres = 010000000 (A8A7=01) %
02 : 100001010;  % ld R1, [R2]  // R1 <- SW (z RS0) %
03 : 101001010;  % st R1, [R2]  // LED <- R1 %
04 : 001111000;  % mvi R7, #00  // skok do poczatku (PC <- 0) %
05 : 000000000;  % wartosc dla R7 = 0 %
06 : 000000000;
07 : 000000000;
08 : 000000000;
09 : 000000000;
0A : 000000000;
0B : 000000000;
0C : 000000000;
0D : 000000000;
0E : 000000000;
0F : 000000000;
10 : 000000000;
11 : 000000000;
12 : 000000000;
13 : 000000000;
14 : 000000000;
15 : 000000000;
16 : 000000000;
17 : 000000000;
18 : 000000000;
19 : 000000000;
1A : 000000000;
1B : 000000000;
1C : 000000000;
1D : 000000000;
1E : 000000000;
1F : 000000000;
20 : 000000000;
21 : 000000000;
22 : 000000000;
23 : 000000000;
24 : 000000000;
25 : 000000000;
26 : 000000000;
27 : 000000000;
28 : 000000000;
29 : 000000000;
2A : 000000000;
2B : 000000000;
2C : 000000000;
2D : 000000000;
2E : 000000000;
2F : 000000000;
30 : 000000000;
31 : 000000000;
32 : 000000000;
33 : 000000000;
34 : 000000000;
35 : 000000000;
36 : 000000000;
37 : 000000000;
38 : 000000000;
39 : 000000000;
3A : 000000000;
3B : 000000000;
3C : 000000000;
3D : 000000000;
3E : 000000000;
3F : 000000000;
40 : 000000000;
41 : 000000000;
42 : 000000000;
43 : 000000000;
44 : 000000000;
45 : 000000000;
46 : 000000000;
47 : 000000000;
48 : 000000000;
49 : 000000000;
4A : 000000000;
4B : 000000000;
4C : 000000000;
4D : 000000000;
4E : 000000000;
4F : 000000000;
50 : 000000000;
51 : 000000000;
52 : 000000000;
53 : 000000000;
54 : 000000000;
55 : 000000000;
56 : 000000000;
57 : 000000000;
58 : 000000000;
59 : 000000000;
5A : 000000000;
5B : 000000000;
5C : 000000000;
5D : 000000000;
5E : 000000000;
5F : 000000000;
60 : 000000000;
61 : 000000000;
62 : 000000000;
63 : 000000000;
64 : 000000000;
65 : 000000000;
66 : 000000000;
67 : 000000000;
68 : 000000000;
69 : 000000000;
6A : 000000000;
6B : 000000000;
6C : 000000000;
6D : 000000000;
6E : 000000000;
6F : 000000000;
70 : 000000000;
71 : 000000000;
72 : 000000000;
73 : 000000000;
74 : 000000000;
75 : 000000000;
76 : 000000000;
77 : 000000000;
78 : 000000000;
79 : 000000000;
7A : 000000000;
7B : 000000000;
7C : 000000000;
7D : 000000000;
7E : 000000000;
7F : 000000000;
END;

module processor_with_SW (
    input         CLOCK_50,
    input  [0:0]  KEY,
    input  [9:0]  SW,
    output [9:0]  LEDR
);
    wire Resetn = KEY[0];  // KEY0 aktywne niskim - nacisniety = reset
    wire Run    = SW[9];
    
    // Synchronizacja Run z zegarem (zgodnie z instrukcja)
    reg Run_s0, Run_s1;
    always @(posedge CLOCK_50) begin
        Run_s0 <= Run;
        Run_s1 <= Run_s0;
    end
    
    // Rejestry wejsciowe RS0 (SW0-7) i RS1 (SW8-9)
    reg [8:0] RS0, RS1;
    always @(posedge CLOCK_50) begin
        RS0 <= {1'b0, SW[7:0]};      // SW7-0 jako 9-bit (gora = 0)
        RS1 <= {7'b0000000, SW[9:8]}; // SW8-9 jako 9-bit
    end
    
    wire [8:0] ADDR, DOUT, BusWires;
    wire W, Done;
    
    // Dekodowanie adresu dla DIN:
    // A8A7 = 00: pamiec (mem_q)
    // A8A7 = 01: RS0
    // A8A7 = 10: RS1
    wire [8:0] mem_q;
    reg  [8:0] DIN_mux;
    
    always @(*) begin
        case (ADDR[8:7])
            2'b00:   DIN_mux = mem_q;
            2'b01:   DIN_mux = RS0;
            2'b10:   DIN_mux = RS1;
            default: DIN_mux = mem_q;
        endcase
    end
    
    // Sygnal zapisu do pamieci (tylko gdy A8A7=00)
    wire wr_mem = W & (ADDR[8:7] == 2'b00);
    
    // Rejestr LED (A8A7=01 do zapisu)
    reg [8:0] led_reg;
    always @(posedge CLOCK_50, negedge Resetn) begin
        if (!Resetn)
            led_reg <= 9'b000000000;
        else if (W && (ADDR[8:7] == 2'b01))
            led_reg <= DOUT;
    end
    
    // Pamiec RAM 128x9
    ram128x9 mem (
        .address(ADDR[6:0]),
        .clock(CLOCK_50),
        .data(DOUT),
        .wren(wr_mem),
        .q(mem_q)
    );
    
    // Procesor
    processor_2 cpu (
        .DIN(DIN_mux),
        .Resetn(Resetn),
        .Clock(CLOCK_50),
        .Run(Run_s1),
        .Done(Done),
        .BusWires(BusWires),
        .ADDR(ADDR),
        .DOUT(DOUT),
        .W(W)
    );
    
    assign LEDR[8:0] = led_reg;
    assign LEDR[9] = Done;
endmodule

create_clock -period 20.000 -name clk [get_ports {CLOCK_50}]
Editor is loading...
Leave a Comment