Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // for MEM
- `define M_NOP 2'b00
- `define M_PUSH 2'b01
- `define M_POP 2'b10
- // for SM - instr
- `define PUSH 3'b000
- `define ADD 3'b001
- `define SUB 3'b010
- `define MUL 3'b011
- // for SM - state
- `define S_LEN 3'b000
- `define S_PRE 3'b001
- `define S_POP1 3'b010
- `define S_POP2 3'b011
- `define S_PUSH 3'b100
- `define S_ERR 3'b101
- // for error
- `define NOERR 3'b000
- `define FULLPUSH 3'b001
- `define UNDEFINE 3'b010
- `define INVALID 3'b100
- module SM(clk, rst_n, instr, pc, d_valid, out_data, err_code, fin);
- input clk;
- input rst_n;
- input [12:0] instr;
- output [9:0] pc;
- output reg d_valid;
- output reg [19:0] out_data;
- output reg [2:0] err_code;
- output fin;
- reg fin1;
- reg [1:0] mem_ctrl1;
- reg [19:0] mw_data1;
- wire signed [19:0] mr_data;
- wire mFull;
- wire mEmpty;
- wire [3:0] mem_count;
- wire [3:0] next_memCount;
- reg [3:0] mem_count1;
- SM_Mem mem(clk, rst_n, mem_ctrl1, mw_data1, mr_data, mFull, mEmpty);
- reg [9:0] length;
- wire signed [19:0] cal;
- wire signed [19:0] next_cal;
- reg signed [19:0] cal1;
- wire [9:0] next_pc;
- reg [9:0] pc1;
- wire [2:0] state;
- wire [2:0] next_state;
- reg [2:0] state1;
- DFF #(10) dff_pc(clk, next_pc, pc);
- DFF #(3) dff_st(clk, next_state, state);
- DFF #(4) dff_cnt(clk, next_memCount, mem_count);
- DFF #(20) dff_cal(clk, next_cal, cal);
- always @(*) begin
- pc1 = pc;
- state1 = state;
- cal1 = cal;
- d_valid = 0;
- err_code = `NOERR;
- case (state)
- `S_LEN: begin
- length = instr[9:0];
- fin1 = 0;
- out_data = 'hz;
- mem_ctrl1 = `M_NOP;
- mw_data1 = 'hz;
- pc1 = pc + 1;
- state1 = `S_PRE;
- end
- `S_PRE: begin
- out_data = 'hz;
- mem_ctrl1 = `M_NOP;
- mw_data1 = 'hz;
- if (instr[12:10] == `PUSH) begin
- if (mFull == 1) begin
- state1 = `S_ERR;
- end
- else begin
- state1 = `S_PUSH;
- cal1 = $signed(instr[9:0]);
- end
- end
- else if (instr[12:10] == `ADD || instr[12:10] == `SUB || instr[12:10] == `MUL) begin
- if (mem_count < 4'd2) begin
- state1 = `S_ERR;
- end
- else begin
- state1 = `S_POP1;
- cal1 = 0;
- end
- end
- else begin
- state1 = `S_ERR;
- end
- end
- `S_POP1: begin
- mem_ctrl1 = `M_POP;
- cal1 = mr_data;
- state1 = `S_POP2;
- end
- `S_POP2: begin
- mem_ctrl1 = `M_POP;
- if (instr[12:10] == `ADD) begin
- cal1 = cal + mr_data;
- end
- else if (instr[12:10] == `SUB) begin
- cal1 = cal - mr_data;
- end
- else if (instr[12:10] == `MUL) begin
- cal1 = cal * mr_data;
- end
- else begin end
- state1 = `S_PUSH;
- end
- `S_PUSH: begin
- mem_ctrl1 = `M_PUSH;
- mw_data1 = cal;
- case (instr[12:10])
- `ADD: begin
- d_valid = 1;
- out_data = cal;
- end
- `SUB: begin
- d_valid = 1;
- out_data = cal;
- end
- `MUL: begin
- d_valid = 1;
- out_data = cal;
- end
- default: begin
- out_data = 'hz;
- end
- endcase
- pc1 = pc + 1;
- state1 = `S_PRE;
- end
- `S_ERR: begin
- d_valid = 1;
- out_data = 0;
- if (instr[12:10] == `PUSH) begin
- err_code = `FULLPUSH;
- end
- else if (instr[12:10] == `ADD || instr[12:10] == `SUB || instr[12:10] == `MUL) begin
- err_code = `INVALID;
- end
- else begin
- err_code = `UNDEFINE;
- end
- mem_ctrl1 = `M_NOP;
- pc1 = pc + 1;
- state1 = `S_PRE;
- end
- default: begin end
- endcase
- if (pc == length) begin
- fin1 = 1;
- end
- else begin end
- end
- always @(*) begin
- mem_count1 = mem_count;
- case (state)
- `S_POP1: begin
- mem_count1 = mem_count - 1;
- end
- `S_POP2: begin
- mem_count1 = mem_count - 1;
- end
- `S_PUSH: begin
- mem_count1 = mem_count + 1;
- end
- default: begin end
- endcase
- end
- assign next_pc = (rst_n == 0)? 10'd1023 : pc1;
- assign next_state = (rst_n == 0)? `S_LEN : state1;
- assign next_cal = (rst_n == 0)? 0 : cal1;
- assign next_memCount = (rst_n == 0)? 4'd0 : mem_count1;
- assign fin = (rst_n == 0)? 0 : fin1;
- endmodule
- module SM_Mem(clk, rst_n, cntrl, w_data, r_data, full, empty);
- input clk;
- input rst_n;
- input [1:0] cntrl;
- input [19:0] w_data;
- output [19:0] r_data;
- output full;
- output empty;
- reg [19:0] stack[7:0];
- reg [3:0] top1;
- wire [3:0] top;
- wire [3:0] next_top;
- wire [19:0] next_Rdata;
- reg [19:0] r_data1;
- DFF #(4) dff_t(clk, next_top, top);
- always @(*) begin
- top1 = top;
- case (cntrl)
- `M_NOP: begin
- r_data1 = 0;
- end
- `M_PUSH: begin
- stack[top] = w_data;
- top1 = top + 1;
- r_data1 = 0;
- end
- `M_POP: begin
- r_data1 = stack[top - 1];
- top1 = top - 1;
- end
- default: begin end
- endcase
- end
- assign next_top = (rst_n == 0)? 0 : top1;
- assign r_data = (rst_n == 0)? 0 : r_data1;
- assign empty = (top == 4'd0)? 1 : 0;
- assign full = (top == 4'd8)? 1 : 0;
- endmodule
- module DFF (clk, next_out, out);
- parameter n = 1;
- input clk;
- input [n-1:0] next_out;
- output reg [n-1:0] out;
- always @(posedge clk) begin
- out <= next_out;
- end
- endmodule
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement