ステータスレジスタの実装です。STATUSレジスタと呼ばれていますが、いわゆる「ステータスフラグ」としては、C(キャリー)、DC(デシマルキャリー),Z(ゼロ)ビットだけであとは別の目的に使われています。今回の実装では、ちょっと手を抜き、TO(ウォッチドッグタイマのタイムアウト)とPD(パワーダウン)はまだ、何もしていません。
各フラグは、special functionレジスタとしてもアクセスできます。悩ましいのは、フラグの更新と、スペシャルファンクションレジスタとしての書き込みが同時起きたときに、どちらを優先するかですが、PICmicro Mid-Range MCU Family Reference Manualによると、フラグの更新が優先するのですね。また、命令ごとに更新されるフラグが異なることも注意が必要です。
そこで、各フラグの更新信号を命令からデコードしてます。つぎに、各フラグごとに更新を行うようにしています。あ、あと、ちょっとポート名などに見直しもしました。
次は、File Registerのコントローラの予定です。
---
本日の御託
家内が近所のスーパーで、靴(というか、ミュールだな)の中敷を買ってきたが、よく見たら2つとも「左足」用だった。(大笑い)
//
// STATUS register
// Section 4.2.2.1 Status Register
//
`include "yap16_instructions.h"
`include "yap16_def.h"
module status_reg(
input clk_i, // system clock
input reset_i, // usual POR
input [(`YAP16_INST_WIDTH -1):0] instruction_i ,
input status_we_i, // write enable for status reg
input [7:0] data_i, // data from write_bus
output irp_o, // IRP
output [1:0] rp_o, // bit6 rp1 bit5 rp0
output to_n_o, // bit4 TO_
output pd_n_o, // bit3 PD_
output z_o, // bit2 Z
output dc_o, // bit1 DC
output c_o, // bit0 C
input z_next_i, // bit2 Z
input dc_next_i, // bit1 DC
input c_next_i // bit0 C
) ;
reg irp, to_n, pd_n, z, dc, c;
reg [1:0] rp;
reg z_we, dc_we, c_we ; // flag write (update) enable
assign {irp_o, rp_o, to_n_o, pd_n_o, z_o, dc_o, c_o }
= {irp, rp, to_n, pd_n, z, dc, c } ;
always@ * begin //always@( instruction_i )
{ z_we, dc_we, c_we } <= 3'b000 ; // reset all
casex( instruction_i)
`YAP16_INST_ADDWF ,
`YAP16_INST_SUBWF ,
`YAP16_INST_ADDLW ,
`YAP16_INST_SUBLW :
{ z_we, dc_we, c_we } <= 3'b111 ;
`YAP16_INST_ANDWF ,
`YAP16_INST_CLRF ,
`YAP16_INST_CLRW ,
`YAP16_INST_COMF ,
`YAP16_INST_DECF ,
`YAP16_INST_INCF ,
`YAP16_INST_IORWF ,
`YAP16_INST_XORWF ,
`YAP16_INST_ANDLW ,
`YAP16_INST_IORLW ,
`YAP16_INST_XORLW :
z_we <= 1'b1 ;
`YAP16_INST_RLF ,
`YAP16_INST_RRF :
c_we <= 1'b1 ;
// No default part
endcase // casex
end // always
// C bit bit 0
always@( posedge clk_i) begin
if( reset_i == 1'b1 ) begin
`ifdef FULL_RESET
c <= 1'b0 ;
`endif // FULL_RESET
end // if
else if ( c_we == 1'b1 ) begin
c <= c_next_i ;
end
else if( status_we_i == 1'b1 ) begin
c <= data_i[0] ;
end
end // always
// DC bit bit 1
always@( posedge clk_i) begin
if( reset_i == 1'b1 ) begin
`ifdef FULL_RESET
dc <= 1'b0 ;
`endif // FULL_RESET
end // if
else if ( dc_we == 1'b1 ) begin
dc <= dc_next_i ;
end
else if( status_we_i == 1'b1 ) begin
dc <= data_i[1] ;
end
end // always
// Z bit bit 2
always@( posedge clk_i) begin
if( reset_i == 1'b1 ) begin
`ifdef FULL_RESET
z <= 1'b0 ;
`endif // FULL_RESET
end // if
else if ( z_we == 1'b1 ) begin
z <= z_next_i ;
end
else if( status_we_i == 1'b1 ) begin
c <= data_i[2] ;
end
end // always
// IRPi,IRP1,IRP0, bit[7:5]
always@( posedge clk_i) begin
if( reset_i == 1'b1 ) begin
{irp, rp } <= 3'b000 ;
end // if
else if( status_we_i == 1'b1 ) begin
{irp, rp } <= data_i[7:5] ;
end
end // always
// to be implemented
//to_n, // bit4 TO_
//pd_n, // bit3 PD_
endmodule // status_reg
// EOF status_reg.v