📄 ac51_fetch.v
字号:
//// ac51_fetch.v//// ac51 microcontroller core//// Version 0.6//// Copyright 2008, Hideyuki Abe. All rights reserved.// Distributed under the terms of the MIT License.//`define FCH_STATE_LEN 2`define FST_IDLE 2'b00`define FST_FETCH1 2'b01`define FST_FETCH2 2'b10`define FST_FETCH3 2'b11module ac51_fetch( clk, rst, paddr, pen, pack, prdata, pc_nxt, inst1, inst2, inst3, inst_rdy, inst_ack, jmp_req, jmp_ack, new_pc);input clk;input rst;output [15:0] paddr;output pen;input pack;input [7:0] prdata;output [15:0] pc_nxt;output [7:0] inst1;output [7:0] inst2;output [7:0] inst3;output inst_rdy;input inst_ack;input jmp_req;output jmp_ack;input [15:0] new_pc;reg pen;reg jmp_ack;reg [`FCH_STATE_LEN - 1:0] state;reg [`FCH_STATE_LEN - 1:0] state_nxt;wire [7:0] inst1;wire [7:0] inst2;wire [7:0] inst3;reg [7:0] inst1_r;reg [7:0] inst2_r;reg [7:0] inst3_r;reg [1:0] nrof_inst;reg [15:0] pc;reg [15:0] pc_nxt;reg inst_rdy;always @(posedge clk or negedge rst) begin if(~rst) state <= `FST_FETCH1; else state <= state_nxt;end // alwaysalways @(posedge clk or negedge rst) begin if(~rst) pc <= 16'h0000; else pc <= pc_nxt;end // alwaysassign paddr = pc_nxt;assign inst1 = (state == `FST_FETCH1) ? prdata : inst1_r;always @(posedge clk or negedge rst) begin if(~rst) inst1_r <= 8'h00; // NOP else if((state == `FST_FETCH1) & pack) inst1_r <= prdata;end // alwaysassign inst2 = (state == `FST_FETCH2) ? prdata : inst2_r;always @(posedge clk or negedge rst) begin if(~rst) inst2_r <= 8'h00; else if((state == `FST_FETCH2) & pack) inst2_r <= prdata;end // alwaysassign inst3 = (state == `FST_FETCH3) ? prdata : inst3_r;always @(posedge clk or negedge rst) begin if(~rst) inst3_r <= 8'h00; else if((state == `FST_FETCH3) & pack) inst3_r <= prdata;end // alwaysalways @( state or pack or pc or inst_ack or nrof_inst or jmp_req or new_pc) begin // default pc_nxt = pc; pen = 1'b0; inst_rdy = 1'b0; state_nxt = state; if(state == `FST_IDLE) begin if(jmp_req) begin pc_nxt = new_pc; jmp_ack = 1'b1; pen = 1'b1; state_nxt = `FST_FETCH1; end else begin jmp_ack = 1'b0; inst_rdy = 1'b1; if(inst_ack) begin pen = 1'b1; state_nxt = `FST_FETCH1; end end end else begin if(pack) begin if(jmp_req) begin pc_nxt = new_pc; jmp_ack = 1'b1; pen = 1'b1; state_nxt = `FST_FETCH1; end else begin pc_nxt = pc + 16'h0001; jmp_ack = 1'b0; if(state == `FST_FETCH1) begin if(nrof_inst == 2'b10 | nrof_inst == 2'b11) begin pen = 1'b1; state_nxt = `FST_FETCH2; end else begin inst_rdy = 1'b1; if(inst_ack) begin pen = 1'b1; state_nxt = `FST_FETCH1; end else state_nxt = `FST_IDLE; end end else if(state == `FST_FETCH2) begin if(nrof_inst == 2'b11) begin pen = 1'b1; state_nxt = `FST_FETCH3; end else begin inst_rdy = 1'b1; if(inst_ack) begin pen = 1'b1; state_nxt = `FST_FETCH1; end else state_nxt = `FST_IDLE; end end else if(state == `FST_FETCH3) begin inst_rdy = 1'b1; if(inst_ack) begin pen = 1'b1; state_nxt = `FST_FETCH1; end else state_nxt = `FST_IDLE; end end end // if(pack) else begin jmp_ack = 1'b0; pen = 1'b1; end endend // always combalways @(inst1) begin case(inst1[3:0]) 4'h0: if(inst1[7:4] == 4'h0 | inst1[7:4] == 4'he | inst1[7:4] == 4'hf) nrof_inst = 2'b01; else if(inst1[7:4] == 4'h1 | inst1[7:4] == 4'h2 | inst1[7:4] == 4'h3 | inst1[7:4] == 4'h9) nrof_inst = 2'b11; else nrof_inst = 2'b10; 4'h1: nrof_inst = 2'b10; // AJMP, ACALL 4'h2: if(inst1[7:4] == 4'h0 | inst1[7:4] == 4'h1) nrof_inst = 2'b11; else if(inst1[7:4] == 4'h2 | inst1[7:4] == 4'h3 | inst1[7:4] == 4'he | inst1[7:4] == 4'hf) nrof_inst = 2'b01; else nrof_inst = 2'b10; 4'h3: if(inst1[7:4] == 4'h4 | inst1[7:4] == 4'h5 | inst1[7:4] == 4'h6) nrof_inst = 2'b11; else nrof_inst = 2'b01; 4'h4: if(inst1[7:4] == 4'hb) nrof_inst = 2'b11; else if(inst1[7:4] == 4'h2 | inst1[7:4] == 4'h3 | inst1[7:4] == 4'h4 | inst1[7:4] == 4'h5 | inst1[7:4] == 4'h6 | inst1[7:4] == 4'h7 | inst1[7:4] == 4'h9) nrof_inst = 2'b10; else nrof_inst = 2'b01; 4'h5: if(inst1[7:4] == 4'ha) // ESC nrof_inst = 2'b01; else if(inst1[7:4] == 4'h7 | inst1[7:4] == 4'h8 | inst1[7:4] == 4'hb | inst1[7:4] == 4'hd) nrof_inst = 2'b11; else nrof_inst = 2'b10; 4'h6, 4'h7: if(inst1[7:4] == 4'hb) nrof_inst = 2'b11; else if(inst1[7:4] == 4'h7 | inst1[7:4] == 4'h8 | inst1[7:4] == 4'ha) nrof_inst = 2'b10; else nrof_inst = 2'b01; 4'h8, 4'h9, 4'ha, 4'hb, 4'hc, 4'hd, 4'he, 4'hf: if(inst1[7:4] == 4'hb) nrof_inst = 2'b11; else if(inst1[7:4] == 4'h7 | inst1[7:4] == 4'h8 | inst1[7:4] == 4'ha | inst1[7:4] == 4'hd) nrof_inst = 2'b10; else nrof_inst = 2'b01; default: nrof_inst = 2'b00; // unknown inst endcaseend // always combendmodule// End of ac51_fetch.v
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -